LLVM 24.0.0git
Attributor.cpp
Go to the documentation of this file.
1//===- Attributor.cpp - Module-wide attribute deduction -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements an interprocedural pass that deduces and/or propagates
10// attributes. This is done in an abstract interpretation style fixpoint
11// iteration. See the Attributor.h file comment and the class descriptions in
12// that file for more information.
13//
14//===----------------------------------------------------------------------===//
15
17
18#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/Statistic.h"
29#include "llvm/IR/Attributes.h"
30#include "llvm/IR/Constant.h"
32#include "llvm/IR/Constants.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/GlobalValue.h"
36#include "llvm/IR/Instruction.h"
39#include "llvm/IR/LLVMContext.h"
40#include "llvm/IR/ValueHandle.h"
43#include "llvm/Support/Debug.h"
47#include "llvm/Support/ModRef.h"
52#include <cstdint>
53#include <memory>
54
55#ifdef EXPENSIVE_CHECKS
56#include "llvm/IR/Verifier.h"
57#endif
58
59#include <cassert>
60#include <optional>
61#include <string>
62
63using namespace llvm;
64
65#define DEBUG_TYPE "attributor"
66#define VERBOSE_DEBUG_TYPE DEBUG_TYPE "-verbose"
67
68DEBUG_COUNTER(ManifestDBGCounter, "attributor-manifest",
69 "Determine what attributes are manifested in the IR");
70
71/// A debug counter to limit the number of AAs created.
72DEBUG_COUNTER(NumAbstractAttributes, "num-abstract-attributes",
73 "How many AAs should be initialized");
74
76 return DebugCounter::shouldExecute(NumAbstractAttributes);
77}
78
79STATISTIC(NumFnDeleted, "Number of function deleted");
80STATISTIC(NumFnWithExactDefinition,
81 "Number of functions with exact definitions");
82STATISTIC(NumFnWithoutExactDefinition,
83 "Number of functions without exact definitions");
84STATISTIC(NumFnShallowWrappersCreated, "Number of shallow wrappers created");
85STATISTIC(NumAttributesTimedOut,
86 "Number of abstract attributes timed out before fixpoint");
87STATISTIC(NumAttributesValidFixpoint,
88 "Number of abstract attributes in a valid fixpoint state");
89STATISTIC(NumAttributesManifested,
90 "Number of abstract attributes manifested in IR");
91
92// TODO: Determine a good default value.
93//
94// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
95// (when run with the first 5 abstract attributes). The results also indicate
96// that we never reach 32 iterations but always find a fixpoint sooner.
97//
98// This will become more evolved once we perform two interleaved fixpoint
99// iterations: bottom-up and top-down.
101 SetFixpointIterations("attributor-max-iterations", cl::Hidden,
102 cl::desc("Maximal number of fixpoint iterations."),
103 cl::init(32));
104
106 MaxSpecializationPerCB("attributor-max-specializations-per-call-base",
108 cl::desc("Maximal number of callees specialized for "
109 "a call base"),
110 cl::init(UINT32_MAX));
111
113 "attributor-max-initialization-chain-length", cl::Hidden,
114 cl::desc(
115 "Maximal number of chained initializations (to avoid stack overflows)"),
118
120 "attributor-annotate-decl-cs", cl::Hidden,
121 cl::desc("Annotate call sites of function declarations."), cl::init(false));
122
123static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
124 cl::init(true), cl::Hidden);
125
126static cl::opt<bool>
127 AllowShallowWrappers("attributor-allow-shallow-wrappers", cl::Hidden,
128 cl::desc("Allow the Attributor to create shallow "
129 "wrappers for non-exact definitions."),
130 cl::init(false));
131
132static cl::opt<bool>
133 AllowDeepWrapper("attributor-allow-deep-wrappers", cl::Hidden,
134 cl::desc("Allow the Attributor to use IP information "
135 "derived from non-exact functions via cloning"),
136 cl::init(false));
137
138// These options can only used for debug builds.
139#ifndef NDEBUG
141 SeedAllowList("attributor-seed-allow-list", cl::Hidden,
142 cl::desc("Comma separated list of attribute names that are "
143 "allowed to be seeded."),
145
147 "attributor-function-seed-allow-list", cl::Hidden,
148 cl::desc("Comma separated list of function names that are "
149 "allowed to be seeded."),
151#endif
152
153static cl::opt<bool>
154 DumpDepGraph("attributor-dump-dep-graph", cl::Hidden,
155 cl::desc("Dump the dependency graph to dot files."),
156 cl::init(false));
157
159 "attributor-depgraph-dot-filename-prefix", cl::Hidden,
160 cl::desc("The prefix used for the CallGraph dot file names."));
161
162static cl::opt<bool> ViewDepGraph("attributor-view-dep-graph", cl::Hidden,
163 cl::desc("View the dependency graph."),
164 cl::init(false));
165
166static cl::opt<bool> PrintDependencies("attributor-print-dep", cl::Hidden,
167 cl::desc("Print attribute dependencies"),
168 cl::init(false));
169
171 "attributor-enable-call-site-specific-deduction", cl::Hidden,
172 cl::desc("Allow the Attributor to do call site specific analysis"),
173 cl::init(false));
174
175static cl::opt<bool>
176 PrintCallGraph("attributor-print-call-graph", cl::Hidden,
177 cl::desc("Print Attributor's internal call graph"),
178 cl::init(false));
179
180static cl::opt<bool> SimplifyAllLoads("attributor-simplify-all-loads",
182 cl::desc("Try to simplify all loads."),
183 cl::init(true));
184
186 "attributor-assume-closed-world", cl::Hidden,
187 cl::desc("Should a closed world be assumed, or not. Default if not set."));
188
189/// Logic operators for the change status enum class.
190///
191///{
196 L = L | R;
197 return L;
198}
203 L = L & R;
204 return L;
205}
206///}
207
208namespace {
209/// NVPTX/AMDGPU address space values (shared between both targets)
210enum class NVPTXAMDGPUAddressSpace : unsigned {
211 Generic = 0,
212 Global = 1,
213 Shared = 3,
214 Constant = 4,
215 Local = 5,
216};
217
218/// SPIRV address space values (StorageClass)
219enum class SPIRVAddressSpace : unsigned {
220 Local = 0, // Function (private/local)
221 Global = 1, // CrossWorkgroup (global)
222 Constant = 2, // UniformConstant (constant)
223 Shared = 3, // Workgroup (shared)
224 Generic = 4, // Generic
225};
226} // namespace
227
228bool AA::isGPU(const Module &M) {
229 Triple T(M.getTargetTriple());
230 return T.isGPU();
231}
232
233bool AA::isGPUSharedAddressSpace(const Module &M, unsigned AS) {
234 assert(AA::isGPU(M) && "Only callable on GPU targets");
235 Triple T(M.getTargetTriple());
236
237 if (T.isSPIRV())
238 return AS == static_cast<unsigned>(SPIRVAddressSpace::Shared);
239
240 return AS == static_cast<unsigned>(NVPTXAMDGPUAddressSpace::Shared);
241}
242
243bool AA::isGPUConstantAddressSpace(const Module &M, unsigned AS) {
244 assert(AA::isGPU(M) && "Only callable on GPU targets");
245 Triple T(M.getTargetTriple());
246
247 if (T.isSPIRV())
248 return AS == static_cast<unsigned>(SPIRVAddressSpace::Constant);
249
250 return AS == static_cast<unsigned>(NVPTXAMDGPUAddressSpace::Constant);
251}
252
253bool AA::isGPULocalAddressSpace(const Module &M, unsigned AS) {
254 assert(AA::isGPU(M) && "Only callable on GPU targets");
255 Triple T(M.getTargetTriple());
256
257 if (T.isSPIRV())
258 return AS == static_cast<unsigned>(SPIRVAddressSpace::Local);
259
260 return AS == static_cast<unsigned>(NVPTXAMDGPUAddressSpace::Local);
261}
262
264 const AbstractAttribute &QueryingAA) {
265 // We are looking for volatile instructions or non-relaxed atomics.
266 if (const auto *CB = dyn_cast<CallBase>(&I)) {
267 if (CB->hasFnAttr(Attribute::NoSync))
268 return true;
269
270 // Non-convergent and readnone imply nosync.
271 if (!CB->isConvergent() && !CB->mayReadOrWriteMemory())
272 return true;
273
274 bool IsKnownNoSync;
276 A, &QueryingAA, IRPosition::callsite_function(*CB),
277 DepClassTy::OPTIONAL, IsKnownNoSync);
278 }
279
280 if (!I.mayReadOrWriteMemory())
281 return true;
282
284}
285
287 const Value &V, bool ForAnalysisOnly) {
288 // TODO: See the AAInstanceInfo class comment.
289 if (!ForAnalysisOnly)
290 return false;
291 auto *InstanceInfoAA = A.getAAFor<AAInstanceInfo>(
293 return InstanceInfoAA && InstanceInfoAA->isAssumedUniqueForAnalysis();
294}
295
296Constant *
298 Value &Obj, Type &Ty, const TargetLibraryInfo *TLI,
299 const DataLayout &DL, AA::RangeTy *RangePtr) {
300 if (Constant *Init = getInitialValueOfAllocation(&Obj, TLI, &Ty))
301 return Init;
302 auto *GV = dyn_cast<GlobalVariable>(&Obj);
303 if (!GV)
304 return nullptr;
305
306 bool UsedAssumedInformation = false;
307 Constant *Initializer = nullptr;
308 if (A.hasGlobalVariableSimplificationCallback(*GV)) {
309 auto AssumedGV = A.getAssumedInitializerFromCallBack(
310 *GV, &QueryingAA, UsedAssumedInformation);
311 Initializer = *AssumedGV;
312 if (!Initializer)
313 return nullptr;
314 } else {
315 if (!GV->hasLocalLinkage()) {
316 // Externally visible global that's either non-constant,
317 // or a constant with an uncertain initializer.
318 if (!GV->hasDefinitiveInitializer() || !GV->isConstant())
319 return nullptr;
320 }
321
322 // Globals with local linkage are always initialized.
323 assert(!GV->hasLocalLinkage() || GV->hasInitializer());
324
325 if (!Initializer)
326 Initializer = GV->getInitializer();
327 }
328
329 if (RangePtr && !RangePtr->offsetOrSizeAreUnknown()) {
330 int64_t StorageSize = DL.getTypeStoreSize(&Ty);
331 if (StorageSize != RangePtr->Size)
332 return nullptr;
333 APInt Offset = APInt(64, RangePtr->Offset);
334 return ConstantFoldLoadFromConst(Initializer, &Ty, Offset, DL);
335 }
336
337 return ConstantFoldLoadFromUniformValue(Initializer, &Ty, DL);
338}
339
340bool AA::isValidInScope(const Value &V, const Function *Scope) {
341 if (isa<Constant>(V))
342 return true;
343 if (auto *I = dyn_cast<Instruction>(&V))
344 return I->getFunction() == Scope;
345 if (auto *A = dyn_cast<Argument>(&V))
346 return A->getParent() == Scope;
347 return false;
348}
349
351 InformationCache &InfoCache) {
352 if (isa<Constant>(VAC.getValue()) || VAC.getValue() == VAC.getCtxI())
353 return true;
354 const Function *Scope = nullptr;
355 const Instruction *CtxI = VAC.getCtxI();
356 if (CtxI)
357 Scope = CtxI->getFunction();
358 if (auto *A = dyn_cast<Argument>(VAC.getValue()))
359 return A->getParent() == Scope;
360 if (auto *I = dyn_cast<Instruction>(VAC.getValue())) {
361 if (I->getFunction() == Scope) {
362 if (const DominatorTree *DT =
364 *Scope))
365 return DT->dominates(I, CtxI);
366 // Local dominance check mostly for the old PM passes.
367 if (CtxI && I->getParent() == CtxI->getParent())
368 return llvm::any_of(
369 make_range(I->getIterator(), I->getParent()->end()),
370 [&](const Instruction &AfterI) { return &AfterI == CtxI; });
371 }
372 }
373 return false;
374}
375
377 if (V.getType() == &Ty)
378 return &V;
379 if (isa<PoisonValue>(V))
380 return PoisonValue::get(&Ty);
381 if (isa<UndefValue>(V))
382 return UndefValue::get(&Ty);
383 if (auto *C = dyn_cast<Constant>(&V)) {
384 if (C->isNullValue() && !Ty.isPtrOrPtrVectorTy())
385 return Constant::getNullValue(&Ty);
386 if (C->getType()->isPointerTy() && Ty.isPointerTy())
387 return ConstantExpr::getPointerCast(C, &Ty);
388 if (C->getType()->getPrimitiveSizeInBits() >= Ty.getPrimitiveSizeInBits()) {
389 if (C->getType()->isIntegerTy() && Ty.isIntegerTy())
390 return ConstantExpr::getTrunc(C, &Ty, /* OnlyIfReduced */ true);
391 if (C->getType()->isFloatingPointTy() && Ty.isFloatingPointTy())
392 return ConstantFoldCastInstruction(Instruction::FPTrunc, C, &Ty);
393 }
394 }
395 return nullptr;
396}
397
398std::optional<Value *>
399AA::combineOptionalValuesInAAValueLatice(const std::optional<Value *> &A,
400 const std::optional<Value *> &B,
401 Type *Ty) {
402 if (A == B)
403 return A;
404 if (!B)
405 return A;
406 if (*B == nullptr)
407 return nullptr;
408 if (!A)
409 return Ty ? getWithType(**B, *Ty) : nullptr;
410 if (*A == nullptr)
411 return nullptr;
412 if (!Ty)
413 Ty = (*A)->getType();
415 return getWithType(**B, *Ty);
416 if (isa<UndefValue>(*B))
417 return A;
418 if (*A && *B && *A == getWithType(**B, *Ty))
419 return A;
420 return nullptr;
421}
422
423template <bool IsLoad, typename Ty>
425 Attributor &A, Ty &I, SmallSetVector<Value *, 4> &PotentialCopies,
426 SmallSetVector<Instruction *, 4> *PotentialValueOrigins,
427 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
428 bool OnlyExact) {
429 LLVM_DEBUG(dbgs() << "Trying to determine the potential copies of " << I
430 << " (only exact: " << OnlyExact << ")\n";);
431
432 Value &Ptr = *I.getPointerOperand();
433 // Containers to remember the pointer infos and new copies while we are not
434 // sure that we can find all of them. If we abort we want to avoid spurious
435 // dependences and potential copies in the provided container.
439
440 const auto *TLI =
441 A.getInfoCache().getTargetLibraryInfoForFunction(*I.getFunction());
442
443 auto Pred = [&](Value &Obj) {
444 LLVM_DEBUG(dbgs() << "Visit underlying object " << Obj << "\n");
445 if (isa<UndefValue>(&Obj))
446 return true;
447 if (isa<ConstantPointerNull>(&Obj)) {
448 // A null pointer access can be undefined but any offset from null may
449 // be OK. We do not try to optimize the latter.
450 if (!NullPointerIsDefined(I.getFunction(),
451 Ptr.getType()->getPointerAddressSpace()) &&
452 A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation,
453 AA::Interprocedural) == &Obj)
454 return true;
456 dbgs() << "Underlying object is a valid nullptr, giving up.\n";);
457 return false;
458 }
459 // TODO: Use assumed noalias return.
460 if (!isa<AllocaInst>(&Obj) && !isa<GlobalVariable>(&Obj) &&
461 !(IsLoad ? isAllocationFn(&Obj, TLI) : isNoAliasCall(&Obj))) {
462 LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << Obj
463 << "\n";);
464 return false;
465 }
466 if (auto *GV = dyn_cast<GlobalVariable>(&Obj))
467 if (!GV->hasLocalLinkage() &&
468 !(GV->isConstant() && GV->hasInitializer())) {
469 LLVM_DEBUG(dbgs() << "Underlying object is global with external "
470 "linkage, not supported yet: "
471 << Obj << "\n";);
472 return false;
473 }
474
475 bool NullOnly = true;
476 bool NullRequired = false;
477 auto CheckForNullOnlyAndUndef = [&](std::optional<Value *> V,
478 bool IsExact) {
479 if (!V || *V == nullptr)
480 NullOnly = false;
481 else if (isa<UndefValue>(*V))
482 /* No op */;
483 else if (isa<Constant>(*V) && cast<Constant>(*V)->isNullValue())
484 NullRequired = !IsExact;
485 else
486 NullOnly = false;
487 };
488
489 auto AdjustWrittenValueType = [&](const AAPointerInfo::Access &Acc,
490 Value &V) {
491 Value *AdjV = AA::getWithType(V, *I.getType());
492 if (!AdjV) {
493 LLVM_DEBUG(dbgs() << "Underlying object written but stored value "
494 "cannot be converted to read type: "
495 << *Acc.getRemoteInst() << " : " << *I.getType()
496 << "\n";);
497 }
498 return AdjV;
499 };
500
501 auto SkipCB = [&](const AAPointerInfo::Access &Acc) {
502 if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))
503 return true;
504 if (IsLoad) {
506 return true;
507 if (PotentialValueOrigins && !isa<AssumeInst>(Acc.getRemoteInst()))
508 return false;
509 if (!Acc.isWrittenValueUnknown())
510 if (Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue()))
511 if (NewCopies.count(V)) {
512 NewCopyOrigins.insert(Acc.getRemoteInst());
513 return true;
514 }
515 if (auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst()))
516 if (Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand()))
517 if (NewCopies.count(V)) {
518 NewCopyOrigins.insert(Acc.getRemoteInst());
519 return true;
520 }
521 }
522 return false;
523 };
524
525 auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) {
526 if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))
527 return true;
528 if (IsLoad && Acc.isWrittenValueYetUndetermined())
529 return true;
530 CheckForNullOnlyAndUndef(Acc.getContent(), IsExact);
531 if (OnlyExact && !IsExact && !NullOnly &&
533 LLVM_DEBUG(dbgs() << "Non exact access " << *Acc.getRemoteInst()
534 << ", abort!\n");
535 return false;
536 }
537 if (NullRequired && !NullOnly) {
538 LLVM_DEBUG(dbgs() << "Required all `null` accesses due to non exact "
539 "one, however found non-null one: "
540 << *Acc.getRemoteInst() << ", abort!\n");
541 return false;
542 }
543 if (IsLoad) {
544 assert(isa<LoadInst>(I) && "Expected load or store instruction only!");
545 if (!Acc.isWrittenValueUnknown()) {
546 Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue());
547 if (!V)
548 return false;
549 NewCopies.insert(V);
550 if (PotentialValueOrigins)
551 NewCopyOrigins.insert(Acc.getRemoteInst());
552 return true;
553 }
554 auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst());
555 if (!SI) {
556 LLVM_DEBUG(dbgs() << "Underlying object written through a non-store "
557 "instruction not supported yet: "
558 << *Acc.getRemoteInst() << "\n";);
559 return false;
560 }
561 Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand());
562 if (!V)
563 return false;
564 NewCopies.insert(V);
565 if (PotentialValueOrigins)
566 NewCopyOrigins.insert(SI);
567 } else {
568 assert(isa<StoreInst>(I) && "Expected load or store instruction only!");
569 auto *LI = dyn_cast<LoadInst>(Acc.getRemoteInst());
570 if (!LI && OnlyExact) {
571 LLVM_DEBUG(dbgs() << "Underlying object read through a non-load "
572 "instruction not supported yet: "
573 << *Acc.getRemoteInst() << "\n";);
574 return false;
575 }
576 NewCopies.insert(Acc.getRemoteInst());
577 }
578 return true;
579 };
580
581 // If the value has been written to we don't need the initial value of the
582 // object.
583 bool HasBeenWrittenTo = false;
584
586 auto *PI = A.getAAFor<AAPointerInfo>(QueryingAA, IRPosition::value(Obj),
588 if (!PI || !PI->forallInterferingAccesses(
589 A, QueryingAA, I,
590 /* FindInterferingWrites */ IsLoad,
591 /* FindInterferingReads */ !IsLoad, CheckAccess,
592 HasBeenWrittenTo, Range, SkipCB)) {
594 dbgs()
595 << "Failed to verify all interfering accesses for underlying object: "
596 << Obj << "\n");
597 return false;
598 }
599
600 if (IsLoad && !HasBeenWrittenTo && !Range.isUnassigned()) {
601 const DataLayout &DL = A.getDataLayout();
602 Value *InitialValue = AA::getInitialValueForObj(
603 A, QueryingAA, Obj, *I.getType(), TLI, DL, &Range);
604 if (!InitialValue) {
605 LLVM_DEBUG(dbgs() << "Could not determine required initial value of "
606 "underlying object, abort!\n");
607 return false;
608 }
609 CheckForNullOnlyAndUndef(InitialValue, /* IsExact */ true);
610 if (NullRequired && !NullOnly) {
611 LLVM_DEBUG(dbgs() << "Non exact access but initial value that is not "
612 "null or undef, abort!\n");
613 return false;
614 }
615
616 NewCopies.insert(InitialValue);
617 if (PotentialValueOrigins)
618 NewCopyOrigins.insert(nullptr);
619 }
620
621 PIs.push_back(PI);
622
623 return true;
624 };
625
626 const auto *AAUO = A.getAAFor<AAUnderlyingObjects>(
627 QueryingAA, IRPosition::value(Ptr), DepClassTy::OPTIONAL);
628 if (!AAUO || !AAUO->forallUnderlyingObjects(Pred)) {
630 dbgs() << "Underlying objects stored into could not be determined\n";);
631 return false;
632 }
633
634 // Only if we were successful collection all potential copies we record
635 // dependences (on non-fix AAPointerInfo AAs). We also only then modify the
636 // given PotentialCopies container.
637 for (const auto *PI : PIs) {
638 if (!PI->getState().isAtFixpoint())
639 UsedAssumedInformation = true;
640 A.recordDependence(*PI, QueryingAA, DepClassTy::OPTIONAL);
641 }
642 PotentialCopies.insert_range(NewCopies);
643 if (PotentialValueOrigins)
644 PotentialValueOrigins->insert_range(NewCopyOrigins);
645
646 return true;
647}
648
650 Attributor &A, LoadInst &LI, SmallSetVector<Value *, 4> &PotentialValues,
651 SmallSetVector<Instruction *, 4> &PotentialValueOrigins,
652 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
653 bool OnlyExact) {
654 return getPotentialCopiesOfMemoryValue</* IsLoad */ true>(
655 A, LI, PotentialValues, &PotentialValueOrigins, QueryingAA,
656 UsedAssumedInformation, OnlyExact);
657}
658
661 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
662 bool OnlyExact) {
663 return getPotentialCopiesOfMemoryValue</* IsLoad */ false>(
664 A, SI, PotentialCopies, nullptr, QueryingAA, UsedAssumedInformation,
665 OnlyExact);
666}
667
669 const AbstractAttribute &QueryingAA,
670 bool RequireReadNone, bool &IsKnown) {
671 if (RequireReadNone) {
673 A, &QueryingAA, IRP, DepClassTy::OPTIONAL, IsKnown,
674 /* IgnoreSubsumingPositions */ true))
675 return true;
677 A, &QueryingAA, IRP, DepClassTy::OPTIONAL, IsKnown,
678 /* IgnoreSubsumingPositions */ true))
679 return true;
680
683 const auto *MemLocAA =
684 A.getAAFor<AAMemoryLocation>(QueryingAA, IRP, DepClassTy::NONE);
685 if (MemLocAA && MemLocAA->isAssumedReadNone()) {
686 IsKnown = MemLocAA->isKnownReadNone();
687 if (!IsKnown)
688 A.recordDependence(*MemLocAA, QueryingAA, DepClassTy::OPTIONAL);
689 return true;
690 }
691 }
692
693 const auto *MemBehaviorAA =
694 A.getAAFor<AAMemoryBehavior>(QueryingAA, IRP, DepClassTy::NONE);
695 if (MemBehaviorAA &&
696 (MemBehaviorAA->isAssumedReadNone() ||
697 (!RequireReadNone && MemBehaviorAA->isAssumedReadOnly()))) {
698 IsKnown = RequireReadNone ? MemBehaviorAA->isKnownReadNone()
699 : MemBehaviorAA->isKnownReadOnly();
700 if (!IsKnown)
701 A.recordDependence(*MemBehaviorAA, QueryingAA, DepClassTy::OPTIONAL);
702 return true;
703 }
704
705 return false;
706}
707
709 const AbstractAttribute &QueryingAA, bool &IsKnown) {
710 return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,
711 /* RequireReadNone */ false, IsKnown);
712}
714 const AbstractAttribute &QueryingAA, bool &IsKnown) {
715 return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,
716 /* RequireReadNone */ true, IsKnown);
717}
718
719static bool
721 const Instruction *ToI, const Function &ToFn,
722 const AbstractAttribute &QueryingAA,
723 const AA::InstExclusionSetTy *ExclusionSet,
724 std::function<bool(const Function &F)> GoBackwardsCB) {
726 dbgs() << "[AA] isPotentiallyReachable @" << ToFn.getName() << " from "
727 << FromI << " [GBCB: " << bool(GoBackwardsCB) << "][#ExS: "
728 << (ExclusionSet ? std::to_string(ExclusionSet->size()) : "none")
729 << "]\n";
730 if (ExclusionSet)
731 for (auto *ES : *ExclusionSet)
732 dbgs() << *ES << "\n";
733 });
734
735 // We know kernels (generally) cannot be called from within the module. Thus,
736 // for reachability we would need to step back from a kernel which would allow
737 // us to reach anything anyway. Even if a kernel is invoked from another
738 // kernel, values like allocas and shared memory are not accessible. We
739 // implicitly check for this situation to avoid costly lookups.
740 if (GoBackwardsCB && &ToFn != FromI.getFunction() &&
741 !GoBackwardsCB(*FromI.getFunction()) && A.getInfoCache().isKernel(ToFn) &&
742 A.getInfoCache().isKernel(*FromI.getFunction())) {
743 LLVM_DEBUG(dbgs() << "[AA] assume kernel cannot be reached from within the "
744 "module; success\n";);
745 return false;
746 }
747
748 // If we can go arbitrarily backwards we will eventually reach an entry point
749 // that can reach ToI. Only if a set of blocks through which we cannot go is
750 // provided, or once we track internal functions not accessible from the
751 // outside, it makes sense to perform backwards analysis in the absence of a
752 // GoBackwardsCB.
753 if (!GoBackwardsCB && !ExclusionSet) {
754 LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI
755 << " is not checked backwards and does not have an "
756 "exclusion set, abort\n");
757 return true;
758 }
759
762 Worklist.push_back(&FromI);
763
764 while (!Worklist.empty()) {
765 const Instruction *CurFromI = Worklist.pop_back_val();
766 if (!Visited.insert(CurFromI).second)
767 continue;
768
769 const Function *FromFn = CurFromI->getFunction();
770 if (FromFn == &ToFn) {
771 if (!ToI)
772 return true;
773 LLVM_DEBUG(dbgs() << "[AA] check " << *ToI << " from " << *CurFromI
774 << " intraprocedurally\n");
775 const auto *ReachabilityAA = A.getAAFor<AAIntraFnReachability>(
776 QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);
777 bool Result = !ReachabilityAA || ReachabilityAA->isAssumedReachable(
778 A, *CurFromI, *ToI, ExclusionSet);
779 LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " "
780 << (Result ? "can potentially " : "cannot ") << "reach "
781 << *ToI << " [Intra]\n");
782 if (Result)
783 return true;
784 }
785
786 bool Result = true;
787 if (!ToFn.isDeclaration() && ToI) {
788 const auto *ToReachabilityAA = A.getAAFor<AAIntraFnReachability>(
789 QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);
790 const Instruction &EntryI = ToFn.getEntryBlock().front();
791 Result = !ToReachabilityAA || ToReachabilityAA->isAssumedReachable(
792 A, EntryI, *ToI, ExclusionSet);
793 LLVM_DEBUG(dbgs() << "[AA] Entry " << EntryI << " of @" << ToFn.getName()
794 << " " << (Result ? "can potentially " : "cannot ")
795 << "reach @" << *ToI << " [ToFn]\n");
796 }
797
798 if (Result) {
799 // The entry of the ToFn can reach the instruction ToI. If the current
800 // instruction is already known to reach the ToFn.
801 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
802 QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);
803 Result = !FnReachabilityAA || FnReachabilityAA->instructionCanReach(
804 A, *CurFromI, ToFn, ExclusionSet);
805 LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " in @" << FromFn->getName()
806 << " " << (Result ? "can potentially " : "cannot ")
807 << "reach @" << ToFn.getName() << " [FromFn]\n");
808 if (Result)
809 return true;
810 }
811
812 // TODO: Check assumed nounwind.
813 const auto *ReachabilityAA = A.getAAFor<AAIntraFnReachability>(
814 QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);
815 auto ReturnInstCB = [&](Instruction &Ret) {
816 bool Result = !ReachabilityAA || ReachabilityAA->isAssumedReachable(
817 A, *CurFromI, Ret, ExclusionSet);
818 LLVM_DEBUG(dbgs() << "[AA][Ret] " << *CurFromI << " "
819 << (Result ? "can potentially " : "cannot ") << "reach "
820 << Ret << " [Intra]\n");
821 return !Result;
822 };
823
824 // Check if we can reach returns.
825 bool UsedAssumedInformation = false;
826 if (A.checkForAllInstructions(ReturnInstCB, FromFn, &QueryingAA,
827 {Instruction::Ret}, UsedAssumedInformation)) {
828 LLVM_DEBUG(dbgs() << "[AA] No return is reachable, done\n");
829 continue;
830 }
831
832 if (!GoBackwardsCB) {
833 LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI
834 << " is not checked backwards, abort\n");
835 return true;
836 }
837
838 // If we do not go backwards from the FromFn we are done here and so far we
839 // could not find a way to reach ToFn/ToI.
840 if (!GoBackwardsCB(*FromFn))
841 continue;
842
843 LLVM_DEBUG(dbgs() << "Stepping backwards to the call sites of @"
844 << FromFn->getName() << "\n");
845
846 auto CheckCallSite = [&](AbstractCallSite ACS) {
847 CallBase *CB = ACS.getInstruction();
848 if (!CB)
849 return false;
850
851 if (isa<InvokeInst>(CB))
852 return false;
853
854 Instruction *Inst = CB->getNextNode();
855 Worklist.push_back(Inst);
856 return true;
857 };
858
859 Result = !A.checkForAllCallSites(CheckCallSite, *FromFn,
860 /* RequireAllCallSites */ true,
861 &QueryingAA, UsedAssumedInformation);
862 if (Result) {
863 LLVM_DEBUG(dbgs() << "[AA] stepping back to call sites from " << *CurFromI
864 << " in @" << FromFn->getName()
865 << " failed, give up\n");
866 return true;
867 }
868
869 LLVM_DEBUG(dbgs() << "[AA] stepped back to call sites from " << *CurFromI
870 << " in @" << FromFn->getName()
871 << " worklist size is: " << Worklist.size() << "\n");
872 }
873 return false;
874}
875
877 Attributor &A, const Instruction &FromI, const Instruction &ToI,
878 const AbstractAttribute &QueryingAA,
879 const AA::InstExclusionSetTy *ExclusionSet,
880 std::function<bool(const Function &F)> GoBackwardsCB) {
881 const Function *ToFn = ToI.getFunction();
882 return ::isPotentiallyReachable(A, FromI, &ToI, *ToFn, QueryingAA,
883 ExclusionSet, GoBackwardsCB);
884}
885
887 Attributor &A, const Instruction &FromI, const Function &ToFn,
888 const AbstractAttribute &QueryingAA,
889 const AA::InstExclusionSetTy *ExclusionSet,
890 std::function<bool(const Function &F)> GoBackwardsCB) {
891 return ::isPotentiallyReachable(A, FromI, /* ToI */ nullptr, ToFn, QueryingAA,
892 ExclusionSet, GoBackwardsCB);
893}
894
896 const AbstractAttribute &QueryingAA) {
897 if (isa<UndefValue>(Obj))
898 return true;
899 if (isa<AllocaInst>(Obj)) {
900 InformationCache &InfoCache = A.getInfoCache();
901 if (!InfoCache.stackIsAccessibleByOtherThreads()) {
903 dbgs() << "[AA] Object '" << Obj
904 << "' is thread local; stack objects are thread local.\n");
905 return true;
906 }
907 bool IsKnownNoCapture;
908 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
909 A, &QueryingAA, IRPosition::value(Obj), DepClassTy::OPTIONAL,
910 IsKnownNoCapture);
911 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj << "' is "
912 << (IsAssumedNoCapture ? "" : "not") << " thread local; "
913 << (IsAssumedNoCapture ? "non-" : "")
914 << "captured stack object.\n");
915 return IsAssumedNoCapture;
916 }
917 if (auto *GV = dyn_cast<GlobalVariable>(&Obj)) {
918 if (GV->isConstant()) {
919 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj
920 << "' is thread local; constant global\n");
921 return true;
922 }
923 if (GV->isThreadLocal()) {
924 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj
925 << "' is thread local; thread local global\n");
926 return true;
927 }
928 }
929
930 if (A.getInfoCache().IsTargetGPU()) {
931 if (AA::isGPULocalAddressSpace(A.getInfoCache().getModule(),
932 Obj.getType()->getPointerAddressSpace())) {
933 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj
934 << "' is thread local; GPU local memory\n");
935 return true;
936 }
938 A.getInfoCache().getModule(),
939 Obj.getType()->getPointerAddressSpace())) {
940 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj
941 << "' is thread local; GPU constant memory\n");
942 return true;
943 }
944 }
945
946 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj << "' is not thread local\n");
947 return false;
948}
949
951 const AbstractAttribute &QueryingAA) {
952 if (!I.mayHaveSideEffects() && !I.mayReadFromMemory())
953 return false;
954
956
957 auto AddLocationPtr = [&](std::optional<MemoryLocation> Loc) {
958 if (!Loc || !Loc->Ptr) {
960 dbgs() << "[AA] Access to unknown location; -> requires barriers\n");
961 return false;
962 }
963 Ptrs.insert(Loc->Ptr);
964 return true;
965 };
966
967 if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&I)) {
968 if (!AddLocationPtr(MemoryLocation::getForDest(MI)))
969 return true;
971 if (!AddLocationPtr(MemoryLocation::getForSource(MTI)))
972 return true;
973 } else if (!AddLocationPtr(MemoryLocation::getOrNone(&I)))
974 return true;
975
976 return isPotentiallyAffectedByBarrier(A, Ptrs.getArrayRef(), QueryingAA, &I);
977}
978
981 const AbstractAttribute &QueryingAA,
982 const Instruction *CtxI) {
983 for (const Value *Ptr : Ptrs) {
984 if (!Ptr) {
985 LLVM_DEBUG(dbgs() << "[AA] nullptr; -> requires barriers\n");
986 return true;
987 }
988
989 auto Pred = [&](Value &Obj) {
990 if (AA::isAssumedThreadLocalObject(A, Obj, QueryingAA))
991 return true;
992 LLVM_DEBUG(dbgs() << "[AA] Access to '" << Obj << "' via '" << *Ptr
993 << "'; -> requires barrier\n");
994 return false;
995 };
996
997 const auto *UnderlyingObjsAA = A.getAAFor<AAUnderlyingObjects>(
998 QueryingAA, IRPosition::value(*Ptr), DepClassTy::OPTIONAL);
999 if (!UnderlyingObjsAA || !UnderlyingObjsAA->forallUnderlyingObjects(Pred))
1000 return true;
1001 }
1002 return false;
1003}
1004
1005/// Return true if \p New is equal or worse than \p Old.
1006static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
1007 if (!Old.isIntAttribute())
1008 return true;
1009
1010 return Old.getValueAsInt() >= New.getValueAsInt();
1011}
1012
1013/// Return the attribute to add to a position to provide the information of
1014/// \p Attr, given the attribute \p Existing of the same kind at the position
1015/// (or none), or an invalid attribute if \p Existing already provides it.
1017 Attribute Existing, bool ForceReplace) {
1018 if (Attr.isEnumAttribute())
1019 return Existing.isValid() ? Attribute() : Attr;
1020 if (Attr.isStringAttribute()) {
1021 if (Existing.isValid() && (!ForceReplace || Existing == Attr))
1022 return Attribute();
1023 return Attr;
1024 }
1025
1026 if (Attr.isIntAttribute()) {
1027 if (!ForceReplace && Attr.getKindAsEnum() == Attribute::Memory) {
1028 MemoryEffects OldME = Existing.isValid() ? Existing.getMemoryEffects()
1030 MemoryEffects ME = Attr.getMemoryEffects() & OldME;
1031 if (ME == OldME)
1032 return Attribute();
1033 return Attribute::getWithMemoryEffects(Ctx, ME);
1034 }
1035 if (Existing.isValid() && !ForceReplace && isEqualOrWorse(Attr, Existing))
1036 return Attribute();
1037 return Attr;
1038 }
1039
1040 if (Attr.isConstantRangeAttribute())
1041 return !ForceReplace && Existing.isValid() ? Attribute() : Attr;
1042
1043 llvm_unreachable("Expected enum or string attribute!");
1044}
1045
1048 return cast<Argument>(&getAnchorValue());
1049
1050 // Not an Argument and no argument number means this is not a call site
1051 // argument, thus we cannot find a callback argument to return.
1052 int ArgNo = getCallSiteArgNo();
1053 if (ArgNo < 0)
1054 return nullptr;
1055
1056 // Use abstract call sites to make the connection between the call site
1057 // values and the ones in callbacks. If a callback was found that makes use
1058 // of the underlying call site operand, we want the corresponding callback
1059 // callee argument and not the direct callee argument.
1060 std::optional<Argument *> CBCandidateArg;
1061 SmallVector<const Use *, 4> CallbackUses;
1062 const auto &CB = cast<CallBase>(getAnchorValue());
1063 AbstractCallSite::getCallbackUses(CB, CallbackUses);
1064 for (const Use *U : CallbackUses) {
1065 AbstractCallSite ACS(U);
1066 assert(ACS && ACS.isCallbackCall());
1067 if (!ACS.getCalledFunction())
1068 continue;
1069
1070 for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {
1071
1072 // Test if the underlying call site operand is argument number u of the
1073 // callback callee.
1074 if (ACS.getCallArgOperandNo(u) != ArgNo)
1075 continue;
1076
1077 assert(ACS.getCalledFunction()->arg_size() > u &&
1078 "ACS mapped into var-args arguments!");
1079 if (CBCandidateArg) {
1080 CBCandidateArg = nullptr;
1081 break;
1082 }
1083 CBCandidateArg = ACS.getCalledFunction()->getArg(u);
1084 }
1085 }
1086
1087 // If we found a unique callback candidate argument, return it.
1088 if (CBCandidateArg && *CBCandidateArg)
1089 return *CBCandidateArg;
1090
1091 // If no callbacks were found, or none used the underlying call site operand
1092 // exclusively, use the direct callee argument if available.
1093 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
1094 if (Callee && Callee->arg_size() > unsigned(ArgNo))
1095 return Callee->getArg(ArgNo);
1096
1097 return nullptr;
1098}
1099
1102 if (getState().isAtFixpoint())
1103 return HasChanged;
1104
1105 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
1106
1107 HasChanged = updateImpl(A);
1108
1109 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
1110 << "\n");
1111
1112 return HasChanged;
1113}
1114
1116 InformationCache &InfoCache,
1117 AttributorConfig Configuration)
1118 : Allocator(InfoCache.Allocator), Functions(Functions),
1119 InfoCache(InfoCache), Configuration(Configuration) {
1120 if (!isClosedWorldModule())
1121 return;
1122 for (Function *Fn : Functions)
1123 if (Fn->hasAddressTaken(/*PutOffender=*/nullptr,
1124 /*IgnoreCallbackUses=*/false,
1125 /*IgnoreAssumeLikeCalls=*/true,
1126 /*IgnoreLLVMUsed=*/true,
1127 /*IgnoreARCAttachedCall=*/false,
1128 /*IgnoreCastedDirectCall=*/true))
1129 InfoCache.IndirectlyCallableFunctions.push_back(Fn);
1130}
1131
1136 "Did expect a valid position!");
1139 if (!Explorer)
1140 return false;
1141
1142 Value &AssociatedValue = IRP.getAssociatedValue();
1143
1144 const Assume2KnowledgeMap &A2K =
1145 getInfoCache().getKnowledgeMap().lookup({&AssociatedValue, AK});
1146
1147 // Check if we found any potential assume use, if not we don't need to create
1148 // explorer iterators.
1149 if (A2K.empty())
1150 return false;
1151
1152 LLVMContext &Ctx = AssociatedValue.getContext();
1153 unsigned AttrsSize = Attrs.size();
1154 auto EIt = Explorer->begin(IRP.getCtxI()),
1155 EEnd = Explorer->end(IRP.getCtxI());
1156 for (const auto &It : A2K)
1157 if (Explorer->findInContextOf(It.first, EIt, EEnd))
1158 Attrs.push_back(Attribute::get(Ctx, AK, It.second.Max));
1159 return AttrsSize != Attrs.size();
1160}
1161
1162template <typename DescTy>
1164Attributor::updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,
1165 function_ref<bool(const DescTy &, AttributeSet,
1166 AttributeMask &, AttrBuilder &)>
1167 CB) {
1168 if (AttrDescs.empty())
1170 switch (IRP.getPositionKind()) {
1174 default:
1175 break;
1176 };
1177
1178 AttributeList AL = IRP.getAttrList();
1179 Value *AttrListAnchor = IRP.getAttrListAnchor();
1180 auto [Iter, Inserted] = AttrsMap.insert({AttrListAnchor, AL});
1181 if (!Inserted)
1182 AL = Iter->second;
1183
1184 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
1185 auto AttrIdx = IRP.getAttrIdx();
1186 AttributeSet AS = AL.getAttributes(AttrIdx);
1187 AttributeMask AM;
1188 AttrBuilder AB(Ctx);
1189
1191 for (const DescTy &AttrDesc : AttrDescs)
1192 if (CB(AttrDesc, AS, AM, AB))
1193 HasChanged = ChangeStatus::CHANGED;
1194
1195 if (HasChanged == ChangeStatus::UNCHANGED)
1197
1198 if (!AM.empty())
1199 AL = AL.removeAttributesAtIndex(Ctx, AttrIdx, AM);
1200 AL = AL.addAttributesAtIndex(Ctx, AttrIdx, AB);
1201
1202 Iter->second = AL;
1203 return HasChanged;
1204}
1205
1208 bool IgnoreSubsumingPositions,
1209 Attribute::AttrKind ImpliedAttributeKind) {
1210 bool Implied = false;
1211 bool HasAttr = false;
1212 auto HasAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,
1213 AttributeMask &, AttrBuilder &) {
1214 if (AttrSet.hasAttribute(Kind)) {
1215 Implied |= Kind != ImpliedAttributeKind;
1216 HasAttr = true;
1217 }
1218 return false;
1219 };
1220 for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {
1221 updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, HasAttrCB);
1222 if (HasAttr)
1223 break;
1224 // The first position returned by the SubsumingPositionIterator is
1225 // always the position itself. If we ignore subsuming positions we
1226 // are done after the first iteration.
1227 if (IgnoreSubsumingPositions)
1228 break;
1229 Implied = true;
1230 }
1231 if (!HasAttr) {
1232 Implied = true;
1233 // Most modules have no assume knowledge.
1234 if (!InfoCache.getKnowledgeMap().empty()) {
1236 for (Attribute::AttrKind AK : AttrKinds)
1237 if (getAttrsFromAssumes(IRP, AK, Attrs)) {
1238 HasAttr = true;
1239 break;
1240 }
1241 }
1242 }
1243
1244 // Check if we should manifest the implied attribute kind at the IRP.
1245 if (ImpliedAttributeKind != Attribute::None && HasAttr && Implied)
1247 ImpliedAttributeKind)});
1248 return HasAttr;
1249}
1250
1254 bool IgnoreSubsumingPositions) {
1255 auto CollectAttrCB = [&](const Attribute::AttrKind &Kind,
1256 AttributeSet AttrSet, AttributeMask &,
1257 AttrBuilder &) {
1258 if (AttrSet.hasAttribute(Kind))
1259 Attrs.push_back(AttrSet.getAttribute(Kind));
1260 return false;
1261 };
1262 for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {
1263 updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, CollectAttrCB);
1264 // The first position returned by the SubsumingPositionIterator is
1265 // always the position itself. If we ignore subsuming positions we
1266 // are done after the first iteration.
1267 if (IgnoreSubsumingPositions)
1268 break;
1269 }
1270 if (!InfoCache.getKnowledgeMap().empty()) {
1271 for (Attribute::AttrKind AK : AttrKinds)
1272 getAttrsFromAssumes(IRP, AK, Attrs);
1273 }
1274}
1275
1278 auto RemoveAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,
1279 AttributeMask &AM, AttrBuilder &) {
1280 if (!AttrSet.hasAttribute(Kind))
1281 return false;
1282 AM.addAttribute(Kind);
1283 return true;
1284 };
1285 return updateAttrMap<Attribute::AttrKind>(IRP, AttrKinds, RemoveAttrCB);
1286}
1287
1289 ArrayRef<StringRef> Attrs) {
1290 auto RemoveAttrCB = [&](StringRef Attr, AttributeSet AttrSet,
1291 AttributeMask &AM, AttrBuilder &) -> bool {
1292 if (!AttrSet.hasAttribute(Attr))
1293 return false;
1294 AM.addAttribute(Attr);
1295 return true;
1296 };
1297
1298 return updateAttrMap<StringRef>(IRP, Attrs, RemoveAttrCB);
1299}
1300
1302 ArrayRef<Attribute> Attrs,
1303 bool ForceReplace) {
1304 if (Attrs.empty())
1306
1307 switch (IRP.getPositionKind()) {
1311 default:
1312 break;
1313 }
1314
1315 AttributeList AL = IRP.getAttrList();
1316 auto [Iter, Inserted] = AttrsMap.insert({IRP.getAttrListAnchor(), AL});
1317 if (!Inserted)
1318 AL = Iter->second;
1319
1320 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
1321 auto AttrIdx = IRP.getAttrIdx();
1322 AttributeSet AS = AL.getAttributes(AttrIdx);
1324 for (Attribute Attr : Attrs) {
1325 Attribute Existing = Attr.isStringAttribute()
1326 ? AS.getAttribute(Attr.getKindAsString())
1327 : AS.getAttribute(Attr.getKindAsEnum());
1328 if (Attribute New = getAttrToAdd(Ctx, Attr, Existing, ForceReplace);
1329 New.isValid())
1330 Added.push_back(New);
1331 }
1332
1333 if (Added.empty())
1335
1336 // Added keeps the order of Attrs, so it is sorted with distinct kinds too.
1337 AL = AL.addSortedAttributesAtIndex(Ctx, AttrIdx, Added);
1338 Iter->second = AL;
1339 return ChangeStatus::CHANGED;
1340}
1341
1343 IRPositions.emplace_back(IRP);
1344
1345 // Helper to determine if operand bundles on a call site are benign or
1346 // potentially problematic. We handle only llvm.assume for now.
1347 auto CanIgnoreOperandBundles = [](const CallBase &CB) {
1348 return (isa<IntrinsicInst>(CB) &&
1349 cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);
1350 };
1351
1352 const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue());
1353 switch (IRP.getPositionKind()) {
1357 return;
1360 IRPositions.emplace_back(IRPosition::function(*IRP.getAnchorScope()));
1361 return;
1363 assert(CB && "Expected call site!");
1364 // TODO: We need to look at the operand bundles similar to the redirection
1365 // in CallBase.
1366 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))
1367 if (auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()))
1368 IRPositions.emplace_back(IRPosition::function(*Callee));
1369 return;
1371 assert(CB && "Expected call site!");
1372 // TODO: We need to look at the operand bundles similar to the redirection
1373 // in CallBase.
1374 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
1375 if (auto *Callee =
1376 dyn_cast_if_present<Function>(CB->getCalledOperand())) {
1377 // The returned position of the callee does not describe the call if
1378 // the call uses a different return type.
1379 bool SameType = Callee->getReturnType() == CB->getType();
1380 if (SameType)
1381 IRPositions.emplace_back(IRPosition::returned(*Callee));
1382 IRPositions.emplace_back(IRPosition::function(*Callee));
1383 for (const Argument &Arg : Callee->args())
1384 if (SameType && Arg.hasReturnedAttr()) {
1385 IRPositions.emplace_back(
1386 IRPosition::callsite_argument(*CB, Arg.getArgNo()));
1387 IRPositions.emplace_back(
1388 IRPosition::value(*CB->getArgOperand(Arg.getArgNo())));
1389 IRPositions.emplace_back(IRPosition::argument(Arg));
1390 }
1391 }
1392 }
1393 IRPositions.emplace_back(IRPosition::callsite_function(*CB));
1394 return;
1396 assert(CB && "Expected call site!");
1397 // TODO: We need to look at the operand bundles similar to the redirection
1398 // in CallBase.
1399 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
1400 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
1401 if (Callee) {
1402 if (Argument *Arg = IRP.getAssociatedArgument())
1403 IRPositions.emplace_back(IRPosition::argument(*Arg));
1404 IRPositions.emplace_back(IRPosition::function(*Callee));
1405 }
1406 }
1407 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
1408 return;
1409 }
1410 }
1411}
1412
1413void IRPosition::verify() {
1414#ifdef EXPENSIVE_CHECKS
1415 switch (getPositionKind()) {
1416 case IRP_INVALID:
1417 assert((CBContext == nullptr) &&
1418 "Invalid position must not have CallBaseContext!");
1419 assert(!Enc.getOpaqueValue() &&
1420 "Expected a nullptr for an invalid position!");
1421 return;
1422 case IRP_FLOAT:
1424 "Expected specialized kind for argument values!");
1425 return;
1426 case IRP_RETURNED:
1427 assert(isa<Function>(getAsValuePtr()) &&
1428 "Expected function for a 'returned' position!");
1429 assert(getAsValuePtr() == &getAssociatedValue() &&
1430 "Associated value mismatch!");
1431 return;
1433 assert((CBContext == nullptr) &&
1434 "'call site returned' position must not have CallBaseContext!");
1435 assert((isa<CallBase>(getAsValuePtr())) &&
1436 "Expected call base for 'call site returned' position!");
1437 assert(getAsValuePtr() == &getAssociatedValue() &&
1438 "Associated value mismatch!");
1439 return;
1440 case IRP_CALL_SITE:
1441 assert((CBContext == nullptr) &&
1442 "'call site function' position must not have CallBaseContext!");
1443 assert((isa<CallBase>(getAsValuePtr())) &&
1444 "Expected call base for 'call site function' position!");
1445 assert(getAsValuePtr() == &getAssociatedValue() &&
1446 "Associated value mismatch!");
1447 return;
1448 case IRP_FUNCTION:
1449 assert(isa<Function>(getAsValuePtr()) &&
1450 "Expected function for a 'function' position!");
1451 assert(getAsValuePtr() == &getAssociatedValue() &&
1452 "Associated value mismatch!");
1453 return;
1454 case IRP_ARGUMENT:
1455 assert(isa<Argument>(getAsValuePtr()) &&
1456 "Expected argument for a 'argument' position!");
1457 assert(getAsValuePtr() == &getAssociatedValue() &&
1458 "Associated value mismatch!");
1459 return;
1461 assert((CBContext == nullptr) &&
1462 "'call site argument' position must not have CallBaseContext!");
1463 Use *U = getAsUsePtr();
1464 (void)U; // Silence unused variable warning.
1465 assert(U && "Expected use for a 'call site argument' position!");
1466 assert(isa<CallBase>(U->getUser()) &&
1467 "Expected call base user for a 'call site argument' position!");
1468 assert(cast<CallBase>(U->getUser())->isArgOperand(U) &&
1469 "Expected call base argument operand for a 'call site argument' "
1470 "position");
1471 assert(cast<CallBase>(U->getUser())->getArgOperandNo(U) ==
1472 unsigned(getCallSiteArgNo()) &&
1473 "Argument number mismatch!");
1474 assert(U->get() == &getAssociatedValue() && "Associated value mismatch!");
1475 return;
1476 }
1477 }
1478#endif
1479}
1480
1481std::optional<Constant *>
1483 const AbstractAttribute &AA,
1484 bool &UsedAssumedInformation) {
1485 // First check all callbacks provided by outside AAs. If any of them returns
1486 // a non-null value that is different from the associated value, or
1487 // std::nullopt, we assume it's simplified.
1488 for (auto &CB : SimplificationCallbacks.lookup(IRP)) {
1489 std::optional<Value *> SimplifiedV = CB(IRP, &AA, UsedAssumedInformation);
1490 if (!SimplifiedV)
1491 return std::nullopt;
1492 if (isa_and_nonnull<Constant>(*SimplifiedV))
1493 return cast<Constant>(*SimplifiedV);
1494 return nullptr;
1495 }
1496 if (auto *C = dyn_cast<Constant>(&IRP.getAssociatedValue()))
1497 return C;
1501 UsedAssumedInformation)) {
1502 if (Values.empty())
1503 return std::nullopt;
1504 if (auto *C = dyn_cast_or_null<Constant>(
1506 return C;
1507 }
1508 return nullptr;
1509}
1510
1512 const IRPosition &IRP, const AbstractAttribute *AA,
1513 bool &UsedAssumedInformation, AA::ValueScope S) {
1514 // First check all callbacks provided by outside AAs. If any of them returns
1515 // a non-null value that is different from the associated value, or
1516 // std::nullopt, we assume it's simplified.
1517 for (auto &CB : SimplificationCallbacks.lookup(IRP))
1518 return CB(IRP, AA, UsedAssumedInformation);
1519
1521 if (!getAssumedSimplifiedValues(IRP, AA, Values, S, UsedAssumedInformation))
1522 return &IRP.getAssociatedValue();
1523 if (Values.empty())
1524 return std::nullopt;
1525 if (AA)
1526 if (Value *V = AAPotentialValues::getSingleValue(*this, *AA, IRP, Values))
1527 return V;
1530 return nullptr;
1531 return &IRP.getAssociatedValue();
1532}
1533
1535 const IRPosition &InitialIRP, const AbstractAttribute *AA,
1537 bool &UsedAssumedInformation, bool RecurseForSelectAndPHI) {
1540 Worklist.push_back(InitialIRP);
1541 while (!Worklist.empty()) {
1542 const IRPosition &IRP = Worklist.pop_back_val();
1543
1544 // First check all callbacks provided by outside AAs. If any of them returns
1545 // a non-null value that is different from the associated value, or
1546 // std::nullopt, we assume it's simplified.
1547 int NV = Values.size();
1548 const auto &SimplificationCBs = SimplificationCallbacks.lookup(IRP);
1549 for (const auto &CB : SimplificationCBs) {
1550 std::optional<Value *> CBResult = CB(IRP, AA, UsedAssumedInformation);
1551 if (!CBResult.has_value())
1552 continue;
1553 Value *V = *CBResult;
1554 if (!V)
1555 return false;
1558 Values.push_back(AA::ValueAndContext{*V, nullptr});
1559 else
1560 return false;
1561 }
1562 if (SimplificationCBs.empty()) {
1563 // If no high-level/outside simplification occurred, use
1564 // AAPotentialValues.
1565 const auto *PotentialValuesAA =
1567 if (PotentialValuesAA &&
1568 PotentialValuesAA->getAssumedSimplifiedValues(*this, Values, S)) {
1569 UsedAssumedInformation |= !PotentialValuesAA->isAtFixpoint();
1570 } else if (IRP.getPositionKind() != IRPosition::IRP_RETURNED) {
1571 Values.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
1572 } else {
1573 // TODO: We could visit all returns and add the operands.
1574 return false;
1575 }
1576 }
1577
1578 if (!RecurseForSelectAndPHI)
1579 break;
1580
1581 for (int I = NV, E = Values.size(); I < E; ++I) {
1582 Value *V = Values[I].getValue();
1583 if (!isa<PHINode>(V) && !isa<SelectInst>(V))
1584 continue;
1585 if (!Seen.insert(V).second)
1586 continue;
1587 // Move the last element to this slot.
1588 Values[I] = Values[E - 1];
1589 // Eliminate the last slot, adjust the indices.
1590 Values.pop_back();
1591 --E;
1592 --I;
1593 // Add a new value (select or phi) to the worklist.
1594 Worklist.push_back(IRPosition::value(*V));
1595 }
1596 }
1597 return true;
1598}
1599
1601 std::optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,
1602 bool &UsedAssumedInformation) {
1603 if (!V)
1604 return V;
1605 if (*V == nullptr || isa<Constant>(*V))
1606 return V;
1607 if (auto *Arg = dyn_cast<Argument>(*V))
1608 if (CB.getCalledOperand() == Arg->getParent() &&
1609 CB.arg_size() > Arg->getArgNo())
1610 if (!Arg->hasPointeeInMemoryValueAttr())
1611 return getAssumedSimplified(
1612 IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,
1613 UsedAssumedInformation, AA::Intraprocedural);
1614 return nullptr;
1615}
1616
1618 // The abstract attributes are allocated via the BumpPtrAllocator Allocator,
1619 // thus we cannot delete them. We can, and want to, destruct them though.
1620 for (auto &It : AAMap) {
1621 AbstractAttribute *AA = It.getSecond();
1622 AA->~AbstractAttribute();
1623 }
1624}
1625
1627 const AAIsDead *FnLivenessAA,
1628 bool &UsedAssumedInformation,
1629 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1630 if (!Configuration.UseLiveness)
1631 return false;
1632 const IRPosition &IRP = AA.getIRPosition();
1633 if (!Functions.count(IRP.getAnchorScope()))
1634 return false;
1635 return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,
1636 CheckBBLivenessOnly, DepClass);
1637}
1638
1640 const AbstractAttribute *QueryingAA,
1641 const AAIsDead *FnLivenessAA,
1642 bool &UsedAssumedInformation,
1643 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1644 if (!Configuration.UseLiveness)
1645 return false;
1646 Instruction *UserI = dyn_cast<Instruction>(U.getUser());
1647 if (!UserI)
1648 return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
1649 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1650
1651 if (auto *CB = dyn_cast<CallBase>(UserI)) {
1652 // For call site argument uses we can check if the argument is
1653 // unused/dead.
1654 if (CB->isArgOperand(&U)) {
1655 const IRPosition &CSArgPos =
1656 IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
1657 return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
1658 UsedAssumedInformation, CheckBBLivenessOnly,
1659 DepClass);
1660 }
1661 } else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
1662 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
1663 return isAssumedDead(RetPos, QueryingAA, FnLivenessAA,
1664 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1665 } else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
1666 BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
1667 return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
1668 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1669 } else if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) {
1670 if (!CheckBBLivenessOnly && SI->getPointerOperand() != U.get()) {
1671 const IRPosition IRP = IRPosition::inst(*SI);
1672 const AAIsDead *IsDeadAA =
1674 if (IsDeadAA && IsDeadAA->isRemovableStore()) {
1675 if (QueryingAA)
1676 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1677 if (!IsDeadAA->isKnown(AAIsDead::IS_REMOVABLE))
1678 UsedAssumedInformation = true;
1679 return true;
1680 }
1681 }
1682 }
1683
1684 return isAssumedDead(IRPosition::inst(*UserI), QueryingAA, FnLivenessAA,
1685 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1686}
1687
1689 const AbstractAttribute *QueryingAA,
1690 const AAIsDead *FnLivenessAA,
1691 bool &UsedAssumedInformation,
1692 bool CheckBBLivenessOnly, DepClassTy DepClass,
1693 bool CheckForDeadStore) {
1694 if (!Configuration.UseLiveness)
1695 return false;
1696 const IRPosition::CallBaseContext *CBCtx =
1697 QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;
1698
1699 if (ManifestAddedBlocks.contains(I.getParent()))
1700 return false;
1701
1702 const Function &F = *I.getFunction();
1703 if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)
1704 FnLivenessAA = getOrCreateAAFor<AAIsDead>(IRPosition::function(F, CBCtx),
1705 QueryingAA, DepClassTy::NONE);
1706
1707 // Don't use recursive reasoning.
1708 if (!FnLivenessAA || QueryingAA == FnLivenessAA)
1709 return false;
1710
1711 // If we have a context instruction and a liveness AA we use it.
1712 if (CheckBBLivenessOnly ? FnLivenessAA->isAssumedDead(I.getParent())
1713 : FnLivenessAA->isAssumedDead(&I)) {
1714 if (QueryingAA)
1715 recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
1716 if (!FnLivenessAA->isKnownDead(&I))
1717 UsedAssumedInformation = true;
1718 return true;
1719 }
1720
1721 if (CheckBBLivenessOnly)
1722 return false;
1723
1724 const IRPosition IRP = IRPosition::inst(I, CBCtx);
1725 const AAIsDead *IsDeadAA =
1727
1728 // Don't use recursive reasoning.
1729 if (!IsDeadAA || QueryingAA == IsDeadAA)
1730 return false;
1731
1732 if (IsDeadAA->isAssumedDead()) {
1733 if (QueryingAA)
1734 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1735 if (!IsDeadAA->isKnownDead())
1736 UsedAssumedInformation = true;
1737 return true;
1738 }
1739
1740 if (CheckForDeadStore && isa<StoreInst>(I) && IsDeadAA->isRemovableStore()) {
1741 if (QueryingAA)
1742 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1743 if (!IsDeadAA->isKnownDead())
1744 UsedAssumedInformation = true;
1745 return true;
1746 }
1747
1748 return false;
1749}
1750
1752 const AbstractAttribute *QueryingAA,
1753 const AAIsDead *FnLivenessAA,
1754 bool &UsedAssumedInformation,
1755 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1756 if (!Configuration.UseLiveness)
1757 return false;
1758 // Don't check liveness for constants, e.g. functions, used as (floating)
1759 // values since the context instruction and such is here meaningless.
1762 return false;
1763 }
1764
1765 Instruction *CtxI = IRP.getCtxI();
1766 if (CtxI &&
1767 isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,
1768 /* CheckBBLivenessOnly */ true,
1769 CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
1770 return true;
1771
1772 if (CheckBBLivenessOnly)
1773 return false;
1774
1775 // If we haven't succeeded we query the specific liveness info for the IRP.
1776 const AAIsDead *IsDeadAA;
1778 IsDeadAA = getOrCreateAAFor<AAIsDead>(
1780 QueryingAA, DepClassTy::NONE);
1781 else
1782 IsDeadAA = getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);
1783
1784 // Don't use recursive reasoning.
1785 if (!IsDeadAA || QueryingAA == IsDeadAA)
1786 return false;
1787
1788 if (IsDeadAA->isAssumedDead()) {
1789 if (QueryingAA)
1790 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1791 if (!IsDeadAA->isKnownDead())
1792 UsedAssumedInformation = true;
1793 return true;
1794 }
1795
1796 return false;
1797}
1798
1800 const AbstractAttribute *QueryingAA,
1801 const AAIsDead *FnLivenessAA,
1802 DepClassTy DepClass) {
1803 if (!Configuration.UseLiveness)
1804 return false;
1805 const Function &F = *BB.getParent();
1806 if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)
1808 QueryingAA, DepClassTy::NONE);
1809
1810 // Don't use recursive reasoning.
1811 if (!FnLivenessAA || QueryingAA == FnLivenessAA)
1812 return false;
1813
1814 if (FnLivenessAA->isAssumedDead(&BB)) {
1815 if (QueryingAA)
1816 recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
1817 return true;
1818 }
1819
1820 return false;
1821}
1822
1825 const AbstractAttribute &QueryingAA, const CallBase &CB) {
1826 if (const Function *Callee = dyn_cast<Function>(CB.getCalledOperand()))
1827 return Pred(Callee);
1828
1829 const auto *CallEdgesAA = getAAFor<AACallEdges>(
1831 if (!CallEdgesAA || CallEdgesAA->hasUnknownCallee())
1832 return false;
1833
1834 const auto &Callees = CallEdgesAA->getOptimisticEdges();
1835 return Pred(Callees.getArrayRef());
1836}
1837
1838bool canMarkAsVisited(const User *Usr) {
1839 return isa<PHINode>(Usr) || !isa<Instruction>(Usr);
1840}
1841
1843 function_ref<bool(const Use &, bool &)> Pred,
1844 const AbstractAttribute &QueryingAA, const Value &V,
1845 bool CheckBBLivenessOnly, DepClassTy LivenessDepClass,
1846 bool IgnoreDroppableUses,
1847 function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB) {
1848
1849 // Check virtual uses first.
1850 for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&V))
1851 if (!CB(*this, &QueryingAA))
1852 return false;
1853
1854 if (isa<ConstantData>(V))
1855 return false;
1856
1857 // Check the trivial case first as it catches void values.
1858 if (V.use_empty())
1859 return true;
1860
1861 const IRPosition &IRP = QueryingAA.getIRPosition();
1864
1865 auto AddUsers = [&](const Value &V, const Use *OldUse) {
1866 for (const Use &UU : V.uses()) {
1867 if (OldUse && EquivalentUseCB && !EquivalentUseCB(*OldUse, UU)) {
1868 LLVM_DEBUG(dbgs() << "[Attributor] Potential copy was "
1869 "rejected by the equivalence call back: "
1870 << *UU << "!\n");
1871 return false;
1872 }
1873
1874 Worklist.push_back(&UU);
1875 }
1876 return true;
1877 };
1878
1879 AddUsers(V, /* OldUse */ nullptr);
1880
1881 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
1882 << " initial uses to check\n");
1883
1884 const Function *ScopeFn = IRP.getAnchorScope();
1885 const auto *LivenessAA =
1886 ScopeFn ? getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
1888 : nullptr;
1889
1890 while (!Worklist.empty()) {
1891 const Use *U = Worklist.pop_back_val();
1892 if (canMarkAsVisited(U->getUser()) && !Visited.insert(U).second)
1893 continue;
1895 if (auto *Fn = dyn_cast<Function>(U->getUser()))
1896 dbgs() << "[Attributor] Check use: " << **U << " in " << Fn->getName()
1897 << "\n";
1898 else
1899 dbgs() << "[Attributor] Check use: " << **U << " in " << *U->getUser()
1900 << "\n";
1901 });
1902 bool UsedAssumedInformation = false;
1903 if (isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,
1904 CheckBBLivenessOnly, LivenessDepClass)) {
1906 dbgs() << "[Attributor] Dead use, skip!\n");
1907 continue;
1908 }
1909 if (IgnoreDroppableUses && U->getUser()->isDroppable()) {
1911 dbgs() << "[Attributor] Droppable user, skip!\n");
1912 continue;
1913 }
1914
1915 if (auto *SI = dyn_cast<StoreInst>(U->getUser())) {
1916 if (&SI->getOperandUse(0) == U) {
1917 if (!Visited.insert(U).second)
1918 continue;
1919 SmallSetVector<Value *, 4> PotentialCopies;
1921 *this, *SI, PotentialCopies, QueryingAA, UsedAssumedInformation,
1922 /* OnlyExact */ true)) {
1924 dbgs()
1925 << "[Attributor] Value is stored, continue with "
1926 << PotentialCopies.size()
1927 << " potential copies instead!\n");
1928 for (Value *PotentialCopy : PotentialCopies)
1929 if (!AddUsers(*PotentialCopy, U))
1930 return false;
1931 continue;
1932 }
1933 }
1934 }
1935
1936 bool Follow = false;
1937 if (!Pred(*U, Follow))
1938 return false;
1939 if (!Follow)
1940 continue;
1941
1942 User &Usr = *U->getUser();
1943 AddUsers(Usr, /* OldUse */ nullptr);
1944 }
1945
1946 return true;
1947}
1948
1950 const AbstractAttribute &QueryingAA,
1951 bool RequireAllCallSites,
1952 bool &UsedAssumedInformation) {
1953 // We can try to determine information from
1954 // the call sites. However, this is only possible all call sites are known,
1955 // hence the function has internal linkage.
1956 const IRPosition &IRP = QueryingAA.getIRPosition();
1957 const Function *AssociatedFunction = IRP.getAssociatedFunction();
1958 if (!AssociatedFunction) {
1959 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
1960 << "\n");
1961 return false;
1962 }
1963
1964 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
1965 &QueryingAA, UsedAssumedInformation);
1966}
1967
1969 const Function &Fn,
1970 bool RequireAllCallSites,
1971 const AbstractAttribute *QueryingAA,
1972 bool &UsedAssumedInformation,
1973 bool CheckPotentiallyDead) {
1974 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
1975 LLVM_DEBUG(
1976 dbgs()
1977 << "[Attributor] Function " << Fn.getName()
1978 << " has no internal linkage, hence not all call sites are known\n");
1979 return false;
1980 }
1981 // Check virtual uses first.
1982 for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&Fn))
1983 if (!CB(*this, QueryingAA))
1984 return false;
1985
1987 for (unsigned u = 0; u < Uses.size(); ++u) {
1988 const Use &U = *Uses[u];
1990 if (auto *Fn = dyn_cast<Function>(U))
1991 dbgs() << "[Attributor] Check use: " << Fn->getName() << " in "
1992 << *U.getUser() << "\n";
1993 else
1994 dbgs() << "[Attributor] Check use: " << *U << " in " << *U.getUser()
1995 << "\n";
1996 });
1997 if (!CheckPotentiallyDead &&
1998 isAssumedDead(U, QueryingAA, nullptr, UsedAssumedInformation,
1999 /* CheckBBLivenessOnly */ true)) {
2001 dbgs() << "[Attributor] Dead use, skip!\n");
2002 continue;
2003 }
2004 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
2005 if (CE->isCast() && CE->getType()->isPointerTy()) {
2007 dbgs() << "[Attributor] Use, is constant cast expression, add "
2008 << CE->getNumUses() << " uses of that expression instead!\n";
2009 });
2010 for (const Use &CEU : CE->uses())
2011 Uses.push_back(&CEU);
2012 continue;
2013 }
2014 }
2015
2016 AbstractCallSite ACS(&U);
2017 if (!ACS) {
2018 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
2019 << " has non call site use " << *U.get() << " in "
2020 << *U.getUser() << "\n");
2021 return false;
2022 }
2023
2024 const Use *EffectiveUse =
2025 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
2026 if (!ACS.isCallee(EffectiveUse)) {
2027 if (!RequireAllCallSites) {
2028 LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()
2029 << " is not a call of " << Fn.getName()
2030 << ", skip use\n");
2031 continue;
2032 }
2033 LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()
2034 << " is an invalid use of " << Fn.getName() << "\n");
2035 return false;
2036 }
2037
2038 // Make sure the arguments that can be matched between the call site and the
2039 // callee argee on their type. It is unlikely they do not and it doesn't
2040 // make sense for all attributes to know/care about this.
2041 assert(&Fn == ACS.getCalledFunction() && "Expected known callee");
2042 unsigned MinArgsParams =
2043 std::min(size_t(ACS.getNumArgOperands()), Fn.arg_size());
2044 for (unsigned u = 0; u < MinArgsParams; ++u) {
2045 Value *CSArgOp = ACS.getCallArgOperand(u);
2046 if (CSArgOp && Fn.getArg(u)->getType() != CSArgOp->getType()) {
2047 LLVM_DEBUG(
2048 dbgs() << "[Attributor] Call site / callee argument type mismatch ["
2049 << u << "@" << Fn.getName() << ": "
2050 << *Fn.getArg(u)->getType() << " vs. "
2051 << *ACS.getCallArgOperand(u)->getType() << "\n");
2052 return false;
2053 }
2054 }
2055
2056 if (Pred(ACS))
2057 continue;
2058
2059 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
2060 << *ACS.getInstruction() << "\n");
2061 return false;
2062 }
2063
2064 return true;
2065}
2066
2067bool Attributor::shouldPropagateCallBaseContext(const IRPosition &IRP) {
2068 // TODO: Maintain a cache of Values that are
2069 // on the pathway from a Argument to a Instruction that would effect the
2070 // liveness/return state etc.
2072}
2073
2075 const AbstractAttribute &QueryingAA,
2077 bool RecurseForSelectAndPHI) {
2078
2079 const IRPosition &IRP = QueryingAA.getIRPosition();
2080 const Function *AssociatedFunction = IRP.getAssociatedFunction();
2081 if (!AssociatedFunction)
2082 return false;
2083
2084 bool UsedAssumedInformation = false;
2087 IRPosition::returned(*AssociatedFunction), &QueryingAA, Values, S,
2088 UsedAssumedInformation, RecurseForSelectAndPHI))
2089 return false;
2090
2091 return llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
2092 return Pred(*VAC.getValue());
2093 });
2094}
2095
2098 function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,
2099 const AAIsDead *LivenessAA, ArrayRef<unsigned> Opcodes,
2100 bool &UsedAssumedInformation, bool CheckBBLivenessOnly = false,
2101 bool CheckPotentiallyDead = false) {
2102 for (unsigned Opcode : Opcodes) {
2103 // Check if we have instructions with this opcode at all first.
2104 auto *Insts = OpcodeInstMap[Opcode];
2105 if (!Insts)
2106 continue;
2107
2108 for (Instruction *I : *Insts) {
2109 // Skip dead instructions.
2110 if (A && !CheckPotentiallyDead &&
2111 A->isAssumedDead(IRPosition::inst(*I), QueryingAA, LivenessAA,
2112 UsedAssumedInformation, CheckBBLivenessOnly)) {
2114 dbgs() << "[Attributor] Instruction " << *I
2115 << " is potentially dead, skip!\n";);
2116 continue;
2117 }
2118
2119 if (!Pred(*I))
2120 return false;
2121 }
2122 }
2123 return true;
2124}
2125
2127 const Function *Fn,
2128 const AbstractAttribute *QueryingAA,
2129 ArrayRef<unsigned> Opcodes,
2130 bool &UsedAssumedInformation,
2131 bool CheckBBLivenessOnly,
2132 bool CheckPotentiallyDead) {
2133 // Since we need to provide instructions we have to have an exact definition.
2134 if (!Fn || Fn->isDeclaration())
2135 return false;
2136
2137 const IRPosition &QueryIRP = IRPosition::function(*Fn);
2138 const auto *LivenessAA =
2139 CheckPotentiallyDead && QueryingAA
2140 ? (getAAFor<AAIsDead>(*QueryingAA, QueryIRP, DepClassTy::NONE))
2141 : nullptr;
2142
2143 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
2144 if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, QueryingAA,
2145 LivenessAA, Opcodes, UsedAssumedInformation,
2146 CheckBBLivenessOnly, CheckPotentiallyDead))
2147 return false;
2148
2149 return true;
2150}
2151
2153 const AbstractAttribute &QueryingAA,
2154 ArrayRef<unsigned> Opcodes,
2155 bool &UsedAssumedInformation,
2156 bool CheckBBLivenessOnly,
2157 bool CheckPotentiallyDead) {
2158 const IRPosition &IRP = QueryingAA.getIRPosition();
2159 const Function *AssociatedFunction = IRP.getAssociatedFunction();
2160 return checkForAllInstructions(Pred, AssociatedFunction, &QueryingAA, Opcodes,
2161 UsedAssumedInformation, CheckBBLivenessOnly,
2162 CheckPotentiallyDead);
2163}
2164
2166 function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA,
2167 bool &UsedAssumedInformation) {
2168 TimeTraceScope TS("checkForAllReadWriteInstructions");
2169
2170 const Function *AssociatedFunction =
2171 QueryingAA.getIRPosition().getAssociatedFunction();
2172 if (!AssociatedFunction)
2173 return false;
2174
2175 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
2176 const auto *LivenessAA =
2177 getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE);
2178
2179 for (Instruction *I :
2180 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
2181 // Skip dead instructions.
2182 if (isAssumedDead(IRPosition::inst(*I), &QueryingAA, LivenessAA,
2183 UsedAssumedInformation))
2184 continue;
2185
2186 if (!Pred(*I))
2187 return false;
2188 }
2189
2190 return true;
2191}
2192
2193void Attributor::runTillFixpoint() {
2194 TimeTraceScope TimeScope("Attributor::runTillFixpoint");
2195 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
2196 << DG.SyntheticRoot.Deps.size()
2197 << " abstract attributes.\n");
2198
2199 // Now that all abstract attributes are collected and initialized we start
2200 // the abstract analysis.
2201
2202 unsigned IterationCounter = 1;
2203 unsigned MaxIterations =
2204 Configuration.MaxFixpointIterations.value_or(SetFixpointIterations);
2205
2207 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
2208 Worklist.insert_range(DG.SyntheticRoot);
2209
2210 do {
2211 // Remember the size to determine new attributes.
2212 size_t NumAAs = DG.SyntheticRoot.Deps.size();
2213 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
2214 << ", Worklist size: " << Worklist.size() << "\n");
2215
2216 // For invalid AAs we can fix dependent AAs that have a required dependence,
2217 // thereby folding long dependence chains in a single step without the need
2218 // to run updates.
2219 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
2220 AbstractAttribute *InvalidAA = InvalidAAs[u];
2221
2222 // Check the dependences to fast track invalidation.
2224 dbgs() << "[Attributor] InvalidAA: " << *InvalidAA
2225 << " has " << InvalidAA->Deps.size()
2226 << " required & optional dependences\n");
2227 for (auto &DepIt : InvalidAA->Deps) {
2228 AbstractAttribute *DepAA = cast<AbstractAttribute>(DepIt.getPointer());
2229 if (DepIt.getInt() == unsigned(DepClassTy::OPTIONAL)) {
2231 dbgs() << " - recompute: " << *DepAA);
2232 Worklist.insert(DepAA);
2233 continue;
2234 }
2236 << " - invalidate: " << *DepAA);
2238 assert(DepAA->getState().isAtFixpoint() && "Expected fixpoint state!");
2239 if (!DepAA->getState().isValidState())
2240 InvalidAAs.insert(DepAA);
2241 else
2242 ChangedAAs.push_back(DepAA);
2243 }
2244 InvalidAA->Deps.clear();
2245 }
2246
2247 // Add all abstract attributes that are potentially dependent on one that
2248 // changed to the work list.
2249 for (AbstractAttribute *ChangedAA : ChangedAAs) {
2250 for (auto &DepIt : ChangedAA->Deps)
2251 Worklist.insert(cast<AbstractAttribute>(DepIt.getPointer()));
2252 ChangedAA->Deps.clear();
2253 }
2254
2255 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
2256 << ", Worklist+Dependent size: " << Worklist.size()
2257 << "\n");
2258
2259 // Reset the changed and invalid set.
2260 ChangedAAs.clear();
2261 InvalidAAs.clear();
2262
2263 // Update all abstract attribute in the work list and record the ones that
2264 // changed.
2265 for (AbstractAttribute *AA : Worklist) {
2266 const auto &AAState = AA->getState();
2267 if (!AAState.isAtFixpoint())
2268 if (updateAA(*AA) == ChangeStatus::CHANGED)
2269 ChangedAAs.push_back(AA);
2270
2271 // Use the InvalidAAs vector to propagate invalid states fast transitively
2272 // without requiring updates.
2273 if (!AAState.isValidState())
2274 InvalidAAs.insert(AA);
2275 }
2276
2277 // Add attributes to the changed set if they have been created in the last
2278 // iteration.
2279 ChangedAAs.append(DG.SyntheticRoot.begin() + NumAAs,
2280 DG.SyntheticRoot.end());
2281
2282 // Reset the work list and repopulate with the changed abstract attributes.
2283 // Note that dependent ones are added above.
2284 Worklist.clear();
2285 Worklist.insert_range(ChangedAAs);
2286 Worklist.insert_range(QueryAAsAwaitingUpdate);
2287 QueryAAsAwaitingUpdate.clear();
2288
2289 } while (!Worklist.empty() && (IterationCounter++ < MaxIterations));
2290
2291 if (IterationCounter > MaxIterations && !Functions.empty()) {
2292 auto Remark = [&](OptimizationRemarkMissed ORM) {
2293 return ORM << "Attributor did not reach a fixpoint after "
2294 << ore::NV("Iterations", MaxIterations) << " iterations.";
2295 };
2296 Function *F = Functions.front();
2298 }
2299
2300 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
2301 << IterationCounter << "/" << MaxIterations
2302 << " iterations\n");
2303
2304 // Reset abstract arguments not settled in a sound fixpoint by now. This
2305 // happens when we stopped the fixpoint iteration early. Note that only the
2306 // ones marked as "changed" *and* the ones transitively depending on them
2307 // need to be reverted to a pessimistic state. Others might not be in a
2308 // fixpoint state but we can use the optimistic results for them anyway.
2309 SmallPtrSet<AbstractAttribute *, 32> Visited;
2310 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
2311 AbstractAttribute *ChangedAA = ChangedAAs[u];
2312 if (!Visited.insert(ChangedAA).second)
2313 continue;
2314
2315 AbstractState &State = ChangedAA->getState();
2316 if (!State.isAtFixpoint()) {
2318
2319 NumAttributesTimedOut++;
2320 }
2321
2322 for (auto &DepIt : ChangedAA->Deps)
2323 ChangedAAs.push_back(cast<AbstractAttribute>(DepIt.getPointer()));
2324 ChangedAA->Deps.clear();
2325 }
2326
2327 LLVM_DEBUG({
2328 if (!Visited.empty())
2329 dbgs() << "\n[Attributor] Finalized " << Visited.size()
2330 << " abstract attributes.\n";
2331 });
2332}
2333
2335 assert(AA.isQueryAA() &&
2336 "Non-query AAs should not be required to register for updates!");
2337 QueryAAsAwaitingUpdate.insert(&AA);
2338}
2339
2340ChangeStatus Attributor::manifestAttributes() {
2341 TimeTraceScope TimeScope("Attributor::manifestAttributes");
2342 size_t NumFinalAAs = DG.SyntheticRoot.Deps.size();
2343
2344 unsigned NumManifested = 0;
2345 unsigned NumAtFixpoint = 0;
2346 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
2347 for (auto &DepAA : DG.SyntheticRoot.Deps) {
2348 AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
2349 AbstractState &State = AA->getState();
2350
2351 // If there is not already a fixpoint reached, we can now take the
2352 // optimistic state. This is correct because we enforced a pessimistic one
2353 // on abstract attributes that were transitively dependent on a changed one
2354 // already above.
2355 if (!State.isAtFixpoint())
2356 State.indicateOptimisticFixpoint();
2357
2358 // We must not manifest Attributes that use Callbase info.
2359 if (AA->hasCallBaseContext())
2360 continue;
2361 // If the state is invalid, we do not try to manifest it.
2362 if (!State.isValidState())
2363 continue;
2364
2365 if (AA->getCtxI() && !isRunOn(*AA->getAnchorScope()))
2366 continue;
2367
2368 // Skip dead code.
2369 bool UsedAssumedInformation = false;
2370 if (isAssumedDead(*AA, nullptr, UsedAssumedInformation,
2371 /* CheckBBLivenessOnly */ true))
2372 continue;
2373 // Check if the manifest debug counter that allows skipping manifestation of
2374 // AAs
2375 if (!DebugCounter::shouldExecute(ManifestDBGCounter))
2376 continue;
2377 // Manifest the state and record if we changed the IR.
2378 ChangeStatus LocalChange = AA->manifest(*this);
2379 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
2380 AA->trackStatistics();
2381 LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA
2382 << "\n");
2383
2384 ManifestChange = ManifestChange | LocalChange;
2385
2386 NumAtFixpoint++;
2387 NumManifested += (LocalChange == ChangeStatus::CHANGED);
2388 }
2389
2390 (void)NumManifested;
2391 (void)NumAtFixpoint;
2392 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
2393 << " arguments while " << NumAtFixpoint
2394 << " were in a valid fixpoint state\n");
2395
2396 NumAttributesManifested += NumManifested;
2397 NumAttributesValidFixpoint += NumAtFixpoint;
2398
2399 (void)NumFinalAAs;
2400 if (NumFinalAAs != DG.SyntheticRoot.Deps.size()) {
2401 auto DepIt = DG.SyntheticRoot.Deps.begin();
2402 for (unsigned u = 0; u < NumFinalAAs; ++u)
2403 ++DepIt;
2404 for (unsigned u = NumFinalAAs; u < DG.SyntheticRoot.Deps.size();
2405 ++u, ++DepIt) {
2406 errs() << "Unexpected abstract attribute: "
2407 << cast<AbstractAttribute>(DepIt->getPointer()) << " :: "
2408 << cast<AbstractAttribute>(DepIt->getPointer())
2409 ->getIRPosition()
2410 .getAssociatedValue()
2411 << "\n";
2412 }
2413 llvm_unreachable("Expected the final number of abstract attributes to "
2414 "remain unchanged!");
2415 }
2416
2417 for (auto &It : AttrsMap) {
2418 AttributeList &AL = It.getSecond();
2419 const IRPosition &IRP =
2420 isa<Function>(It.getFirst())
2421 ? IRPosition::function(*cast<Function>(It.getFirst()))
2422 : IRPosition::callsite_function(*cast<CallBase>(It.getFirst()));
2423 if (IRP.getAttrList() == AL)
2424 continue;
2425 IRP.setAttrList(AL);
2426 AttrModifiedFunctions.insert(IRP.getAnchorScope());
2427 }
2428
2429 return ManifestChange;
2430}
2431
2432void Attributor::identifyDeadInternalFunctions() {
2433 // Early exit if we don't intend to delete functions.
2434 if (!Configuration.DeleteFns)
2435 return;
2436
2437 // To avoid triggering an assertion in the lazy call graph we will not delete
2438 // any internal library functions. We should modify the assertion though and
2439 // allow internals to be deleted.
2440 const auto *TLI =
2441 isModulePass()
2442 ? nullptr
2443 : getInfoCache().getTargetLibraryInfoForFunction(*Functions.back());
2444
2445 // Identify dead internal functions and delete them. This happens outside
2446 // the other fixpoint analysis as we might treat potentially dead functions
2447 // as live to lower the number of iterations. If they happen to be dead, the
2448 // below fixpoint loop will identify and eliminate them.
2449
2450 SmallVector<Function *, 8> InternalFns;
2451 for (Function *F : Functions)
2452 if (F->hasLocalLinkage() &&
2453 (isModulePass() || TLI->getLibFunc(*F) == NotLibFunc))
2454 InternalFns.push_back(F);
2455
2456 SmallPtrSet<Function *, 8> LiveInternalFns;
2457 bool FoundLiveInternal = true;
2458 while (FoundLiveInternal) {
2459 FoundLiveInternal = false;
2460 for (Function *&F : InternalFns) {
2461 if (!F)
2462 continue;
2463
2464 bool UsedAssumedInformation = false;
2466 [&](AbstractCallSite ACS) {
2468 return ToBeDeletedFunctions.count(Callee) ||
2469 (Functions.count(Callee) && Callee->hasLocalLinkage() &&
2470 !LiveInternalFns.count(Callee));
2471 },
2472 *F, true, nullptr, UsedAssumedInformation)) {
2473 continue;
2474 }
2475
2476 LiveInternalFns.insert(F);
2477 F = nullptr;
2478 FoundLiveInternal = true;
2479 }
2480 }
2481
2482 for (Function *F : InternalFns)
2483 if (F)
2484 ToBeDeletedFunctions.insert(F);
2485}
2486
2487ChangeStatus Attributor::cleanupIR() {
2488 TimeTraceScope TimeScope("Attributor::cleanupIR");
2489 // Delete stuff at the end to avoid invalid references and a nice order.
2490 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete/replace at least "
2491 << ToBeDeletedFunctions.size() << " functions and "
2492 << ToBeDeletedBlocks.size() << " blocks and "
2493 << ToBeDeletedInsts.size() << " instructions and "
2494 << ToBeChangedValues.size() << " values and "
2495 << ToBeChangedUses.size() << " uses. To insert "
2496 << ToBeChangedToUnreachableInsts.size()
2497 << " unreachables.\n"
2498 << "Preserve manifest added " << ManifestAddedBlocks.size()
2499 << " blocks\n");
2500
2502 SmallVector<Instruction *, 32> TerminatorsToFold;
2503
2504 auto ReplaceUse = [&](Use *U, Value *NewV) {
2505 Value *OldV = U->get();
2506
2507 // If we plan to replace NewV we need to update it at this point.
2508 do {
2509 const auto &Entry = ToBeChangedValues.lookup(NewV);
2510 if (!get<0>(Entry))
2511 break;
2512 NewV = get<0>(Entry);
2513 } while (true);
2514
2515 Instruction *I = dyn_cast<Instruction>(U->getUser());
2516 assert((!I || isRunOn(*I->getFunction())) &&
2517 "Cannot replace an instruction outside the current SCC!");
2518
2519 // Do not replace uses in returns if the value is a must-tail call we will
2520 // not delete.
2521 if (auto *RI = dyn_cast_or_null<ReturnInst>(I)) {
2522 if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))
2523 if (CI->isMustTailCall() && !ToBeDeletedInsts.count(CI))
2524 return;
2525 // If we rewrite a return and the new value is not an argument, strip the
2526 // `returned` attribute as it is wrong now.
2527 if (!isa<Argument>(NewV))
2528 for (auto &Arg : RI->getFunction()->args())
2529 Arg.removeAttr(Attribute::Returned);
2530 }
2531
2532 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
2533 << " instead of " << *OldV << "\n");
2534 U->set(NewV);
2535
2536 // The new value may reference a function, e.g., if an argument is replaced
2537 // by a function pointer, so the call graph of the user's function changes.
2538 if (I) {
2539 CGModifiedFunctions.insert(I->getFunction());
2540 if (auto *C = dyn_cast<Constant>(NewV))
2541 Configuration.CGUpdater.addReferences(*I->getFunction(), *C);
2542 }
2543 if (Instruction *OldI = dyn_cast<Instruction>(OldV)) {
2544 if (!isa<PHINode>(OldI) && !ToBeDeletedInsts.count(OldI) &&
2546 DeadInsts.push_back(OldI);
2547 }
2548 if (isa<UndefValue>(NewV) && isa<CallBase>(U->getUser())) {
2549 auto *CB = cast<CallBase>(U->getUser());
2550 if (CB->isArgOperand(U)) {
2551 unsigned Idx = CB->getArgOperandNo(U);
2552 // Drop all attributes that make passing undef UB, e.g., dereferenceable
2553 // implies noundef.
2554 AttributeMask UBImplying = AttributeFuncs::getUBImplyingAttributes();
2555 CB->removeParamAttrs(Idx, UBImplying);
2556 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
2557 if (Callee && Callee->arg_size() > Idx)
2558 Callee->removeParamAttrs(Idx, UBImplying);
2559 }
2560 }
2561 if (isa<Constant>(NewV) && isa<CondBrInst>(U->getUser())) {
2562 Instruction *UserI = cast<Instruction>(U->getUser());
2563 if (isa<UndefValue>(NewV)) {
2564 ToBeChangedToUnreachableInsts.insert(UserI);
2565 } else {
2566 TerminatorsToFold.push_back(UserI);
2567 }
2568 }
2569 };
2570
2571 for (auto &It : ToBeChangedUses) {
2572 Use *U = It.first;
2573 Value *NewV = It.second;
2574 ReplaceUse(U, NewV);
2575 }
2576
2578 for (auto &It : ToBeChangedValues) {
2579 Value *OldV = It.first;
2580 auto [NewV, Done] = It.second;
2581 Uses.clear();
2582 for (auto &U : OldV->uses())
2583 if (Done || !U.getUser()->isDroppable())
2584 Uses.push_back(&U);
2585 for (Use *U : Uses) {
2586 if (auto *I = dyn_cast<Instruction>(U->getUser()))
2587 if (!isRunOn(*I->getFunction()))
2588 continue;
2589 ReplaceUse(U, NewV);
2590 }
2591 }
2592
2593 for (const auto &V : InvokeWithDeadSuccessor)
2594 if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
2595 assert(isRunOn(*II->getFunction()) &&
2596 "Cannot replace an invoke outside the current SCC!");
2597 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
2598 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
2599 bool Invoke2CallAllowed =
2601 assert((UnwindBBIsDead || NormalBBIsDead) &&
2602 "Invoke does not have dead successors!");
2603 BasicBlock *BB = II->getParent();
2604 BasicBlock *NormalDestBB = II->getNormalDest();
2605 if (UnwindBBIsDead) {
2606 Instruction *NormalNextIP = &NormalDestBB->front();
2607 if (Invoke2CallAllowed) {
2609 NormalNextIP = BB->getTerminator();
2610 }
2611 if (NormalBBIsDead)
2612 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
2613 } else {
2614 assert(NormalBBIsDead && "Broken invariant!");
2615 if (!NormalDestBB->getUniquePredecessor())
2616 NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2617 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
2618 }
2619 }
2620 for (Instruction *I : TerminatorsToFold) {
2621 assert(isRunOn(*I->getFunction()) &&
2622 "Cannot replace a terminator outside the current SCC!");
2623 CGModifiedFunctions.insert(I->getFunction());
2624 ConstantFoldTerminator(I->getParent());
2625 }
2626 for (const auto &V : ToBeChangedToUnreachableInsts)
2627 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
2628 LLVM_DEBUG(dbgs() << "[Attributor] Change to unreachable: " << *I
2629 << "\n");
2630 assert(isRunOn(*I->getFunction()) &&
2631 "Cannot replace an instruction outside the current SCC!");
2632 CGModifiedFunctions.insert(I->getFunction());
2634 }
2635
2636 for (const auto &V : ToBeDeletedInsts) {
2637 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
2639 isRunOn(*I->getFunction())) &&
2640 "Cannot delete an instruction outside the current SCC!");
2641 I->dropDroppableUses();
2642 CGModifiedFunctions.insert(I->getFunction());
2643 if (!I->getType()->isVoidTy())
2644 I->replaceAllUsesWith(UndefValue::get(I->getType()));
2646 DeadInsts.push_back(I);
2647 else
2648 I->eraseFromParent();
2649 }
2650 }
2651
2652 llvm::erase_if(DeadInsts, [&](WeakTrackingVH I) { return !I; });
2653
2654 LLVM_DEBUG({
2655 dbgs() << "[Attributor] DeadInsts size: " << DeadInsts.size() << "\n";
2656 for (auto &I : DeadInsts)
2657 if (I)
2658 dbgs() << " - " << *I << "\n";
2659 });
2660
2662
2663 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
2664 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
2665 ToBeDeletedBBs.reserve(NumDeadBlocks);
2666 for (BasicBlock *BB : ToBeDeletedBlocks) {
2667 assert(isRunOn(*BB->getParent()) &&
2668 "Cannot delete a block outside the current SCC!");
2669 CGModifiedFunctions.insert(BB->getParent());
2670 // Do not delete BBs added during manifests of AAs.
2671 if (ManifestAddedBlocks.contains(BB))
2672 continue;
2673 ToBeDeletedBBs.push_back(BB);
2674 }
2675 // Actually we do not delete the blocks but squash them into a single
2676 // unreachable but untangling branches that jump here is something we need
2677 // to do in a more generic way.
2678 detachDeadBlocks(ToBeDeletedBBs, nullptr);
2679 }
2680
2681 identifyDeadInternalFunctions();
2682
2683 // Rewrite the functions as requested during manifest.
2684 ChangeStatus ManifestChange = rewriteFunctionSignatures(CGModifiedFunctions);
2685
2686 for (Function *Fn : CGModifiedFunctions)
2687 if (!ToBeDeletedFunctions.count(Fn) && Functions.count(Fn))
2688 Configuration.CGUpdater.reanalyzeFunction(*Fn);
2689
2690 for (Function *Fn : ToBeDeletedFunctions) {
2691 if (!Functions.count(Fn))
2692 continue;
2693 Configuration.CGUpdater.removeFunction(*Fn);
2694 }
2695
2696 if (!ToBeChangedUses.empty())
2697 ManifestChange = ChangeStatus::CHANGED;
2698
2699 if (!ToBeChangedToUnreachableInsts.empty())
2700 ManifestChange = ChangeStatus::CHANGED;
2701
2702 if (!ToBeDeletedFunctions.empty())
2703 ManifestChange = ChangeStatus::CHANGED;
2704
2705 if (!ToBeDeletedBlocks.empty())
2706 ManifestChange = ChangeStatus::CHANGED;
2707
2708 if (!ToBeDeletedInsts.empty())
2709 ManifestChange = ChangeStatus::CHANGED;
2710
2711 if (!InvokeWithDeadSuccessor.empty())
2712 ManifestChange = ChangeStatus::CHANGED;
2713
2714 if (!DeadInsts.empty())
2715 ManifestChange = ChangeStatus::CHANGED;
2716
2717 NumFnDeleted += ToBeDeletedFunctions.size();
2718
2719 LLVM_DEBUG(dbgs() << "[Attributor] Deleted " << ToBeDeletedFunctions.size()
2720 << " functions after manifest.\n");
2721
2722#ifdef EXPENSIVE_CHECKS
2723 for (Function *F : Functions) {
2724 if (ToBeDeletedFunctions.count(F))
2725 continue;
2726 assert(!verifyFunction(*F, &errs()) && "Module verification failed!");
2727 }
2728#endif
2729
2730 return ManifestChange;
2731}
2732
2734 TimeTraceScope TimeScope("Attributor::run");
2735 AttributorCallGraph ACallGraph(*this);
2736
2737 if (PrintCallGraph)
2738 ACallGraph.populateAll();
2739
2740 Phase = AttributorPhase::UPDATE;
2741 runTillFixpoint();
2742
2743 // dump graphs on demand
2744 if (DumpDepGraph)
2745 DG.dumpGraph();
2746
2747 if (ViewDepGraph)
2748 DG.viewGraph();
2749
2751 DG.print();
2752
2753 Phase = AttributorPhase::MANIFEST;
2754 ChangeStatus ManifestChange = manifestAttributes();
2755
2756 Phase = AttributorPhase::CLEANUP;
2757 ChangeStatus CleanupChange = cleanupIR();
2758
2759 if (PrintCallGraph)
2760 ACallGraph.print();
2761
2762 return ManifestChange | CleanupChange;
2763}
2764
2765ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {
2766 std::optional<TimeTraceScope> TimeScope;
2767 if (TimeTraceEnabled) {
2768 TimeScope.emplace("updateAA", [&]() {
2769 return AA.getName().str() +
2770 std::to_string(AA.getIRPosition().getPositionKind());
2771 });
2772 }
2773
2774 assert(Phase == AttributorPhase::UPDATE &&
2775 "We can update AA only in the update stage!");
2776
2777 // Use a new dependence vector for this update.
2778 DependenceVector DV;
2779 DependenceStack.push_back(&DV);
2780
2781 auto &AAState = AA.getState();
2783 bool UsedAssumedInformation = false;
2784 if (!isAssumedDead(AA, nullptr, UsedAssumedInformation,
2785 /* CheckBBLivenessOnly */ true))
2786 CS = AA.update(*this);
2787
2788 if (!AA.isQueryAA() && DV.empty() && !AA.getState().isAtFixpoint()) {
2789 // If the AA did not rely on outside information but changed, we run it
2790 // again to see if it found a fixpoint. Most AAs do but we don't require
2791 // them to. Hence, it might take the AA multiple iterations to get to a
2792 // fixpoint even if it does not rely on outside information, which is fine.
2794 if (CS == ChangeStatus::CHANGED)
2795 RerunCS = AA.update(*this);
2796
2797 // If the attribute did not change during the run or rerun, and it still did
2798 // not query any non-fix information, the state will not change and we can
2799 // indicate that right at this point.
2800 if (RerunCS == ChangeStatus::UNCHANGED && !AA.isQueryAA() && DV.empty())
2801 AAState.indicateOptimisticFixpoint();
2802 }
2803
2804 if (!AAState.isAtFixpoint())
2805 rememberDependences();
2806
2807 // Verify the stack was used properly, that is we pop the dependence vector we
2808 // put there earlier.
2809 DependenceVector *PoppedDV = DependenceStack.pop_back_val();
2810 (void)PoppedDV;
2811 assert(PoppedDV == &DV && "Inconsistent usage of the dependence stack!");
2812
2813 return CS;
2814}
2815
2817 assert(!F.isDeclaration() && "Cannot create a wrapper around a declaration!");
2818
2819 Module &M = *F.getParent();
2820 LLVMContext &Ctx = M.getContext();
2821 FunctionType *FnTy = F.getFunctionType();
2822
2823 Function *Wrapper =
2824 Function::Create(FnTy, F.getLinkage(), F.getAddressSpace(), F.getName());
2825 F.setName(""); // set the inside function anonymous
2826 M.getFunctionList().insert(F.getIterator(), Wrapper);
2827
2828 F.setLinkage(GlobalValue::InternalLinkage);
2829
2830 F.replaceAllUsesWith(Wrapper);
2831 assert(F.use_empty() && "Uses remained after wrapper was created!");
2832
2833 // Move the COMDAT section to the wrapper.
2834 // TODO: Check if we need to keep it for F as well.
2835 Wrapper->setComdat(F.getComdat());
2836 F.setComdat(nullptr);
2837
2838 // Copy all metadata and attributes but keep them on F as well.
2840 F.getAllMetadata(MDs);
2841 for (auto MDIt : MDs)
2842 Wrapper->addMetadata(MDIt.first, *MDIt.second);
2843 Wrapper->setAttributes(F.getAttributes());
2844
2845 // Create the call in the wrapper.
2846 BasicBlock *EntryBB = BasicBlock::Create(Ctx, "entry", Wrapper);
2847
2849 Argument *FArgIt = F.arg_begin();
2850 for (Argument &Arg : Wrapper->args()) {
2851 Args.push_back(&Arg);
2852 Arg.setName((FArgIt++)->getName());
2853 }
2854
2855 CallInst *CI = CallInst::Create(&F, Args, "", EntryBB);
2856 CI->setTailCall(true);
2857 CI->addFnAttr(Attribute::NoInline);
2858 ReturnInst::Create(Ctx, CI->getType()->isVoidTy() ? nullptr : CI, EntryBB);
2859
2860 NumFnShallowWrappersCreated++;
2861}
2862
2864 if (F.isDeclaration() || F.hasLocalLinkage() ||
2866 return false;
2867 return true;
2868}
2869
2871 if (!AllowDeepWrapper && !Force)
2872 return nullptr;
2873 if (!isInternalizable(F))
2874 return nullptr;
2875
2876 SmallPtrSet<Function *, 2> FnSet = {&F};
2877 DenseMap<Function *, Function *> InternalizedFns;
2878 internalizeFunctions(FnSet, InternalizedFns);
2879
2880 return InternalizedFns[&F];
2881}
2882
2885 for (Function *F : FnSet)
2887 return false;
2888
2889 FnMap.clear();
2890 // Generate the internalized version of each function.
2891 for (Function *F : FnSet) {
2892 Module &M = *F->getParent();
2893 FunctionType *FnTy = F->getFunctionType();
2894
2895 // Create a copy of the current function
2896 Function *Copied =
2897 Function::Create(FnTy, F->getLinkage(), F->getAddressSpace(),
2898 F->getName() + ".internalized");
2899 ValueToValueMapTy VMap;
2900 auto *NewFArgIt = Copied->arg_begin();
2901 for (auto &Arg : F->args()) {
2902 auto ArgName = Arg.getName();
2903 NewFArgIt->setName(ArgName);
2904 VMap[&Arg] = &(*NewFArgIt++);
2905 }
2907
2908 // Copy the body of the original function to the new one
2909 CloneFunctionInto(Copied, F, VMap,
2911
2912 // Set the linakage and visibility late as CloneFunctionInto has some
2913 // implicit requirements.
2916
2917 // Copy metadata
2919 F->getAllMetadata(MDs);
2920 for (auto MDIt : MDs)
2921 if (!Copied->hasMetadata())
2922 Copied->addMetadata(MDIt.first, *MDIt.second);
2923
2924 M.getFunctionList().insert(F->getIterator(), Copied);
2925 Copied->setDSOLocal(true);
2926 FnMap[F] = Copied;
2927 }
2928
2929 // Replace all uses of the old function with the new internalized function
2930 // unless the caller is a function that was just internalized.
2931 for (Function *F : FnSet) {
2932 auto &InternalizedFn = FnMap[F];
2933 auto IsNotInternalized = [&](Use &U) -> bool {
2934 if (auto *CB = dyn_cast<CallBase>(U.getUser()))
2935 return !FnMap.lookup(CB->getCaller());
2936 return false;
2937 };
2938 F->replaceUsesWithIf(InternalizedFn, IsNotInternalized);
2939 }
2940
2941 return true;
2942}
2943
2945 Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
2946
2947 if (!Configuration.RewriteSignatures)
2948 return false;
2949
2950 Function *Fn = Arg.getParent();
2951 auto CallSiteCanBeChanged = [Fn](AbstractCallSite ACS) {
2952 // Forbid the call site to cast the function return type. If we need to
2953 // rewrite these functions we need to re-create a cast for the new call site
2954 // (if the old had uses).
2955 if (!ACS.getCalledFunction() ||
2956 ACS.getInstruction()->getType() !=
2958 return false;
2959 if (cast<CallBase>(ACS.getInstruction())->getCalledOperand()->getType() !=
2960 Fn->getType())
2961 return false;
2962 if (ACS.getNumArgOperands() != Fn->arg_size())
2963 return false;
2964 // Forbid must-tail calls for now.
2965 return !ACS.isCallbackCall() && !ACS.getInstruction()->isMustTailCall();
2966 };
2967
2968 // Avoid var-arg functions for now.
2969 if (Fn->isVarArg()) {
2970 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
2971 return false;
2972 }
2973
2974 // Avoid functions with complicated argument passing semantics.
2975 AttributeList FnAttributeList = Fn->getAttributes();
2976 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
2977 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
2978 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca) ||
2979 FnAttributeList.hasAttrSomewhere(Attribute::Preallocated)) {
2980 LLVM_DEBUG(
2981 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
2982 return false;
2983 }
2984
2985 // Avoid callbacks for now.
2986 bool UsedAssumedInformation = false;
2987 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,
2988 UsedAssumedInformation,
2989 /* CheckPotentiallyDead */ true)) {
2990 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
2991 return false;
2992 }
2993
2994 auto InstPred = [](Instruction &I) {
2995 if (auto *CI = dyn_cast<CallInst>(&I))
2996 return !CI->isMustTailCall();
2997 return true;
2998 };
2999
3000 // Forbid must-tail calls for now.
3001 // TODO:
3002 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
3003 if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
3004 nullptr, {Instruction::Call},
3005 UsedAssumedInformation)) {
3006 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
3007 return false;
3008 }
3009
3010 return true;
3011}
3012
3014 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
3017 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
3018 << Arg.getParent()->getName() << " with "
3019 << ReplacementTypes.size() << " replacements\n");
3020 assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&
3021 "Cannot register an invalid rewrite");
3022
3023 Function *Fn = Arg.getParent();
3025 ArgumentReplacementMap[Fn];
3026 if (ARIs.empty())
3027 ARIs.resize(Fn->arg_size());
3028
3029 // If we have a replacement already with less than or equal new arguments,
3030 // ignore this request.
3031 std::unique_ptr<ArgumentReplacementInfo> &ARI = ARIs[Arg.getArgNo()];
3032 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
3033 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
3034 return false;
3035 }
3036
3037 // If we have a replacement already but we like the new one better, delete
3038 // the old.
3039 ARI.reset();
3040
3041 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
3042 << Arg.getParent()->getName() << " with "
3043 << ReplacementTypes.size() << " replacements\n");
3044
3045 // Remember the replacement.
3046 ARI.reset(new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
3047 std::move(CalleeRepairCB),
3048 std::move(ACSRepairCB)));
3049
3050 return true;
3051}
3052
3053bool Attributor::shouldSeedAttribute(AbstractAttribute &AA) {
3054 bool Result = true;
3055#ifndef NDEBUG
3056 if (SeedAllowList.size() != 0)
3057 Result = llvm::is_contained(SeedAllowList, AA.getName());
3058 Function *Fn = AA.getAnchorScope();
3059 if (FunctionSeedAllowList.size() != 0 && Fn)
3061#endif
3062 return Result;
3063}
3064
3065ChangeStatus Attributor::rewriteFunctionSignatures(
3066 SmallSetVector<Function *, 8> &ModifiedFns) {
3068
3069 for (auto &It : ArgumentReplacementMap) {
3070 Function *OldFn = It.first;
3071
3072 // Deleted functions do not require rewrites.
3073 if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))
3074 continue;
3075
3077 It.second;
3078 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
3079
3080 SmallVector<Type *, 16> NewArgumentTypes;
3081 SmallVector<AttributeSet, 16> NewArgumentAttributes;
3082
3083 // Collect replacement argument types and copy over existing attributes.
3084 AttributeList OldFnAttributeList = OldFn->getAttributes();
3085 for (Argument &Arg : OldFn->args()) {
3086 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3087 ARIs[Arg.getArgNo()]) {
3088 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
3089 ARI->ReplacementTypes.end());
3090 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
3091 AttributeSet());
3092 } else {
3093 NewArgumentTypes.push_back(Arg.getType());
3094 NewArgumentAttributes.push_back(
3095 OldFnAttributeList.getParamAttrs(Arg.getArgNo()));
3096 }
3097 }
3098
3099 uint64_t LargestVectorWidth = 0;
3100 for (auto *I : NewArgumentTypes)
3101 if (auto *VT = dyn_cast<llvm::VectorType>(I))
3102 LargestVectorWidth =
3103 std::max(LargestVectorWidth,
3104 VT->getPrimitiveSizeInBits().getKnownMinValue());
3105
3106 FunctionType *OldFnTy = OldFn->getFunctionType();
3107 Type *RetTy = OldFnTy->getReturnType();
3108
3109 // Construct the new function type using the new arguments types.
3110 FunctionType *NewFnTy =
3111 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
3112
3113 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
3114 << "' from " << *OldFn->getFunctionType() << " to "
3115 << *NewFnTy << "\n");
3116
3117 // Create the new function body and insert it into the module.
3118 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
3119 OldFn->getAddressSpace(), "");
3120 Functions.insert(NewFn);
3121 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
3122 NewFn->takeName(OldFn);
3123 NewFn->copyAttributesFrom(OldFn);
3124
3125 // Patch the pointer to LLVM function in debug info descriptor.
3126 NewFn->setSubprogram(OldFn->getSubprogram());
3127 OldFn->setSubprogram(nullptr);
3128
3129 // Recompute the parameter attributes list based on the new arguments for
3130 // the function.
3131 LLVMContext &Ctx = OldFn->getContext();
3132 NewFn->setAttributes(AttributeList::get(
3133 Ctx, OldFnAttributeList.getFnAttrs(), OldFnAttributeList.getRetAttrs(),
3134 NewArgumentAttributes));
3135 AttributeFuncs::updateMinLegalVectorWidthAttr(*NewFn, LargestVectorWidth);
3136
3137 // Remove argmem from the memory effects if we have no more pointer
3138 // arguments, or they are readnone.
3139 MemoryEffects ME = NewFn->getMemoryEffects();
3140 int ArgNo = -1;
3141 if (ME.doesAccessArgPointees() && all_of(NewArgumentTypes, [&](Type *T) {
3142 ++ArgNo;
3143 return !T->isPtrOrPtrVectorTy() ||
3144 NewFn->hasParamAttribute(ArgNo, Attribute::ReadNone);
3145 })) {
3147 }
3148
3149 // Since we have now created the new function, splice the body of the old
3150 // function right into the new function, leaving the old rotting hulk of the
3151 // function empty.
3152 NewFn->splice(NewFn->begin(), OldFn);
3153
3154 // Set of all "call-like" instructions that invoke the old function mapped
3155 // to their new replacements.
3157
3158 // Callback to create a new "call-like" instruction for a given one.
3159 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
3160 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
3161 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
3162
3163 // Collect the new argument operands for the replacement call site.
3164 SmallVector<Value *, 16> NewArgOperands;
3165 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
3166 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
3167 unsigned NewFirstArgNum = NewArgOperands.size();
3168 (void)NewFirstArgNum; // only used inside assert.
3169 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3170 ARIs[OldArgNum]) {
3171 if (ARI->ACSRepairCB)
3172 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
3173 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
3174 NewArgOperands.size() &&
3175 "ACS repair callback did not provide as many operand as new "
3176 "types were registered!");
3177 // TODO: Exose the attribute set to the ACS repair callback
3178 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
3179 AttributeSet());
3180 } else {
3181 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
3182 NewArgOperandAttributes.push_back(
3183 OldCallAttributeList.getParamAttrs(OldArgNum));
3184 }
3185 }
3186
3187 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
3188 "Mismatch # argument operands vs. # argument operand attributes!");
3189 assert(NewArgOperands.size() == NewFn->arg_size() &&
3190 "Mismatch # argument operands vs. # function arguments!");
3191
3192 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
3193 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
3194
3195 // Create a new call or invoke instruction to replace the old one.
3196 CallBase *NewCB;
3197 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
3198 NewCB = InvokeInst::Create(NewFn, II->getNormalDest(),
3199 II->getUnwindDest(), NewArgOperands,
3200 OperandBundleDefs, "", OldCB->getIterator());
3201 } else {
3202 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
3203 "", OldCB->getIterator());
3204 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
3205 NewCB = NewCI;
3206 }
3207
3208 // Copy over various properties and the new attributes.
3209 NewCB->copyProfileAndDebugMetadata(*OldCB);
3210 NewCB->setCallingConv(OldCB->getCallingConv());
3211 NewCB->takeName(OldCB);
3212 NewCB->setAttributes(AttributeList::get(
3213 Ctx, OldCallAttributeList.getFnAttrs(),
3214 OldCallAttributeList.getRetAttrs(), NewArgOperandAttributes));
3215
3216 AttributeFuncs::updateMinLegalVectorWidthAttr(*NewCB->getCaller(),
3217 LargestVectorWidth);
3218
3219 CallSitePairs.push_back({OldCB, NewCB});
3220 return true;
3221 };
3222
3223 // Use the CallSiteReplacementCreator to create replacement call sites.
3224 bool UsedAssumedInformation = false;
3225 bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,
3226 true, nullptr, UsedAssumedInformation,
3227 /* CheckPotentiallyDead */ true);
3228 (void)Success;
3229 assert(Success && "Assumed call site replacement to succeed!");
3230
3231 // Rewire the arguments.
3232 Argument *OldFnArgIt = OldFn->arg_begin();
3233 Argument *NewFnArgIt = NewFn->arg_begin();
3234 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
3235 ++OldArgNum, ++OldFnArgIt) {
3236 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3237 ARIs[OldArgNum]) {
3238 if (ARI->CalleeRepairCB)
3239 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
3240 if (ARI->ReplacementTypes.empty())
3241 OldFnArgIt->replaceAllUsesWith(
3242 PoisonValue::get(OldFnArgIt->getType()));
3243 NewFnArgIt += ARI->ReplacementTypes.size();
3244 } else {
3245 NewFnArgIt->takeName(&*OldFnArgIt);
3246 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
3247 ++NewFnArgIt;
3248 }
3249 }
3250
3251 // Eliminate the instructions *after* we visited all of them.
3252 for (auto &CallSitePair : CallSitePairs) {
3253 CallBase &OldCB = *CallSitePair.first;
3254 CallBase &NewCB = *CallSitePair.second;
3255 assert(OldCB.getType() == NewCB.getType() &&
3256 "Cannot handle call sites with different types!");
3257 ModifiedFns.insert(OldCB.getFunction());
3258 OldCB.replaceAllUsesWith(&NewCB);
3259 OldCB.eraseFromParent();
3260 }
3261
3262 // Replace the function in the call graph (if any).
3263 Configuration.CGUpdater.replaceFunctionWith(*OldFn, *NewFn);
3264
3265 // If the old function was modified and needed to be reanalyzed, the new one
3266 // does now.
3267 if (ModifiedFns.remove(OldFn))
3268 ModifiedFns.insert(NewFn);
3269
3271 }
3272
3273 return Changed;
3274}
3275
3276void InformationCache::initializeInformationCache(const Function &CF,
3277 FunctionInfo &FI) {
3278 // As we do not modify the function here we can remove the const
3279 // withouth breaking implicit assumptions. At the end of the day, we could
3280 // initialize the cache eagerly which would look the same to the users.
3281 Function &F = const_cast<Function &>(CF);
3282
3283 FI.IsKernel = F.hasFnAttribute("kernel");
3284
3285 // Walk all instructions to find interesting instructions that might be
3286 // queried by abstract attributes during their initialization or update.
3287 // This has to happen before we create attributes.
3288
3289 DenseMap<const Value *, std::optional<short>> AssumeUsesMap;
3290
3291 // Add \p V to the assume uses map which track the number of uses outside of
3292 // "visited" assumes. If no outside uses are left the value is added to the
3293 // assume only use vector.
3294 auto AddToAssumeUsesMap = [&](const Value &V) -> void {
3295 SmallVector<const Instruction *> Worklist;
3296 if (auto *I = dyn_cast<Instruction>(&V))
3297 Worklist.push_back(I);
3298 while (!Worklist.empty()) {
3299 const Instruction *I = Worklist.pop_back_val();
3300 std::optional<short> &NumUses = AssumeUsesMap[I];
3301 if (!NumUses)
3302 NumUses = I->getNumUses();
3303 NumUses = *NumUses - /* this assume */ 1;
3304 if (*NumUses != 0)
3305 continue;
3306 AssumeOnlyValues.insert(I);
3307 for (const Value *Op : I->operands())
3308 if (auto *OpI = dyn_cast<Instruction>(Op))
3309 Worklist.push_back(OpI);
3310 }
3311 };
3312
3313 for (Instruction &I : instructions(&F)) {
3314 bool IsInterestingOpcode = false;
3315
3316 // To allow easy access to all instructions in a function with a given
3317 // opcode we store them in the InfoCache. As not all opcodes are interesting
3318 // to concrete attributes we only cache the ones that are as identified in
3319 // the following switch.
3320 // Note: There are no concrete attributes now so this is initially empty.
3321 switch (I.getOpcode()) {
3322 default:
3323 assert(!isa<CallBase>(&I) &&
3324 "New call base instruction type needs to be known in the "
3325 "Attributor.");
3326 break;
3327 case Instruction::Call:
3328 // Calls are interesting on their own, additionally:
3329 // For `llvm.assume` calls we also fill the KnowledgeMap as we find them.
3330 // For `must-tail` calls we remember the caller and callee.
3331 if (auto *Assume = dyn_cast<AssumeInst>(&I)) {
3332 AssumeOnlyValues.insert(Assume);
3333 fillMapFromAssume(*Assume, KnowledgeMap);
3334 AddToAssumeUsesMap(*Assume->getArgOperand(0));
3335 } else if (cast<CallInst>(I).isMustTailCall()) {
3336 FI.ContainsMustTailCall = true;
3337 if (auto *Callee = dyn_cast_if_present<Function>(
3338 cast<CallInst>(I).getCalledOperand()))
3339 getFunctionInfo(*Callee).CalledViaMustTail = true;
3340 }
3341 [[fallthrough]];
3342 case Instruction::CallBr:
3343 case Instruction::Invoke:
3344 case Instruction::CleanupRet:
3345 case Instruction::CatchSwitch:
3346 case Instruction::AtomicRMW:
3347 case Instruction::AtomicCmpXchg:
3348 case Instruction::UncondBr:
3349 case Instruction::CondBr:
3350 case Instruction::Resume:
3351 case Instruction::Ret:
3352 case Instruction::Load:
3353 // The alignment of a pointer is interesting for loads.
3354 case Instruction::Store:
3355 // The alignment of a pointer is interesting for stores.
3356 case Instruction::Alloca:
3357 case Instruction::AddrSpaceCast:
3358 IsInterestingOpcode = true;
3359 }
3360 if (IsInterestingOpcode) {
3361 auto *&Insts = FI.OpcodeInstMap[I.getOpcode()];
3362 if (!Insts)
3363 Insts = new (Allocator) InstructionVectorTy();
3364 Insts->push_back(&I);
3365 }
3366 if (I.mayReadOrWriteMemory())
3367 FI.RWInsts.push_back(&I);
3368 }
3369
3370 if (F.hasFnAttribute(Attribute::AlwaysInline) &&
3371 isInlineViable(F).isSuccess())
3372 InlineableFunctions.insert(&F);
3373}
3374
3375InformationCache::FunctionInfo::~FunctionInfo() {
3376 // The instruction vectors are allocated using a BumpPtrAllocator, we need to
3377 // manually destroy them.
3378 for (InstructionVectorTy *Insts : OpcodeInstMap) {
3379 if (Insts)
3380 Insts->~InstructionVectorTy();
3381 }
3382}
3383
3386 assert(A.isClosedWorldModule() && "Cannot see all indirect callees!");
3387 return IndirectlyCallableFunctions;
3388}
3389
3390std::optional<unsigned> InformationCache::getFlatAddressSpace() const {
3391 if (IsTargetGPU())
3392 return 0;
3393 return std::nullopt;
3394}
3395
3397 const AbstractAttribute &ToAA,
3398 DepClassTy DepClass) {
3399 if (DepClass == DepClassTy::NONE)
3400 return;
3401 // If we are outside of an update, thus before the actual fixpoint iteration
3402 // started (= when we create AAs), we do not track dependences because we will
3403 // put all AAs into the initial worklist anyway.
3404 if (DependenceStack.empty())
3405 return;
3406 if (FromAA.getState().isAtFixpoint())
3407 return;
3408 DependenceStack.back()->push_back({&FromAA, &ToAA, DepClass});
3409}
3410
3411void Attributor::rememberDependences() {
3412 assert(!DependenceStack.empty() && "No dependences to remember!");
3413
3414 for (DepInfo &DI : *DependenceStack.back()) {
3415 assert((DI.DepClass == DepClassTy::REQUIRED ||
3416 DI.DepClass == DepClassTy::OPTIONAL) &&
3417 "Expected required or optional dependence (1 bit)!");
3418 auto &DepAAs = const_cast<AbstractAttribute &>(*DI.FromAA).Deps;
3419 DepAAs.insert(AbstractAttribute::DepTy(
3420 const_cast<AbstractAttribute *>(DI.ToAA), unsigned(DI.DepClass)));
3421 }
3422}
3423
3424template <Attribute::AttrKind AK, typename AAType>
3425void Attributor::checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs,
3426 bool SkipHasAttrCheck) {
3427 bool IsKnown;
3428 if (SkipHasAttrCheck || !Attrs.hasAttribute(AK))
3429 if (!Configuration.Allowed || Configuration.Allowed->count(&AAType::ID))
3430 if (!AA::hasAssumedIRAttr<AK>(*this, nullptr, IRP, DepClassTy::NONE,
3431 IsKnown))
3432 getOrCreateAAFor<AAType>(IRP);
3433}
3434
3436 assert(!F.isDeclaration());
3437
3438 if (!VisitedFunctions.insert(&F).second)
3439 return;
3440
3441 // In non-module runs we need to look at the call sites of a function to
3442 // determine if it is part of a must-tail call edge. This will influence what
3443 // attributes we can derive.
3444 InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(F);
3445 if (!isModulePass() && !FI.CalledViaMustTail) {
3446 for (const Use &U : F.uses())
3447 if (const auto *CB = dyn_cast<CallBase>(U.getUser()))
3448 if (CB->isCallee(&U) && CB->isMustTailCall())
3449 FI.CalledViaMustTail = true;
3450 }
3451
3453 bool IsIPOAmendable = isFunctionIPOAmendable(F);
3454 auto Attrs = F.getAttributes();
3455 auto FnAttrs = Attrs.getFnAttrs();
3456
3457 // Check for dead BasicBlocks in every function.
3458 // We need dead instruction detection because we do not want to deal with
3459 // broken IR in which SSA rules do not apply.
3461
3462 // Every function might contain instructions that cause "undefined
3463 // behavior".
3465
3466 // Every function might be applicable for Heap-To-Stack conversion.
3469
3470 // Every function might be "must-progress".
3471 checkAndQueryIRAttr<Attribute::MustProgress, AAMustProgress>(FPos, FnAttrs);
3472
3473 // Every function might be "no-free".
3474 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(FPos, FnAttrs);
3475
3476 // Every function might be "will-return".
3477 checkAndQueryIRAttr<Attribute::WillReturn, AAWillReturn>(FPos, FnAttrs);
3478
3479 // Every function might be marked "nosync"
3480 checkAndQueryIRAttr<Attribute::NoSync, AANoSync>(FPos, FnAttrs);
3481
3482 // Everything that is visible from the outside (=function, argument, return
3483 // positions), cannot be changed if the function is not IPO amendable. We can
3484 // however analyse the code inside.
3485 if (IsIPOAmendable) {
3486
3487 // Every function can be nounwind.
3488 checkAndQueryIRAttr<Attribute::NoUnwind, AANoUnwind>(FPos, FnAttrs);
3489
3490 // Every function might be "no-return".
3491 checkAndQueryIRAttr<Attribute::NoReturn, AANoReturn>(FPos, FnAttrs);
3492
3493 // Every function might be "no-recurse".
3494 checkAndQueryIRAttr<Attribute::NoRecurse, AANoRecurse>(FPos, FnAttrs);
3495
3496 // Every function can be "non-convergent".
3497 if (Attrs.hasFnAttr(Attribute::Convergent))
3499
3500 // Every function might be "readnone/readonly/writeonly/...".
3502
3503 // Every function can be "readnone/argmemonly/inaccessiblememonly/...".
3505
3506 // Every function can track active assumptions.
3508
3509 // If we're not using a dynamic mode for float, there's nothing worthwhile
3510 // to infer. This misses the edge case denormal-fp-math="dynamic" and
3511 // denormal-fp-math-f32=something, but that likely has no real world use.
3512 DenormalMode Mode = F.getDenormalMode(APFloat::IEEEsingle());
3513 if (Mode.Input == DenormalMode::Dynamic ||
3514 Mode.Output == DenormalMode::Dynamic)
3516
3517 // Return attributes are only appropriate if the return type is non void.
3518 Type *ReturnType = F.getReturnType();
3519 if (!ReturnType->isVoidTy()) {
3521 AttributeSet RetAttrs = Attrs.getRetAttrs();
3522
3523 // Every returned value might be dead.
3525
3526 // Every function might be simplified.
3527 bool UsedAssumedInformation = false;
3528 getAssumedSimplified(RetPos, nullptr, UsedAssumedInformation,
3530
3531 // Every returned value might be marked noundef.
3532 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(RetPos, RetAttrs);
3533
3534 if (ReturnType->isPointerTy()) {
3535
3536 // Every function with pointer return type might be marked align.
3538
3539 // Every function with pointer return type might be marked nonnull.
3540 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(RetPos, RetAttrs);
3541
3542 // Every function with pointer return type might be marked noalias.
3543 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(RetPos, RetAttrs);
3544
3545 // Every function with pointer return type might be marked
3546 // dereferenceable.
3548 } else if (AttributeFuncs::isNoFPClassCompatibleType(ReturnType)) {
3550 }
3551 }
3552 }
3553
3554 for (Argument &Arg : F.args()) {
3555 IRPosition ArgPos = IRPosition::argument(Arg);
3556 auto ArgNo = Arg.getArgNo();
3557 AttributeSet ArgAttrs = Attrs.getParamAttrs(ArgNo);
3558
3559 if (!IsIPOAmendable) {
3560 if (Arg.getType()->isPointerTy())
3561 // Every argument with pointer type might be marked nofree.
3562 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);
3563 continue;
3564 }
3565
3566 // Every argument might be simplified. We have to go through the
3567 // Attributor interface though as outside AAs can register custom
3568 // simplification callbacks.
3569 bool UsedAssumedInformation = false;
3570 getAssumedSimplified(ArgPos, /* AA */ nullptr, UsedAssumedInformation,
3572
3573 // Every argument might be dead.
3575
3576 // Every argument might be marked noundef.
3577 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(ArgPos, ArgAttrs);
3578
3579 if (Arg.getType()->isPointerTy()) {
3580 // Every argument with pointer type might be marked nonnull.
3581 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(ArgPos, ArgAttrs);
3582
3583 // Every argument with pointer type might be marked noalias.
3584 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(ArgPos, ArgAttrs);
3585
3586 // Every argument with pointer type might be marked dereferenceable.
3588
3589 // Every argument with pointer type might be marked align.
3591
3592 // Every argument with pointer type might be marked nocapture.
3593 checkAndQueryIRAttr<Attribute::Captures, AANoCapture>(
3594 ArgPos, ArgAttrs, /*SkipHasAttrCheck=*/true);
3595
3596 // Every argument with pointer type might be marked
3597 // "readnone/readonly/writeonly/..."
3599
3600 // Every argument with pointer type might be marked nofree.
3601 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);
3602
3603 // Every argument with pointer type might be privatizable (or
3604 // promotable)
3606 } else if (AttributeFuncs::isNoFPClassCompatibleType(Arg.getType())) {
3608 }
3609 }
3610
3611 auto CallSitePred = [&](Instruction &I) -> bool {
3612 auto &CB = cast<CallBase>(I);
3613 IRPosition CBInstPos = IRPosition::inst(CB);
3615
3616 // Call sites might be dead if they do not have side effects and no live
3617 // users. The return value might be dead if there are no live users.
3618 getOrCreateAAFor<AAIsDead>(CBInstPos);
3619
3620 Function *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
3621 // TODO: Even if the callee is not known now we might be able to simplify
3622 // the call/callee.
3623 if (!Callee) {
3625 return true;
3626 }
3627
3628 // Every call site can track active assumptions.
3630
3631 // Skip declarations except if annotations on their call sites were
3632 // explicitly requested.
3633 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
3634 !Callee->hasMetadata(LLVMContext::MD_callback))
3635 return true;
3636
3637 if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
3639 bool UsedAssumedInformation = false;
3640 getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation,
3642
3643 if (AttributeFuncs::isNoFPClassCompatibleType(Callee->getReturnType()))
3645 }
3646
3647 const AttributeList &CBAttrs = CBFnPos.getAttrList();
3648 for (int I = 0, E = CB.arg_size(); I < E; ++I) {
3649
3651 AttributeSet CBArgAttrs = CBAttrs.getParamAttrs(I);
3652
3653 // Every call site argument might be dead.
3655
3656 // Call site argument might be simplified. We have to go through the
3657 // Attributor interface though as outside AAs can register custom
3658 // simplification callbacks.
3659 bool UsedAssumedInformation = false;
3660 getAssumedSimplified(CBArgPos, /* AA */ nullptr, UsedAssumedInformation,
3662
3663 // Every call site argument might be marked "noundef".
3664 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(CBArgPos, CBArgAttrs);
3665
3666 Type *ArgTy = CB.getArgOperand(I)->getType();
3667
3668 if (!ArgTy->isPointerTy()) {
3669 if (AttributeFuncs::isNoFPClassCompatibleType(ArgTy))
3671
3672 continue;
3673 }
3674
3675 // Call site argument attribute "non-null".
3676 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(CBArgPos, CBArgAttrs);
3677
3678 // Call site argument attribute "captures(none)".
3679 checkAndQueryIRAttr<Attribute::Captures, AANoCapture>(
3680 CBArgPos, CBArgAttrs, /*SkipHasAttrCheck=*/true);
3681
3682 // Call site argument attribute "no-alias".
3683 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(CBArgPos, CBArgAttrs);
3684
3685 // Call site argument attribute "dereferenceable".
3687
3688 // Call site argument attribute "align".
3689 getOrCreateAAFor<AAAlign>(CBArgPos);
3690
3691 // Call site argument attribute
3692 // "readnone/readonly/writeonly/..."
3693 if (!CBAttrs.hasParamAttr(I, Attribute::ReadNone))
3695
3696 // Call site argument attribute "nofree".
3697 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(CBArgPos, CBArgAttrs);
3698 }
3699 return true;
3700 };
3701
3702 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
3703 [[maybe_unused]] bool Success;
3704 bool UsedAssumedInformation = false;
3706 nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
3707 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
3708 (unsigned)Instruction::Call},
3709 UsedAssumedInformation);
3710 assert(Success && "Expected the check call to be successful!");
3711
3712 auto LoadStorePred = [&](Instruction &I) -> bool {
3713 if (auto *LI = dyn_cast<LoadInst>(&I)) {
3714 getOrCreateAAFor<AAAlign>(IRPosition::value(*LI->getPointerOperand()));
3715 if (SimplifyAllLoads)
3717 UsedAssumedInformation, AA::Intraprocedural);
3719 IRPosition::value(*LI->getPointerOperand()));
3721 IRPosition::value(*LI->getPointerOperand()));
3722 } else {
3723 auto &SI = cast<StoreInst>(I);
3725 getAssumedSimplified(IRPosition::value(*SI.getValueOperand()), nullptr,
3726 UsedAssumedInformation, AA::Intraprocedural);
3727 getOrCreateAAFor<AAAlign>(IRPosition::value(*SI.getPointerOperand()));
3729 IRPosition::value(*SI.getPointerOperand()));
3730 }
3731 return true;
3732 };
3734 nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
3735 {(unsigned)Instruction::Load, (unsigned)Instruction::Store},
3736 UsedAssumedInformation);
3737 assert(Success && "Expected the check call to be successful!");
3738
3739 // AllocaInstPredicate
3740 auto AAAllocationInfoPred = [&](Instruction &I) -> bool {
3742 return true;
3743 };
3744
3746 nullptr, OpcodeInstMap, AAAllocationInfoPred, nullptr, nullptr,
3747 {(unsigned)Instruction::Alloca}, UsedAssumedInformation);
3748 assert(Success && "Expected the check call to be successful!");
3749}
3750
3752 if (CloseWorldAssumption.getNumOccurrences())
3753 return CloseWorldAssumption;
3754 return isModulePass() && Configuration.IsClosedWorldModule;
3755}
3756
3757/// Helpers to ease debugging through output streams and print calls.
3758///
3759///{
3761 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
3762}
3763
3765 switch (AP) {
3767 return OS << "inv";
3769 return OS << "flt";
3771 return OS << "fn_ret";
3773 return OS << "cs_ret";
3775 return OS << "fn";
3777 return OS << "cs";
3779 return OS << "arg";
3781 return OS << "cs_arg";
3782 }
3783 llvm_unreachable("Unknown attribute position!");
3784}
3785
3787 const Value &AV = Pos.getAssociatedValue();
3788 OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
3789 << Pos.getAnchorValue().getName() << "@" << Pos.getCallSiteArgNo() << "]";
3790
3791 if (Pos.hasCallBaseContext())
3792 OS << "[cb_context:" << *Pos.getCallBaseContext() << "]";
3793 return OS << "}";
3794}
3795
3797 OS << "range-state(" << S.getBitWidth() << ")<";
3798 S.getKnown().print(OS);
3799 OS << " / ";
3800 S.getAssumed().print(OS);
3801 OS << ">";
3802
3803 return OS << static_cast<const AbstractState &>(S);
3804}
3805
3807 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
3808}
3809
3811 AA.print(OS);
3812 return OS;
3813}
3814
3817 OS << "set-state(< {";
3818 if (!S.isValidState())
3819 OS << "full-set";
3820 else {
3821 for (const auto &It : S.getAssumedSet())
3822 OS << It << ", ";
3823 if (S.undefIsContained())
3824 OS << "undef ";
3825 }
3826 OS << "} >)";
3827
3828 return OS;
3829}
3830
3832 const PotentialLLVMValuesState &S) {
3833 OS << "set-state(< {";
3834 if (!S.isValidState())
3835 OS << "full-set";
3836 else {
3837 for (const auto &It : S.getAssumedSet()) {
3838 if (auto *F = dyn_cast<Function>(It.first.getValue()))
3839 OS << "@" << F->getName() << "[" << int(It.second) << "], ";
3840 else
3841 OS << *It.first.getValue() << "[" << int(It.second) << "], ";
3842 }
3843 if (S.undefIsContained())
3844 OS << "undef ";
3845 }
3846 OS << "} >)";
3847
3848 return OS;
3849}
3850
3852 OS << "[";
3853 OS << getName();
3854 OS << "] for CtxI ";
3855
3856 if (auto *I = getCtxI()) {
3857 OS << "'";
3858 I->print(OS);
3859 OS << "'";
3860 } else
3861 OS << "<<null inst>>";
3862
3863 OS << " at position " << getIRPosition() << " with state " << getAsStr(A)
3864 << '\n';
3865}
3866
3868 print(OS);
3869
3870 for (const auto &DepAA : Deps) {
3871 auto *AA = DepAA.getPointer();
3872 OS << " updates ";
3873 AA->print(OS);
3874 }
3875
3876 OS << '\n';
3877}
3878
3880 const AAPointerInfo::Access &Acc) {
3881 OS << " [" << Acc.getKind() << "] " << *Acc.getRemoteInst();
3882 if (Acc.getLocalInst() != Acc.getRemoteInst())
3883 OS << " via " << *Acc.getLocalInst();
3884 if (Acc.getContent()) {
3885 if (*Acc.getContent())
3886 OS << " [" << **Acc.getContent() << "]";
3887 else
3888 OS << " [ <unknown> ]";
3889 }
3890 return OS;
3891}
3892///}
3893
3894/// ----------------------------------------------------------------------------
3895/// Pass (Manager) Boilerplate
3896/// ----------------------------------------------------------------------------
3897
3899 SetVector<Function *> &Functions,
3900 CallGraphUpdater &CGUpdater,
3902 bool DeleteFns, bool IsModulePass) {
3903 if (Functions.empty())
3904 return false;
3905
3906 LLVM_DEBUG({
3907 dbgs() << "[Attributor] Run on module with " << Functions.size()
3908 << " functions:\n";
3909 for (Function *Fn : Functions)
3910 dbgs() << " - " << Fn->getName() << "\n";
3911 });
3912
3913 // Create an Attributor and initially empty information cache that is filled
3914 // while we identify default attribute opportunities.
3915 AttributorConfig AC(CGUpdater);
3916 AC.IsModulePass = IsModulePass;
3917 AC.DeleteFns = DeleteFns;
3918 auto OREGetter = [&FAM](Function *F) -> OptimizationRemarkEmitter & {
3919 return FAM.getResult<OptimizationRemarkEmitterAnalysis>(*F);
3920 };
3921 AC.OREGetter = OREGetter;
3922 AC.PassName = DEBUG_TYPE;
3923
3924 /// Tracking callback for specialization of indirect calls.
3926 IndirectCalleeTrackingMap;
3927 if (MaxSpecializationPerCB.getNumOccurrences()) {
3928 AC.IndirectCalleeSpecializationCallback =
3929 [&](Attributor &, const AbstractAttribute &AA, CallBase &CB,
3930 Function &Callee, unsigned) {
3931 if (MaxSpecializationPerCB == 0)
3932 return false;
3933 auto &Set = IndirectCalleeTrackingMap[&CB];
3934 if (!Set)
3935 Set = std::make_unique<SmallPtrSet<Function *, 8>>();
3936 if (Set->size() >= MaxSpecializationPerCB)
3937 return Set->contains(&Callee);
3938 Set->insert(&Callee);
3939 return true;
3940 };
3941 }
3942
3943 Attributor A(Functions, InfoCache, AC);
3944
3945 // Create shallow wrappers for all functions that are not IPO amendable
3947 for (Function *F : Functions)
3948 if (!A.isFunctionIPOAmendable(*F))
3950
3951 // Internalize non-exact functions
3952 // TODO: for now we eagerly internalize functions without calculating the
3953 // cost, we need a cost interface to determine whether internalizing
3954 // a function is "beneficial"
3955 if (AllowDeepWrapper) {
3956 unsigned FunSize = Functions.size();
3957 for (unsigned u = 0; u < FunSize; u++) {
3958 Function *F = Functions[u];
3959 if (!F->isDeclaration() && !F->isDefinitionExact() && !F->use_empty() &&
3960 !GlobalValue::isInterposableLinkage(F->getLinkage())) {
3962 assert(NewF && "Could not internalize function.");
3963 Functions.insert(NewF);
3964
3965 // Update call graph
3966 CGUpdater.replaceFunctionWith(*F, *NewF);
3967 for (const Use &U : NewF->uses())
3968 if (CallBase *CB = dyn_cast<CallBase>(U.getUser())) {
3969 auto *CallerF = CB->getCaller();
3970 CGUpdater.reanalyzeFunction(*CallerF);
3971 }
3972 }
3973 }
3974 }
3975
3976 for (Function *F : Functions) {
3977 if (F->isDeclaration())
3978 continue;
3979
3980 if (F->hasExactDefinition())
3981 NumFnWithExactDefinition++;
3982 else
3983 NumFnWithoutExactDefinition++;
3984
3985 // We look at internal functions only on-demand but if any use is not a
3986 // direct call or outside the current set of analyzed functions, we have
3987 // to do it eagerly.
3988 if (F->hasLocalLinkage()) {
3989 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
3990 const auto *CB = dyn_cast<CallBase>(U.getUser());
3991 return CB && CB->isCallee(&U) &&
3992 Functions.count(const_cast<Function *>(CB->getCaller()));
3993 }))
3994 continue;
3995 }
3996
3997 // Populate the Attributor with abstract attribute opportunities in the
3998 // function and the information cache with IR information.
3999 A.identifyDefaultAbstractAttributes(*F);
4000 }
4001
4002 ChangeStatus Changed = A.run();
4003
4004 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
4005 << " functions, result: " << Changed << ".\n");
4007}
4008
4010 SetVector<Function *> &Functions,
4011 CallGraphUpdater &CGUpdater,
4013 bool IsModulePass) {
4014 if (Functions.empty())
4015 return false;
4016
4017 LLVM_DEBUG({
4018 dbgs() << "[AttributorLight] Run on module with " << Functions.size()
4019 << " functions:\n";
4020 for (Function *Fn : Functions)
4021 dbgs() << " - " << Fn->getName() << "\n";
4022 });
4023
4024 // Create an Attributor and initially empty information cache that is filled
4025 // while we identify default attribute opportunities.
4026 AttributorConfig AC(CGUpdater);
4027 AC.IsModulePass = IsModulePass;
4028 AC.DeleteFns = false;
4029 DenseSet<const char *> Allowed(
4036 AC.Allowed = &Allowed;
4037 AC.UseLiveness = false;
4038
4039 Attributor A(Functions, InfoCache, AC);
4040
4041 for (Function *F : Functions) {
4042 if (F->isDeclaration())
4043 continue;
4044
4045 if (F->hasExactDefinition())
4046 NumFnWithExactDefinition++;
4047 else
4048 NumFnWithoutExactDefinition++;
4049
4050 // We look at internal functions only on-demand but if any use is not a
4051 // direct call or outside the current set of analyzed functions, we have
4052 // to do it eagerly.
4053 if (AC.UseLiveness && F->hasLocalLinkage()) {
4054 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
4055 const auto *CB = dyn_cast<CallBase>(U.getUser());
4056 return CB && CB->isCallee(&U) &&
4057 Functions.count(const_cast<Function *>(CB->getCaller()));
4058 }))
4059 continue;
4060 }
4061
4062 // Populate the Attributor with abstract attribute opportunities in the
4063 // function and the information cache with IR information.
4064 A.identifyDefaultAbstractAttributes(*F);
4065 }
4066
4067 ChangeStatus Changed = A.run();
4068
4070 // Invalidate analyses for modified functions so that we don't have to
4071 // invalidate all analyses for all functions in this SCC.
4072 PreservedAnalyses FuncPA;
4073 // We haven't changed the CFG for modified functions.
4074 FuncPA.preserveSet<CFGAnalyses>();
4075 // Functions whose instructions did not change do not need to be simplified
4076 // again if their SCC is revisited.
4077 PreservedAnalyses AttrOnlyPA = FuncPA;
4079
4080 const SmallSetVector<Function *, 8> &IRModified = A.getModifiedFunctions();
4081
4082 // Also invalidate any direct callers of changed functions since analyses
4083 // may care about attributes of direct callees. For example, MemorySSA
4084 // cares about whether or not a call's callee modifies memory and queries
4085 // that through function attributes.
4086 auto InvalidateCallers = [&](Function &Changed) {
4087 for (auto *U : Changed.users()) {
4088 auto *Call = dyn_cast<CallBase>(U);
4089 if (Call && Call->getCalledFunction() == &Changed)
4090 FAM.invalidate(*Call->getFunction(), AttrOnlyPA);
4091 }
4092 };
4093
4094 for (Function *Changed : IRModified) {
4095 FAM.invalidate(*Changed, FuncPA);
4096 InvalidateCallers(*Changed);
4097 }
4098
4099 for (Function *Changed : A.getAttrModifiedFunctions()) {
4100 if (IRModified.contains(Changed))
4101 continue;
4102 FAM.invalidate(*Changed, AttrOnlyPA);
4103 InvalidateCallers(*Changed);
4104 }
4105 }
4106 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
4107 << " functions, result: " << Changed << ".\n");
4109}
4110
4111void AADepGraph::viewGraph() { llvm::ViewGraph(this, "Dependency Graph"); }
4112
4114 static std::atomic<int> CallTimes;
4115 std::string Prefix;
4116
4117 if (!DepGraphDotFileNamePrefix.empty())
4119 else
4120 Prefix = "dep_graph";
4121 std::string Filename =
4122 Prefix + "_" + std::to_string(CallTimes.load()) + ".dot";
4123
4124 outs() << "Dependency graph dump to " << Filename << ".\n";
4125
4126 std::error_code EC;
4127
4129 if (!EC)
4130 llvm::WriteGraph(File, this);
4131
4132 CallTimes++;
4133}
4134
4136 for (auto DepAA : SyntheticRoot.Deps)
4137 cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(outs());
4138}
4139
4143 AnalysisGetter AG(FAM);
4144
4145 SetVector<Function *> Functions;
4146 Functions.reserve(M.size());
4147 for (Function &F : M)
4148 Functions.insert(&F);
4149
4150 CallGraphUpdater CGUpdater;
4151 BumpPtrAllocator Allocator;
4152 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);
4153 if (runAttributorOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4154 /* DeleteFns */ true, /* IsModulePass */ true)) {
4155 // FIXME: Think about passes we will preserve and add them here.
4156 return PreservedAnalyses::none();
4157 }
4158 return PreservedAnalyses::all();
4159}
4160
4163 LazyCallGraph &CG,
4164 CGSCCUpdateResult &UR) {
4166 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
4167 AnalysisGetter AG(FAM);
4168
4169 SetVector<Function *> Functions;
4170 Functions.reserve(C.size());
4171 for (LazyCallGraph::Node &N : C)
4172 Functions.insert(&N.getFunction());
4173
4174 if (Functions.empty())
4175 return PreservedAnalyses::all();
4176
4177 Module &M = *Functions.back()->getParent();
4178 CallGraphUpdater CGUpdater;
4179 CGUpdater.initialize(CG, C, AM, UR);
4180 BumpPtrAllocator Allocator;
4181 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
4182 if (runAttributorOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4183 /* DeleteFns */ false,
4184 /* IsModulePass */ false)) {
4185 // FIXME: Think about passes we will preserve and add them here.
4188 return PA;
4189 }
4190 return PreservedAnalyses::all();
4191}
4192
4197 AnalysisGetter AG(FAM, /* CachedOnly */ true);
4198
4199 SetVector<Function *> Functions;
4200 Functions.reserve(M.size());
4201 for (Function &F : M)
4202 Functions.insert(&F);
4203
4204 CallGraphUpdater CGUpdater;
4205 BumpPtrAllocator Allocator;
4206 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);
4207 if (runAttributorLightOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4208 /* IsModulePass */ true)) {
4210 // We have not added or removed functions.
4212 // We already invalidated all relevant function analyses above.
4214 return PA;
4215 }
4216 return PreservedAnalyses::all();
4217}
4218
4221 LazyCallGraph &CG,
4222 CGSCCUpdateResult &UR) {
4224 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
4225 AnalysisGetter AG(FAM);
4226
4227 SetVector<Function *> Functions;
4228 for (LazyCallGraph::Node &N : C)
4229 Functions.insert(&N.getFunction());
4230
4231 if (Functions.empty())
4232 return PreservedAnalyses::all();
4233
4234 Module &M = *Functions.back()->getParent();
4235 CallGraphUpdater CGUpdater;
4236 CGUpdater.initialize(CG, C, AM, UR);
4237 BumpPtrAllocator Allocator;
4238 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
4239 if (runAttributorLightOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4240 /* IsModulePass */ false)) {
4242 // We have not added or removed functions.
4244 // We already invalidated all relevant function analyses above.
4246 return PA;
4247 }
4248 return PreservedAnalyses::all();
4249}
4250namespace llvm {
4251
4268
4269template <>
4271 static NodeRef getEntryNode(AADepGraph *DG) { return DG->GetEntryNode(); }
4272
4275
4276 static nodes_iterator nodes_begin(AADepGraph *DG) { return DG->begin(); }
4277
4278 static nodes_iterator nodes_end(AADepGraph *DG) { return DG->end(); }
4279};
4280
4281template <> struct DOTGraphTraits<AADepGraph *> : public DefaultDOTGraphTraits {
4283
4284 static std::string getNodeLabel(const AADepGraphNode *Node,
4285 const AADepGraph *DG) {
4286 std::string AAString;
4287 raw_string_ostream O(AAString);
4288 Node->print(O);
4289 return AAString;
4290 }
4291};
4292
4293} // end namespace llvm
static unsigned getIntrinsicID(const SDNode *N)
const TargetLowering & TLI
SDValue Pred
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
uint64_t uint64_t
Rewrite undef for PHI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static cl::opt< bool > AllowShallowWrappers("attributor-allow-shallow-wrappers", cl::Hidden, cl::desc("Allow the Attributor to create shallow " "wrappers for non-exact definitions."), cl::init(false))
bool canMarkAsVisited(const User *Usr)
#define VERBOSE_DEBUG_TYPE
static cl::opt< bool > EnableHeapToStack("enable-heap-to-stack-conversion", cl::init(true), cl::Hidden)
static cl::list< std::string > SeedAllowList("attributor-seed-allow-list", cl::Hidden, cl::desc("Comma separated list of attribute names that are " "allowed to be seeded."), cl::CommaSeparated)
static bool getPotentialCopiesOfMemoryValue(Attributor &A, Ty &I, SmallSetVector< Value *, 4 > &PotentialCopies, SmallSetVector< Instruction *, 4 > *PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact)
static cl::opt< unsigned, true > MaxInitializationChainLengthX("attributor-max-initialization-chain-length", cl::Hidden, cl::desc("Maximal number of chained initializations (to avoid stack overflows)"), cl::location(MaxInitializationChainLength), cl::init(1024))
static cl::opt< unsigned > MaxSpecializationPerCB("attributor-max-specializations-per-call-base", cl::Hidden, cl::desc("Maximal number of callees specialized for " "a call base"), cl::init(UINT32_MAX))
static cl::opt< bool > SimplifyAllLoads("attributor-simplify-all-loads", cl::Hidden, cl::desc("Try to simplify all loads."), cl::init(true))
static bool runAttributorOnFunctions(InformationCache &InfoCache, SetVector< Function * > &Functions, CallGraphUpdater &CGUpdater, FunctionAnalysisManager &FAM, bool DeleteFns, bool IsModulePass)
}
static bool runAttributorLightOnFunctions(InformationCache &InfoCache, SetVector< Function * > &Functions, CallGraphUpdater &CGUpdater, FunctionAnalysisManager &FAM, bool IsModulePass)
static cl::opt< bool > ViewDepGraph("attributor-view-dep-graph", cl::Hidden, cl::desc("View the dependency graph."), cl::init(false))
static bool isEqualOrWorse(const Attribute &New, const Attribute &Old)
Return true if New is equal or worse than Old.
static cl::opt< bool > AllowDeepWrapper("attributor-allow-deep-wrappers", cl::Hidden, cl::desc("Allow the Attributor to use IP information " "derived from non-exact functions via cloning"), cl::init(false))
static cl::opt< bool > DumpDepGraph("attributor-dump-dep-graph", cl::Hidden, cl::desc("Dump the dependency graph to dot files."), cl::init(false))
static cl::opt< bool > PrintCallGraph("attributor-print-call-graph", cl::Hidden, cl::desc("Print Attributor's internal call graph"), cl::init(false))
static bool checkForAllInstructionsImpl(Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap, function_ref< bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA, const AAIsDead *LivenessAA, ArrayRef< unsigned > Opcodes, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, bool CheckPotentiallyDead=false)
static cl::opt< bool > PrintDependencies("attributor-print-dep", cl::Hidden, cl::desc("Print attribute dependencies"), cl::init(false))
static bool isAssumedReadOnlyOrReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool RequireReadNone, bool &IsKnown)
static cl::opt< std::string > DepGraphDotFileNamePrefix("attributor-depgraph-dot-filename-prefix", cl::Hidden, cl::desc("The prefix used for the CallGraph dot file names."))
static cl::opt< bool > AnnotateDeclarationCallSites("attributor-annotate-decl-cs", cl::Hidden, cl::desc("Annotate call sites of function declarations."), cl::init(false))
static cl::opt< unsigned > SetFixpointIterations("attributor-max-iterations", cl::Hidden, cl::desc("Maximal number of fixpoint iterations."), cl::init(32))
static cl::list< std::string > FunctionSeedAllowList("attributor-function-seed-allow-list", cl::Hidden, cl::desc("Comma separated list of function names that are " "allowed to be seeded."), cl::CommaSeparated)
static cl::opt< bool > EnableCallSiteSpecific("attributor-enable-call-site-specific-deduction", cl::Hidden, cl::desc("Allow the Attributor to do call site specific analysis"), cl::init(false))
static cl::opt< bool > CloseWorldAssumption("attributor-assume-closed-world", cl::Hidden, cl::desc("Should a closed world be assumed, or not. Default if not set."))
static Attribute getAttrToAdd(LLVMContext &Ctx, Attribute Attr, Attribute Existing, bool ForceReplace)
Return the attribute to add to a position to provide the information of Attr, given the attribute Exi...
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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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...
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
#define DEBUG_TYPE
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static constexpr StringLiteral Filename
FunctionAnalysisManager FAM
This file defines the PointerIntPair class.
static StringRef getName(Value *V)
Remove Loads Into Fake Uses
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet 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
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Definition Debug.h:72
void print(OutputBuffer &OB) const
static const fltSemantics & IEEEsingle()
Definition APFloat.h:304
Class for arbitrary precision integers.
Definition APInt.h:78
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
const Use & getCalleeUseForCallback() const
Return the use of the callee value in the underlying instruction.
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
bool isCallee(Value::const_user_iterator UI) const
Return true if UI is the use that defines the callee of this ACS.
Value * getCallArgOperand(Argument &Arg) const
Return the operand of the underlying instruction associated with Arg.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
unsigned getNumArgOperands() const
Return the number of parameters of the callee.
Function * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it's an indirect...
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
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
bool empty() const
Return true if the mask contains no attributes.
This class holds the attributes for a particular argument, parameter, function, or return value.
Definition Attributes.h:406
LLVM_ABI Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
LLVM_ABI bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
LLVM_ABI bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
LLVM_ABI bool isIntAttribute() const
Return true if the attribute is an integer attribute.
LLVM_ABI uint64_t getValueAsInt() const
Return the attribute's value as an integer.
LLVM_ABI bool isConstantRangeAttribute() const
Return true if the attribute is a ConstantRange attribute.
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:125
@ None
No attributes have been set.
Definition Attributes.h:127
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:262
LLVM Basic Block Representation.
Definition BasicBlock.h:62
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:463
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
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...
void setCallingConv(CallingConv::ID CC)
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
LLVM_ABI void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
CallingConv::ID getCallingConv() const
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
void setAttributes(AttributeList A)
Set the attributes for this call.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
Wrapper to unify "old style" CallGraph and "new style" LazyCallGraph.
LLVM_ABI void replaceFunctionWith(Function &OldFn, Function &NewFn)
Replace OldFn in the call graph (and SCC) with NewFn.
LLVM_ABI void reanalyzeFunction(Function &Fn)
After an CGSCC pass changes a function in ways that affect the call graph, this method can be called ...
void initialize(LazyCallGraph &LCG, LazyCallGraph::SCC &SCC, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR)
Initializers for usage outside of a CGSCC pass, inside a CGSCC pass in the old and new pass manager (...
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
void setTailCall(bool IsTc=true)
A constant value that is initialized with an expression using other constant values.
Definition Constants.h:1316
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static LLVM_ABI Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
LLVM_ABI void print(raw_ostream &OS) const
Print out the bounds to a stream.
This is an important base class in LLVM.
Definition Constant.h:44
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
static bool shouldExecute(CounterInfo &Counter)
bool empty() const
Definition DenseMap.h:716
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:793
Implements a dense probed hash-table based set.
Definition DenseSet.h:283
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
A proxy from a FunctionAnalysisManager to an SCC.
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void setSubprogram(DISubprogram *SP)
Set the attached subprogram.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:169
void splice(Function::iterator ToIt, Function *FromF)
Transfer all blocks from FromF to this function at ToIt.
Definition Function.h:746
const BasicBlock & getEntryBlock() const
Definition Function.h:794
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:212
iterator_range< arg_iterator > args()
Definition Function.h:877
DISubprogram * getSubprogram() const
Get the attached subprogram.
MemoryEffects getMemoryEffects() const
Definition Function.cpp:862
bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const
check if an attributes is in the list of attributes.
Definition Function.cpp:743
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
iterator begin()
Definition Function.h:838
arg_iterator arg_begin()
Definition Function.h:853
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition Function.h:332
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:352
size_t arg_size() const
Definition Function.h:886
Type * getReturnType() const
Returns the type of the ret val.
Definition Function.h:217
void setMemoryEffects(MemoryEffects ME)
Definition Function.cpp:865
Argument * getArg(unsigned i) const
Definition Function.h:871
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition Function.cpp:846
bool hasMetadata() const
Return true if this GlobalObject has any metadata attached to it.
LLVM_ABI void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
LinkageTypes getLinkage() const
bool hasLocalLinkage() const
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
void setDSOLocal(bool Local)
PointerType * getType() const
Global values are always pointers.
@ DefaultVisibility
The GV is visible.
Definition GlobalValue.h:68
void setVisibility(VisibilityTypes V)
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
LLVM_ABI void copyProfileAndDebugMetadata(const Instruction &SrcInst)
Copy debug, profile, and memprof metadata from SrcInst to this instruction without copying alias-anal...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr, InsertPosition InsertBefore=nullptr)
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
A node in the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
An instruction for reading from memory.
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memcpy/memmove intrinsics.
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
bool doesAccessArgPointees() const
Whether this function may access argument memory.
Definition ModRef.h:260
static MemoryEffectsBase unknown()
Definition ModRef.h:123
static LLVM_ABI MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
static LLVM_ABI MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
const FunctionListType & getFunctionList() const
Get the Module's list of functions (constant).
Definition Module.h:714
The optimization diagnostic interface.
PointerIntPair - This class implements a pair of a pointer and small integer.
void * getOpaqueValue() const
PointerTy getPointer() const
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
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.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
A vector that has set insertion semantics.
Definition SetVector.h:57
ArrayRef< value_type > getArrayRef() const
Definition SetVector.h:91
bool remove(const value_type &X)
Remove an item from the set vector.
Definition SetVector.h:187
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
void reserve(size_type Size)
Reserve space in the SetVector if supported by the underlying containers.
Definition SetVector.h:106
void insert_range(Range &&R)
Definition SetVector.h:182
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
Definition SetVector.h:268
typename vector_type::const_iterator iterator
Definition SetVector.h:72
void clear()
Completely clear the SetVector.
Definition SetVector.h:273
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition SetVector.h:112
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
size_type size() const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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:346
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
A visitor class for IR positions.
LLVM_ABI SubsumingPositionIterator(const IRPosition &IRP)
Provides information about what library functions are available for the current target.
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:548
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:707
iterator_range< use_iterator > uses()
Definition Value.h:382
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:395
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
iterator insert(iterator where, pointer New)
Definition ilist.h:165
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU constant address space for the target triple...
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU shared address space for the target triple i...
LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU local/private address space for the target t...
LLVM_ABI bool isPotentiallyAffectedByBarrier(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is potentially affected by a barrier.
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
LLVM_ABI Constant * getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA, Value &Obj, Type &Ty, const TargetLibraryInfo *TLI, const DataLayout &DL, RangeTy *RangePtr=nullptr)
Return the initial value of Obj with type Ty if that is a constant.
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:186
@ Intraprocedural
Definition Attributor.h:187
@ Interprocedural
Definition Attributor.h:188
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
Definition FileSystem.h:802
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
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:1755
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp:522
LLVM_ABI unsigned MaxInitializationChainLength
The value passed to the line option that defines the maximal initialization chain length.
LLVM_ABI bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr, DomTreeUpdater *DTU=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
Definition Local.cpp:133
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
APInt operator&(APInt a, const APInt &b)
Definition APInt.h:2149
LLVM_ABI void detachDeadBlocks(ArrayRef< BasicBlock * > BBs, SmallVectorImpl< DominatorTree::UpdateType > *Updates, bool KeepOneInputPHIs=false)
Replace contents of every block in BBs with single unreachable instruction.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Done
Definition Threading.h:60
DenseMap< AssumeInst *, MinMax > Assume2KnowledgeMap
A mapping from intrinsics (=llvm.assume calls) to a value range (=knowledge) that is encoded in them.
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
LLVM_ABI CallInst * changeToCall(InvokeInst *II, DomTreeUpdater *DTU=nullptr)
This function converts the specified invoke into a normal call.
Definition Local.cpp:2612
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
LLVM_ABI InlineResult isInlineViable(Function &Callee)
Check if it is mechanically possible to inline the function Callee, based on the contents of the func...
LLVM_ABI bool shouldCreateAbstractAttribute()
Check the debug counter used to limit the number of AAs created.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
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:1762
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
Definition Local.cpp:408
LLVM_ABI Constant * ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty, const DataLayout &DL)
If C is a uniform value where all bits are the same (either all zero, all ones, all undef or all pois...
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI bool AreStatisticsEnabled()
Check if statistics are enabled.
LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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
@ Success
The lock was released successfully.
LLVM_ABI unsigned changeToUnreachable(Instruction *I, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
Definition Local.cpp:2547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Global
Append to llvm.global_dtors.
LLVM_ABI BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock * > Preds, const char *Suffix, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)
This method introduces at least one new basic block into the function and moves some of the predecess...
PotentialValuesState< APInt > PotentialConstantIntValuesState
bool operator&=(SparseBitVector< ElementSize > *LHS, const SparseBitVector< ElementSize > &RHS)
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
Definition CFG.cpp:335
DWARFExpression::Operation Op
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, CloneFunctionChangeType Changes, SmallVectorImpl< ReturnInst * > &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Clone OldFunc into NewFunc, transforming the old arguments into references to VMap values.
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:2208
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
LLVM_ABI bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates or reallocates memory (eith...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
ChangeStatus
{
Definition Attributor.h:477
LLVM_ABI void fillMapFromAssume(AssumeInst &Assume, RetainedKnowledgeMap &Result)
Insert into the map all the informations contained in the operand bundles of the llvm....
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
LLVM_ABI Constant * ConstantFoldCastInstruction(unsigned opcode, Constant *V, Type *DestTy)
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:489
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:490
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:488
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
APInt operator|(APInt a, const APInt &b)
Definition APInt.h:2169
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
#define N
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
DepSetTy Deps
Set of dependency graph nodes which should be updated if this one is updated.
Definition Attributor.h:504
PointerIntPair< AADepGraphNode *, 1 > DepTy
Definition Attributor.h:498
The data structure for the dependency graph.
Definition Attributor.h:537
iterator begin()
Definition Attributor.h:552
LLVM_ABI void viewGraph()
AADepGraphNode SyntheticRoot
There is no root node for the dependency graph.
Definition Attributor.h:549
LLVM_ABI void print()
Print dependency graph.
iterator end()
Definition Attributor.h:553
LLVM_ABI void dumpGraph()
Dump graph to file.
AADepGraphNode * GetEntryNode()
Definition Attributor.h:550
An abstract interface to track if a value leaves it's defining function instance.
bool isAssumedUniqueForAnalysis() const
Return true if we assume that the underlying value is unique in its scope wrt.
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for liveness abstract attribute.
virtual bool isKnownDead() const =0
Returns true if the underlying value is known dead.
virtual bool isAssumedDead() const =0
The query functions are protected such that other attributes need to go through the Attributor interf...
virtual bool isRemovableStore() const
Return true if the underlying value is a store that is known to be removable.
static bool mayCatchAsynchronousExceptions(const Function &F)
Determine if F might catch asynchronous exceptions.
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An access description.
bool isWrittenValueUnknown() const
Return true if the value written cannot be determined at all.
std::optional< Value * > getContent() const
Return the written value which can be llvm::null if it is not yet determined.
bool isWriteOrAssumption() const
Return true if this is a write access.
bool isRead() const
Return true if this is a read access.
Value * getWrittenValue() const
Return the value writen, if any.
Instruction * getLocalInst() const
Return the instruction that causes the access with respect to the local scope of the associated attri...
Instruction * getRemoteInst() const
Return the actual instruction that causes the access.
bool isWrittenValueYetUndetermined() const
Return true if the value written is not known yet.
AccessKind getKind() const
Return the access kind.
An abstract interface for struct information.
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract attribute for getting all assumption underlying objects.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:245
bool offsetOrSizeAreUnknown() const
Return true if offset or size are unknown.
Definition Attributor.h:254
Value * getValue() const
Definition Attributor.h:198
const Instruction * getCtxI() const
Definition Attributor.h:199
Base struct for all "concrete attribute" deductions.
ChangeStatus update(Attributor &A)
Hook for the Attributor to trigger an update of the internal state.
friend struct Attributor
}
virtual void printWithDeps(raw_ostream &OS) const
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
virtual const std::string getAsStr(Attributor *A) const =0
This function should return the "summarized" assumed state as string.
virtual bool isQueryAA() const
A query AA is always scheduled as long as we do updates because it does lazy computation that cannot ...
virtual ChangeStatus updateImpl(Attributor &A)=0
The actual update/transfer function which has to be implemented by the derived classes.
const IRPosition & getIRPosition() const
Return an IR position, see struct IRPosition.
An interface to query the internal state of an abstract attribute.
virtual ChangeStatus indicatePessimisticFixpoint()=0
Indicate that the abstract state should converge to the pessimistic state.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Wrapper for FunctionAnalysisManager.
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
void populateAll() const
Force populate the entire call graph.
Configuration for the Attributor.
std::optional< unsigned > MaxFixpointIterations
Maximum number of iterations to run until fixpoint.
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Helper struct used in the communication between an abstract attribute (AA) that wants to change the s...
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
LLVM_ABI bool registerFunctionSignatureRewrite(Argument &Arg, ArrayRef< Type * > ReplacementTypes, ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB, ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB)
Register a rewrite for a function signature.
LLVM_ABI ~Attributor()
LLVM_ABI bool checkForAllCallees(function_ref< bool(ArrayRef< const Function * > Callees)> Pred, const AbstractAttribute &QueryingAA, const CallBase &CB)
Check Pred on all potential Callees of CB.
bool isModulePass() const
Return true if this is a module pass, false otherwise.
LLVM_ABI bool isValidFunctionSignatureRewrite(Argument &Arg, ArrayRef< Type * > ReplacementTypes)
Check if we can rewrite a function signature.
static LLVM_ABI bool isInternalizable(Function &F)
Returns true if the function F can be internalized.
LLVM_ABI ChangeStatus removeAttrs(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AttrKinds)
Remove all AttrKinds attached to IRP.
void emitRemark(Instruction *I, StringRef RemarkName, RemarkCallBack &&RemarkCB) const
Emit a remark generically.
bool isRunOn(Function &Fn) const
Return true if we derive attributes for Fn.
LLVM_ABI bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, DepClassTy DepClass=DepClassTy::OPTIONAL)
Return true if AA (or its context instruction) is assumed dead.
LLVM_ABI bool checkForAllInstructions(function_ref< bool(Instruction &)> Pred, const Function *Fn, const AbstractAttribute *QueryingAA, ArrayRef< unsigned > Opcodes, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, bool CheckPotentiallyDead=false)
Check Pred on all instructions in Fn with an opcode present in Opcodes.
LLVM_ABI void recordDependence(const AbstractAttribute &FromAA, const AbstractAttribute &ToAA, DepClassTy DepClass)
Explicitly record a dependence from FromAA to ToAA, that is if FromAA changes ToAA should be updated ...
static LLVM_ABI void createShallowWrapper(Function &F)
Create a shallow wrapper for F such that F has internal linkage afterwards.
const AAType * getAAFor(const AbstractAttribute &QueryingAA, const IRPosition &IRP, DepClassTy DepClass)
Lookup an abstract attribute of type AAType at position IRP.
std::optional< Value * > getAssumedSimplified(const IRPosition &IRP, const AbstractAttribute &AA, bool &UsedAssumedInformation, AA::ValueScope S)
If V is assumed simplified, return it, if it is unclear yet, return std::nullopt, otherwise return nu...
static LLVM_ABI Function * internalizeFunction(Function &F, bool Force=false)
Make another copy of the function F such that the copied version has internal linkage afterwards and ...
bool isFunctionIPOAmendable(const Function &F)
Determine whether the function F is IPO amendable.
const AAType * getOrCreateAAFor(IRPosition IRP, const AbstractAttribute *QueryingAA, DepClassTy DepClass, bool ForceUpdate=false, bool UpdateAfterInit=true)
The version of getAAFor that allows to omit a querying abstract attribute.
LLVM_ABI bool checkForAllReadWriteInstructions(function_ref< bool(Instruction &)> Pred, AbstractAttribute &QueryingAA, bool &UsedAssumedInformation)
Check Pred on all Read/Write instructions.
LLVM_ABI bool checkForAllReturnedValues(function_ref< bool(Value &)> Pred, const AbstractAttribute &QueryingAA, AA::ValueScope S=AA::ValueScope::Intraprocedural, bool RecurseForSelectAndPHI=true)
Check Pred on all values potentially returned by the function associated with QueryingAA.
LLVM_ABI bool isClosedWorldModule() const
Return true if the module contains the whole world, thus, no outside functions exist.
LLVM_ABI std::optional< Constant * > getAssumedConstant(const IRPosition &IRP, const AbstractAttribute &AA, bool &UsedAssumedInformation)
If IRP is assumed to be a constant, return it, if it is unclear yet, return std::nullopt,...
LLVM_ABI Attributor(SetVector< Function * > &Functions, InformationCache &InfoCache, AttributorConfig Configuration)
Constructor.
LLVM_ABI void getAttrs(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AKs, SmallVectorImpl< Attribute > &Attrs, bool IgnoreSubsumingPositions=false)
Return the attributes of any kind in AKs existing in the IR at a position that will affect this one.
InformationCache & getInfoCache()
Return the internal information cache.
LLVM_ABI std::optional< Value * > translateArgumentToCallSiteContent(std::optional< Value * > V, CallBase &CB, const AbstractAttribute &AA, bool &UsedAssumedInformation)
Translate V from the callee context into the call site context.
LLVM_ABI bool checkForAllUses(function_ref< bool(const Use &, bool &)> Pred, const AbstractAttribute &QueryingAA, const Value &V, bool CheckBBLivenessOnly=false, DepClassTy LivenessDepClass=DepClassTy::OPTIONAL, bool IgnoreDroppableUses=true, function_ref< bool(const Use &OldU, const Use &NewU)> EquivalentUseCB=nullptr)
Check Pred on all (transitive) uses of V.
LLVM_ABI ChangeStatus manifestAttrs(const IRPosition &IRP, ArrayRef< Attribute > DeducedAttrs, bool ForceReplace=false)
Attach DeducedAttrs to IRP, if ForceReplace is set we do this even if the same attribute kind was alr...
LLVM_ABI bool hasAttr(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AKs, bool IgnoreSubsumingPositions=false, Attribute::AttrKind ImpliedAttributeKind=Attribute::None)
Return true if any kind in AKs existing in the IR at a position that will affect this one.
LLVM_ABI void registerForUpdate(AbstractAttribute &AA)
Allows a query AA to request an update if a new query was received.
std::function< bool(Attributor &, const AbstractAttribute *)> VirtualUseCallbackTy
LLVM_ABI void identifyDefaultAbstractAttributes(Function &F)
Determine opportunities to derive 'default' attributes in F and create abstract attribute objects for...
LLVM_ABI bool getAssumedSimplifiedValues(const IRPosition &IRP, const AbstractAttribute *AA, SmallVectorImpl< AA::ValueAndContext > &Values, AA::ValueScope S, bool &UsedAssumedInformation, bool RecurseForSelectAndPHI=true)
Try to simplify IRP and in the scope S.
BumpPtrAllocator & Allocator
The allocator used to allocate memory, e.g. for AbstractAttributes.
LLVM_ABI ChangeStatus run()
Run the analyses until a fixpoint is reached or enforced (timeout).
static LLVM_ABI bool internalizeFunctions(SmallPtrSetImpl< Function * > &FnSet, DenseMap< Function *, Function * > &FnMap)
Make copies of each function in the set FnSet such that the copied version has internal linkage after...
LLVM_ABI bool checkForAllCallSites(function_ref< bool(AbstractCallSite)> Pred, const AbstractAttribute &QueryingAA, bool RequireAllCallSites, bool &UsedAssumedInformation)
Check Pred on all function call sites.
LLVM_ABI bool getAttrsFromAssumes(const IRPosition &IRP, Attribute::AttrKind AK, SmallVectorImpl< Attribute > &Attrs)
Return the attributes of kind AK existing in the IR as operand bundles of an llvm....
bool isKnown(base_t BitsEncoding=BestState) const
Return true if the bits set in BitsEncoding are "known bits".
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
static std::string getNodeLabel(const AADepGraphNode *Node, const AADepGraph *DG)
DefaultDOTGraphTraits(bool simple=false)
Represent subnormal handling kind for floating point instruction inputs and outputs.
@ Dynamic
Denormals have unknown treatment.
static NodeRef DepGetVal(const DepTy &DT)
PointerIntPair< AADepGraphNode *, 1 > DepTy
static ChildIteratorType child_end(NodeRef N)
static NodeRef getEntryNode(AADepGraphNode *DGN)
mapped_iterator< AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)> ChildIteratorType
PointerIntPair< AADepGraphNode *, 1 > EdgeRef
static ChildIteratorType child_begin(NodeRef N)
AADepGraphNode::DepSetTy::iterator ChildEdgeIteratorType
static NodeRef getEntryNode(AADepGraph *DG)
mapped_iterator< AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)> nodes_iterator
static nodes_iterator nodes_begin(AADepGraph *DG)
static nodes_iterator nodes_end(AADepGraph *DG)
typename AADepGraph *::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:94
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:573
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:704
void setAttrList(const AttributeList &AttrList) const
Update the attributes associated with this function or call site scope.
Definition Attributor.h:840
unsigned getAttrIdx() const
Return the index in the attribute list for this position.
Definition Attributor.h:805
bool hasCallBaseContext() const
Check if the position has any call base context.
Definition Attributor.h:900
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:641
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:623
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:597
CallBase CallBaseContext
Definition Attributor.h:576
AttributeList getAttrList() const
Return the attributes associated with this function or call site scope.
Definition Attributor.h:833
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:609
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:646
Kind
The positions we distinguish in the IR.
Definition Attributor.h:579
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:587
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:583
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:586
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:584
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:585
@ IRP_FLOAT
A position that is not associated with a spot suitable for attributes.
Definition Attributor.h:581
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:588
@ IRP_INVALID
An invalid position.
Definition Attributor.h:580
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:757
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:630
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:616
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:897
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:771
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:690
Value * getAttrListAnchor() const
Return the value attributes are attached to.
Definition Attributor.h:826
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition Attributor.h:800
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:847
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:636
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:745
Data structure to hold cached (LLVM-IR) information.
bool IsTargetGPU() const
Return true if the target is a GPU.
friend struct Attributor
Give the Attributor access to the members so Attributor::identifyDefaultAbstractAttributes(....
bool stackIsAccessibleByOtherThreads()
Return true if the stack (llvm::Alloca) can be accessed by other threads.
MustBeExecutedContextExplorer * getMustBeExecutedContextExplorer()
Return MustBeExecutedContextExplorer.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
std::array< InstructionVectorTy *, Instruction::OtherOpsEnd > OpcodeInstMapTy
A map type from opcodes to instructions with this opcode.
LLVM_ABI std::optional< unsigned > getFlatAddressSpace() const
Return the flat address space if the associated target has.
const RetainedKnowledgeMap & getKnowledgeMap() const
Return the map conaining all the knowledge we have from llvm.assumes.
LLVM_ABI ArrayRef< Function * > getIndirectlyCallableFunctions(Attributor &A) const
Return all functions that might be called indirectly, only valid for closed world modules (see isClos...
SmallVector< Instruction *, 8 > InstructionVectorTy
A vector type to hold instructions.
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
State for an integer range.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
uint32_t getBitWidth() const
Return associated values' bit width.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool undefIsContained() const
Returns whether this state contains an undef value or not.
bool isValidState() const override
Return if this abstract state is in a valid state.
const SetTy & getAssumedSet() const
Return this set.