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) { return M.getTargetTriple().isGPU(); }
229
230bool AA::isGPUSharedAddressSpace(const Module &M, unsigned AS) {
231 assert(AA::isGPU(M) && "Only callable on GPU targets");
232 const Triple &T = M.getTargetTriple();
233
234 if (T.isSPIRV())
235 return AS == static_cast<unsigned>(SPIRVAddressSpace::Shared);
236
237 return AS == static_cast<unsigned>(NVPTXAMDGPUAddressSpace::Shared);
238}
239
240bool AA::isGPUConstantAddressSpace(const Module &M, unsigned AS) {
241 assert(AA::isGPU(M) && "Only callable on GPU targets");
242 const Triple &T = M.getTargetTriple();
243
244 if (T.isSPIRV())
245 return AS == static_cast<unsigned>(SPIRVAddressSpace::Constant);
246
247 return AS == static_cast<unsigned>(NVPTXAMDGPUAddressSpace::Constant);
248}
249
250bool AA::isGPULocalAddressSpace(const Module &M, unsigned AS) {
251 assert(AA::isGPU(M) && "Only callable on GPU targets");
252 const Triple &T = M.getTargetTriple();
253
254 if (T.isSPIRV())
255 return AS == static_cast<unsigned>(SPIRVAddressSpace::Local);
256
257 return AS == static_cast<unsigned>(NVPTXAMDGPUAddressSpace::Local);
258}
259
261 const AbstractAttribute &QueryingAA) {
262 // We are looking for volatile instructions or non-relaxed atomics.
263 if (const auto *CB = dyn_cast<CallBase>(&I)) {
264 if (CB->hasFnAttr(Attribute::NoSync))
265 return true;
266
267 // Non-convergent and readnone imply nosync.
268 if (!CB->isConvergent() && !CB->mayReadOrWriteMemory())
269 return true;
270
271 bool IsKnownNoSync;
273 A, &QueryingAA, IRPosition::callsite_function(*CB),
274 DepClassTy::OPTIONAL, IsKnownNoSync);
275 }
276
277 if (!I.mayReadOrWriteMemory())
278 return true;
279
281}
282
284 const Value &V, bool ForAnalysisOnly) {
285 // TODO: See the AAInstanceInfo class comment.
286 if (!ForAnalysisOnly)
287 return false;
288 auto *InstanceInfoAA = A.getAAFor<AAInstanceInfo>(
290 return InstanceInfoAA && InstanceInfoAA->isAssumedUniqueForAnalysis();
291}
292
293Constant *
295 Value &Obj, Type &Ty, const TargetLibraryInfo *TLI,
296 const DataLayout &DL, AA::RangeTy *RangePtr) {
297 if (Constant *Init = getInitialValueOfAllocation(&Obj, TLI, &Ty))
298 return Init;
299 auto *GV = dyn_cast<GlobalVariable>(&Obj);
300 if (!GV)
301 return nullptr;
302
303 bool UsedAssumedInformation = false;
304 Constant *Initializer = nullptr;
305 if (A.hasGlobalVariableSimplificationCallback(*GV)) {
306 auto AssumedGV = A.getAssumedInitializerFromCallBack(
307 *GV, &QueryingAA, UsedAssumedInformation);
308 Initializer = *AssumedGV;
309 if (!Initializer)
310 return nullptr;
311 } else {
312 if (!GV->hasLocalLinkage()) {
313 // Externally visible global that's either non-constant,
314 // or a constant with an uncertain initializer.
315 if (!GV->hasDefinitiveInitializer() || !GV->isConstant())
316 return nullptr;
317 }
318
319 // Globals with local linkage are always initialized.
320 assert(!GV->hasLocalLinkage() || GV->hasInitializer());
321
322 if (!Initializer)
323 Initializer = GV->getInitializer();
324 }
325
326 if (RangePtr && !RangePtr->offsetOrSizeAreUnknown()) {
327 int64_t StorageSize = DL.getTypeStoreSize(&Ty);
328 if (StorageSize != RangePtr->Size)
329 return nullptr;
330 APInt Offset = APInt(64, RangePtr->Offset);
331 return ConstantFoldLoadFromConst(Initializer, &Ty, Offset, DL);
332 }
333
334 return ConstantFoldLoadFromUniformValue(Initializer, &Ty, DL);
335}
336
337bool AA::isValidInScope(const Value &V, const Function *Scope) {
338 if (isa<Constant>(V))
339 return true;
340 if (auto *I = dyn_cast<Instruction>(&V))
341 return I->getFunction() == Scope;
342 if (auto *A = dyn_cast<Argument>(&V))
343 return A->getParent() == Scope;
344 return false;
345}
346
348 InformationCache &InfoCache) {
349 if (isa<Constant>(VAC.getValue()) || VAC.getValue() == VAC.getCtxI())
350 return true;
351 const Function *Scope = nullptr;
352 const Instruction *CtxI = VAC.getCtxI();
353 if (CtxI)
354 Scope = CtxI->getFunction();
355 if (auto *A = dyn_cast<Argument>(VAC.getValue()))
356 return A->getParent() == Scope;
357 if (auto *I = dyn_cast<Instruction>(VAC.getValue())) {
358 if (I->getFunction() == Scope) {
359 if (const DominatorTree *DT =
361 *Scope))
362 return DT->dominates(I, CtxI);
363 // Local dominance check mostly for the old PM passes.
364 if (CtxI && I->getParent() == CtxI->getParent())
365 return llvm::any_of(
366 make_range(I->getIterator(), I->getParent()->end()),
367 [&](const Instruction &AfterI) { return &AfterI == CtxI; });
368 }
369 }
370 return false;
371}
372
374 if (V.getType() == &Ty)
375 return &V;
376 if (isa<PoisonValue>(V))
377 return PoisonValue::get(&Ty);
378 if (isa<UndefValue>(V))
379 return UndefValue::get(&Ty);
380 if (auto *C = dyn_cast<Constant>(&V)) {
381 if (C->isNullValue() && !Ty.isPtrOrPtrVectorTy())
382 return Constant::getNullValue(&Ty);
383 if (C->getType()->isPointerTy() && Ty.isPointerTy())
384 return ConstantExpr::getPointerCast(C, &Ty);
385 if (C->getType()->getPrimitiveSizeInBits() >= Ty.getPrimitiveSizeInBits()) {
386 if (C->getType()->isIntegerTy() && Ty.isIntegerTy())
387 return ConstantExpr::getTrunc(C, &Ty, /* OnlyIfReduced */ true);
388 if (C->getType()->isFloatingPointTy() && Ty.isFloatingPointTy())
389 return ConstantFoldCastInstruction(Instruction::FPTrunc, C, &Ty);
390 }
391 }
392 return nullptr;
393}
394
395std::optional<Value *>
396AA::combineOptionalValuesInAAValueLatice(const std::optional<Value *> &A,
397 const std::optional<Value *> &B,
398 Type *Ty) {
399 if (A == B)
400 return A;
401 if (!B)
402 return A;
403 if (*B == nullptr)
404 return nullptr;
405 if (!A)
406 return Ty ? getWithType(**B, *Ty) : nullptr;
407 if (*A == nullptr)
408 return nullptr;
409 if (!Ty)
410 Ty = (*A)->getType();
412 return getWithType(**B, *Ty);
413 if (isa<UndefValue>(*B))
414 return A;
415 if (*A && *B && *A == getWithType(**B, *Ty))
416 return A;
417 return nullptr;
418}
419
420template <bool IsLoad, typename Ty>
422 Attributor &A, Ty &I, SmallSetVector<Value *, 4> &PotentialCopies,
423 SmallSetVector<Instruction *, 4> *PotentialValueOrigins,
424 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
425 bool OnlyExact) {
426 LLVM_DEBUG(dbgs() << "Trying to determine the potential copies of " << I
427 << " (only exact: " << OnlyExact << ")\n";);
428
429 Value &Ptr = *I.getPointerOperand();
430 // Containers to remember the pointer infos and new copies while we are not
431 // sure that we can find all of them. If we abort we want to avoid spurious
432 // dependences and potential copies in the provided container.
436
437 const auto *TLI =
438 A.getInfoCache().getTargetLibraryInfoForFunction(*I.getFunction());
439
440 auto Pred = [&](Value &Obj) {
441 LLVM_DEBUG(dbgs() << "Visit underlying object " << Obj << "\n");
442 if (isa<UndefValue>(&Obj))
443 return true;
444 if (isa<ConstantPointerNull>(&Obj)) {
445 // A null pointer access can be undefined but any offset from null may
446 // be OK. We do not try to optimize the latter.
447 if (!NullPointerIsDefined(I.getFunction(),
448 Ptr.getType()->getPointerAddressSpace()) &&
449 A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation,
450 AA::Interprocedural) == &Obj)
451 return true;
453 dbgs() << "Underlying object is a valid nullptr, giving up.\n";);
454 return false;
455 }
456 // TODO: Use assumed noalias return.
457 if (!isa<AllocaInst>(&Obj) && !isa<GlobalVariable>(&Obj) &&
458 !(IsLoad ? isAllocationFn(&Obj, TLI) : isNoAliasCall(&Obj))) {
459 LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << Obj
460 << "\n";);
461 return false;
462 }
463 if (auto *GV = dyn_cast<GlobalVariable>(&Obj))
464 if (!GV->hasLocalLinkage() &&
465 !(GV->isConstant() && GV->hasInitializer())) {
466 LLVM_DEBUG(dbgs() << "Underlying object is global with external "
467 "linkage, not supported yet: "
468 << Obj << "\n";);
469 return false;
470 }
471
472 bool NullOnly = true;
473 bool NullRequired = false;
474 auto CheckForNullOnlyAndUndef = [&](std::optional<Value *> V,
475 bool IsExact) {
476 if (!V || *V == nullptr)
477 NullOnly = false;
478 else if (isa<UndefValue>(*V))
479 /* No op */;
480 else if (isa<Constant>(*V) && cast<Constant>(*V)->isNullValue())
481 NullRequired = !IsExact;
482 else
483 NullOnly = false;
484 };
485
486 auto AdjustWrittenValueType = [&](const AAPointerInfo::Access &Acc,
487 Value &V) {
488 Value *AdjV = AA::getWithType(V, *I.getType());
489 if (!AdjV) {
490 LLVM_DEBUG(dbgs() << "Underlying object written but stored value "
491 "cannot be converted to read type: "
492 << *Acc.getRemoteInst() << " : " << *I.getType()
493 << "\n";);
494 }
495 return AdjV;
496 };
497
498 auto SkipCB = [&](const AAPointerInfo::Access &Acc) {
499 if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))
500 return true;
501 if (IsLoad) {
503 return true;
504 if (PotentialValueOrigins && !isa<AssumeInst>(Acc.getRemoteInst()))
505 return false;
506 if (!Acc.isWrittenValueUnknown())
507 if (Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue()))
508 if (NewCopies.count(V)) {
509 NewCopyOrigins.insert(Acc.getRemoteInst());
510 return true;
511 }
512 if (auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst()))
513 if (Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand()))
514 if (NewCopies.count(V)) {
515 NewCopyOrigins.insert(Acc.getRemoteInst());
516 return true;
517 }
518 }
519 return false;
520 };
521
522 auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) {
523 if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))
524 return true;
525 if (IsLoad && Acc.isWrittenValueYetUndetermined())
526 return true;
527 CheckForNullOnlyAndUndef(Acc.getContent(), IsExact);
528 if (OnlyExact && !IsExact && !NullOnly &&
530 LLVM_DEBUG(dbgs() << "Non exact access " << *Acc.getRemoteInst()
531 << ", abort!\n");
532 return false;
533 }
534 if (NullRequired && !NullOnly) {
535 LLVM_DEBUG(dbgs() << "Required all `null` accesses due to non exact "
536 "one, however found non-null one: "
537 << *Acc.getRemoteInst() << ", abort!\n");
538 return false;
539 }
540 if (IsLoad) {
541 assert(isa<LoadInst>(I) && "Expected load or store instruction only!");
542 if (!Acc.isWrittenValueUnknown()) {
543 Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue());
544 if (!V)
545 return false;
546 NewCopies.insert(V);
547 if (PotentialValueOrigins)
548 NewCopyOrigins.insert(Acc.getRemoteInst());
549 return true;
550 }
551 auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst());
552 if (!SI) {
553 LLVM_DEBUG(dbgs() << "Underlying object written through a non-store "
554 "instruction not supported yet: "
555 << *Acc.getRemoteInst() << "\n";);
556 return false;
557 }
558 Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand());
559 if (!V)
560 return false;
561 NewCopies.insert(V);
562 if (PotentialValueOrigins)
563 NewCopyOrigins.insert(SI);
564 } else {
565 assert(isa<StoreInst>(I) && "Expected load or store instruction only!");
566 auto *LI = dyn_cast<LoadInst>(Acc.getRemoteInst());
567 if (!LI && OnlyExact) {
568 LLVM_DEBUG(dbgs() << "Underlying object read through a non-load "
569 "instruction not supported yet: "
570 << *Acc.getRemoteInst() << "\n";);
571 return false;
572 }
573 NewCopies.insert(Acc.getRemoteInst());
574 }
575 return true;
576 };
577
578 // If the value has been written to we don't need the initial value of the
579 // object.
580 bool HasBeenWrittenTo = false;
581
583 auto *PI = A.getAAFor<AAPointerInfo>(QueryingAA, IRPosition::value(Obj),
585 if (!PI || !PI->forallInterferingAccesses(
586 A, QueryingAA, I,
587 /* FindInterferingWrites */ IsLoad,
588 /* FindInterferingReads */ !IsLoad, CheckAccess,
589 HasBeenWrittenTo, Range, SkipCB)) {
591 dbgs()
592 << "Failed to verify all interfering accesses for underlying object: "
593 << Obj << "\n");
594 return false;
595 }
596
597 if (IsLoad && !HasBeenWrittenTo && !Range.isUnassigned()) {
598 const DataLayout &DL = A.getDataLayout();
599 Value *InitialValue = AA::getInitialValueForObj(
600 A, QueryingAA, Obj, *I.getType(), TLI, DL, &Range);
601 if (!InitialValue) {
602 LLVM_DEBUG(dbgs() << "Could not determine required initial value of "
603 "underlying object, abort!\n");
604 return false;
605 }
606 CheckForNullOnlyAndUndef(InitialValue, /* IsExact */ true);
607 if (NullRequired && !NullOnly) {
608 LLVM_DEBUG(dbgs() << "Non exact access but initial value that is not "
609 "null or undef, abort!\n");
610 return false;
611 }
612
613 NewCopies.insert(InitialValue);
614 if (PotentialValueOrigins)
615 NewCopyOrigins.insert(nullptr);
616 }
617
618 PIs.push_back(PI);
619
620 return true;
621 };
622
623 const auto *AAUO = A.getAAFor<AAUnderlyingObjects>(
624 QueryingAA, IRPosition::value(Ptr), DepClassTy::OPTIONAL);
625 if (!AAUO || !AAUO->forallUnderlyingObjects(Pred)) {
627 dbgs() << "Underlying objects stored into could not be determined\n";);
628 return false;
629 }
630
631 // Only if we were successful collection all potential copies we record
632 // dependences (on non-fix AAPointerInfo AAs). We also only then modify the
633 // given PotentialCopies container.
634 for (const auto *PI : PIs) {
635 if (!PI->getState().isAtFixpoint())
636 UsedAssumedInformation = true;
637 A.recordDependence(*PI, QueryingAA, DepClassTy::OPTIONAL);
638 }
639 PotentialCopies.insert_range(NewCopies);
640 if (PotentialValueOrigins)
641 PotentialValueOrigins->insert_range(NewCopyOrigins);
642
643 return true;
644}
645
647 Attributor &A, LoadInst &LI, SmallSetVector<Value *, 4> &PotentialValues,
648 SmallSetVector<Instruction *, 4> &PotentialValueOrigins,
649 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
650 bool OnlyExact) {
651 return getPotentialCopiesOfMemoryValue</* IsLoad */ true>(
652 A, LI, PotentialValues, &PotentialValueOrigins, QueryingAA,
653 UsedAssumedInformation, OnlyExact);
654}
655
658 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
659 bool OnlyExact) {
660 return getPotentialCopiesOfMemoryValue</* IsLoad */ false>(
661 A, SI, PotentialCopies, nullptr, QueryingAA, UsedAssumedInformation,
662 OnlyExact);
663}
664
666 const AbstractAttribute &QueryingAA,
667 bool RequireReadNone, bool &IsKnown) {
668 if (RequireReadNone) {
670 A, &QueryingAA, IRP, DepClassTy::OPTIONAL, IsKnown,
671 /* IgnoreSubsumingPositions */ true))
672 return true;
674 A, &QueryingAA, IRP, DepClassTy::OPTIONAL, IsKnown,
675 /* IgnoreSubsumingPositions */ true))
676 return true;
677
680 const auto *MemLocAA =
681 A.getAAFor<AAMemoryLocation>(QueryingAA, IRP, DepClassTy::NONE);
682 if (MemLocAA && MemLocAA->isAssumedReadNone()) {
683 IsKnown = MemLocAA->isKnownReadNone();
684 if (!IsKnown)
685 A.recordDependence(*MemLocAA, QueryingAA, DepClassTy::OPTIONAL);
686 return true;
687 }
688 }
689
690 const auto *MemBehaviorAA =
691 A.getAAFor<AAMemoryBehavior>(QueryingAA, IRP, DepClassTy::NONE);
692 if (MemBehaviorAA &&
693 (MemBehaviorAA->isAssumedReadNone() ||
694 (!RequireReadNone && MemBehaviorAA->isAssumedReadOnly()))) {
695 IsKnown = RequireReadNone ? MemBehaviorAA->isKnownReadNone()
696 : MemBehaviorAA->isKnownReadOnly();
697 if (!IsKnown)
698 A.recordDependence(*MemBehaviorAA, QueryingAA, DepClassTy::OPTIONAL);
699 return true;
700 }
701
702 return false;
703}
704
706 const AbstractAttribute &QueryingAA, bool &IsKnown) {
707 return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,
708 /* RequireReadNone */ false, IsKnown);
709}
711 const AbstractAttribute &QueryingAA, bool &IsKnown) {
712 return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,
713 /* RequireReadNone */ true, IsKnown);
714}
715
716static bool
718 const Instruction *ToI, const Function &ToFn,
719 const AbstractAttribute &QueryingAA,
720 const AA::InstExclusionSetTy *ExclusionSet,
721 std::function<bool(const Function &F)> GoBackwardsCB) {
723 dbgs() << "[AA] isPotentiallyReachable @" << ToFn.getName() << " from "
724 << FromI << " [GBCB: " << bool(GoBackwardsCB) << "][#ExS: "
725 << (ExclusionSet ? std::to_string(ExclusionSet->size()) : "none")
726 << "]\n";
727 if (ExclusionSet)
728 for (auto *ES : *ExclusionSet)
729 dbgs() << *ES << "\n";
730 });
731
732 // We know kernels (generally) cannot be called from within the module. Thus,
733 // for reachability we would need to step back from a kernel which would allow
734 // us to reach anything anyway. Even if a kernel is invoked from another
735 // kernel, values like allocas and shared memory are not accessible. We
736 // implicitly check for this situation to avoid costly lookups.
737 if (GoBackwardsCB && &ToFn != FromI.getFunction() &&
738 !GoBackwardsCB(*FromI.getFunction()) && A.getInfoCache().isKernel(ToFn) &&
739 A.getInfoCache().isKernel(*FromI.getFunction())) {
740 LLVM_DEBUG(dbgs() << "[AA] assume kernel cannot be reached from within the "
741 "module; success\n";);
742 return false;
743 }
744
745 // If we can go arbitrarily backwards we will eventually reach an entry point
746 // that can reach ToI. Only if a set of blocks through which we cannot go is
747 // provided, or once we track internal functions not accessible from the
748 // outside, it makes sense to perform backwards analysis in the absence of a
749 // GoBackwardsCB.
750 if (!GoBackwardsCB && !ExclusionSet) {
751 LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI
752 << " is not checked backwards and does not have an "
753 "exclusion set, abort\n");
754 return true;
755 }
756
759 Worklist.push_back(&FromI);
760
761 while (!Worklist.empty()) {
762 const Instruction *CurFromI = Worklist.pop_back_val();
763 if (!Visited.insert(CurFromI).second)
764 continue;
765
766 const Function *FromFn = CurFromI->getFunction();
767 if (FromFn == &ToFn) {
768 if (!ToI)
769 return true;
770 LLVM_DEBUG(dbgs() << "[AA] check " << *ToI << " from " << *CurFromI
771 << " intraprocedurally\n");
772 const auto *ReachabilityAA = A.getAAFor<AAIntraFnReachability>(
773 QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);
774 bool Result = !ReachabilityAA || ReachabilityAA->isAssumedReachable(
775 A, *CurFromI, *ToI, ExclusionSet);
776 LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " "
777 << (Result ? "can potentially " : "cannot ") << "reach "
778 << *ToI << " [Intra]\n");
779 if (Result)
780 return true;
781 }
782
783 bool Result = true;
784 if (!ToFn.isDeclaration() && ToI) {
785 const auto *ToReachabilityAA = A.getAAFor<AAIntraFnReachability>(
786 QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);
787 const Instruction &EntryI = ToFn.getEntryBlock().front();
788 Result = !ToReachabilityAA || ToReachabilityAA->isAssumedReachable(
789 A, EntryI, *ToI, ExclusionSet);
790 LLVM_DEBUG(dbgs() << "[AA] Entry " << EntryI << " of @" << ToFn.getName()
791 << " " << (Result ? "can potentially " : "cannot ")
792 << "reach @" << *ToI << " [ToFn]\n");
793 }
794
795 if (Result) {
796 // The entry of the ToFn can reach the instruction ToI. If the current
797 // instruction is already known to reach the ToFn.
798 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
799 QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);
800 Result = !FnReachabilityAA || FnReachabilityAA->instructionCanReach(
801 A, *CurFromI, ToFn, ExclusionSet);
802 LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " in @" << FromFn->getName()
803 << " " << (Result ? "can potentially " : "cannot ")
804 << "reach @" << ToFn.getName() << " [FromFn]\n");
805 if (Result)
806 return true;
807 }
808
809 // TODO: Check assumed nounwind.
810 const auto *ReachabilityAA = A.getAAFor<AAIntraFnReachability>(
811 QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);
812 auto ReturnInstCB = [&](Instruction &Ret) {
813 bool Result = !ReachabilityAA || ReachabilityAA->isAssumedReachable(
814 A, *CurFromI, Ret, ExclusionSet);
815 LLVM_DEBUG(dbgs() << "[AA][Ret] " << *CurFromI << " "
816 << (Result ? "can potentially " : "cannot ") << "reach "
817 << Ret << " [Intra]\n");
818 return !Result;
819 };
820
821 // Check if we can reach returns.
822 bool UsedAssumedInformation = false;
823 if (A.checkForAllInstructions(ReturnInstCB, FromFn, &QueryingAA,
824 {Instruction::Ret}, UsedAssumedInformation)) {
825 LLVM_DEBUG(dbgs() << "[AA] No return is reachable, done\n");
826 continue;
827 }
828
829 if (!GoBackwardsCB) {
830 LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI
831 << " is not checked backwards, abort\n");
832 return true;
833 }
834
835 // If we do not go backwards from the FromFn we are done here and so far we
836 // could not find a way to reach ToFn/ToI.
837 if (!GoBackwardsCB(*FromFn))
838 continue;
839
840 LLVM_DEBUG(dbgs() << "Stepping backwards to the call sites of @"
841 << FromFn->getName() << "\n");
842
843 auto CheckCallSite = [&](AbstractCallSite ACS) {
844 CallBase *CB = ACS.getInstruction();
845 if (!CB)
846 return false;
847
848 if (isa<InvokeInst>(CB))
849 return false;
850
851 Instruction *Inst = CB->getNextNode();
852 Worklist.push_back(Inst);
853 return true;
854 };
855
856 Result = !A.checkForAllCallSites(CheckCallSite, *FromFn,
857 /* RequireAllCallSites */ true,
858 &QueryingAA, UsedAssumedInformation);
859 if (Result) {
860 LLVM_DEBUG(dbgs() << "[AA] stepping back to call sites from " << *CurFromI
861 << " in @" << FromFn->getName()
862 << " failed, give up\n");
863 return true;
864 }
865
866 LLVM_DEBUG(dbgs() << "[AA] stepped back to call sites from " << *CurFromI
867 << " in @" << FromFn->getName()
868 << " worklist size is: " << Worklist.size() << "\n");
869 }
870 return false;
871}
872
874 Attributor &A, const Instruction &FromI, const Instruction &ToI,
875 const AbstractAttribute &QueryingAA,
876 const AA::InstExclusionSetTy *ExclusionSet,
877 std::function<bool(const Function &F)> GoBackwardsCB) {
878 const Function *ToFn = ToI.getFunction();
879 return ::isPotentiallyReachable(A, FromI, &ToI, *ToFn, QueryingAA,
880 ExclusionSet, GoBackwardsCB);
881}
882
884 Attributor &A, const Instruction &FromI, const Function &ToFn,
885 const AbstractAttribute &QueryingAA,
886 const AA::InstExclusionSetTy *ExclusionSet,
887 std::function<bool(const Function &F)> GoBackwardsCB) {
888 return ::isPotentiallyReachable(A, FromI, /* ToI */ nullptr, ToFn, QueryingAA,
889 ExclusionSet, GoBackwardsCB);
890}
891
893 const AbstractAttribute &QueryingAA) {
894 if (isa<UndefValue>(Obj))
895 return true;
896 if (isa<AllocaInst>(Obj)) {
897 InformationCache &InfoCache = A.getInfoCache();
898 if (!InfoCache.stackIsAccessibleByOtherThreads()) {
900 dbgs() << "[AA] Object '" << Obj
901 << "' is thread local; stack objects are thread local.\n");
902 return true;
903 }
904 bool IsKnownNoCapture;
905 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
906 A, &QueryingAA, IRPosition::value(Obj), DepClassTy::OPTIONAL,
907 IsKnownNoCapture);
908 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj << "' is "
909 << (IsAssumedNoCapture ? "" : "not") << " thread local; "
910 << (IsAssumedNoCapture ? "non-" : "")
911 << "captured stack object.\n");
912 return IsAssumedNoCapture;
913 }
914 if (auto *GV = dyn_cast<GlobalVariable>(&Obj)) {
915 if (GV->isConstant()) {
916 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj
917 << "' is thread local; constant global\n");
918 return true;
919 }
920 if (GV->isThreadLocal()) {
921 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj
922 << "' is thread local; thread local global\n");
923 return true;
924 }
925 }
926
927 if (A.getInfoCache().IsTargetGPU()) {
928 if (AA::isGPULocalAddressSpace(A.getInfoCache().getModule(),
929 Obj.getType()->getPointerAddressSpace())) {
930 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj
931 << "' is thread local; GPU local memory\n");
932 return true;
933 }
935 A.getInfoCache().getModule(),
936 Obj.getType()->getPointerAddressSpace())) {
937 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj
938 << "' is thread local; GPU constant memory\n");
939 return true;
940 }
941 }
942
943 LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj << "' is not thread local\n");
944 return false;
945}
946
948 const AbstractAttribute &QueryingAA) {
949 if (!I.mayHaveSideEffects() && !I.mayReadFromMemory())
950 return false;
951
953
954 auto AddLocationPtr = [&](std::optional<MemoryLocation> Loc) {
955 if (!Loc || !Loc->Ptr) {
957 dbgs() << "[AA] Access to unknown location; -> requires barriers\n");
958 return false;
959 }
960 Ptrs.insert(Loc->Ptr);
961 return true;
962 };
963
964 if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&I)) {
965 if (!AddLocationPtr(MemoryLocation::getForDest(MI)))
966 return true;
968 if (!AddLocationPtr(MemoryLocation::getForSource(MTI)))
969 return true;
970 } else if (!AddLocationPtr(MemoryLocation::getOrNone(&I)))
971 return true;
972
973 return isPotentiallyAffectedByBarrier(A, Ptrs.getArrayRef(), QueryingAA, &I);
974}
975
978 const AbstractAttribute &QueryingAA,
979 const Instruction *CtxI) {
980 for (const Value *Ptr : Ptrs) {
981 if (!Ptr) {
982 LLVM_DEBUG(dbgs() << "[AA] nullptr; -> requires barriers\n");
983 return true;
984 }
985
986 auto Pred = [&](Value &Obj) {
987 if (AA::isAssumedThreadLocalObject(A, Obj, QueryingAA))
988 return true;
989 LLVM_DEBUG(dbgs() << "[AA] Access to '" << Obj << "' via '" << *Ptr
990 << "'; -> requires barrier\n");
991 return false;
992 };
993
994 const auto *UnderlyingObjsAA = A.getAAFor<AAUnderlyingObjects>(
995 QueryingAA, IRPosition::value(*Ptr), DepClassTy::OPTIONAL);
996 if (!UnderlyingObjsAA || !UnderlyingObjsAA->forallUnderlyingObjects(Pred))
997 return true;
998 }
999 return false;
1000}
1001
1002/// Return true if \p New is equal or worse than \p Old.
1003static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
1004 if (!Old.isIntAttribute())
1005 return true;
1006
1007 return Old.getValueAsInt() >= New.getValueAsInt();
1008}
1009
1010/// Return the attribute to add to a position to provide the information of
1011/// \p Attr, given the attribute \p Existing of the same kind at the position
1012/// (or none), or an invalid attribute if \p Existing already provides it.
1014 Attribute Existing, bool ForceReplace) {
1015 if (Attr.isEnumAttribute())
1016 return Existing.isValid() ? Attribute() : Attr;
1017 if (Attr.isStringAttribute()) {
1018 if (Existing.isValid() && (!ForceReplace || Existing == Attr))
1019 return Attribute();
1020 return Attr;
1021 }
1022
1023 if (Attr.isIntAttribute()) {
1024 if (!ForceReplace && Attr.getKindAsEnum() == Attribute::Memory) {
1025 MemoryEffects OldME = Existing.isValid() ? Existing.getMemoryEffects()
1027 MemoryEffects ME = Attr.getMemoryEffects() & OldME;
1028 if (ME == OldME)
1029 return Attribute();
1030 return Attribute::getWithMemoryEffects(Ctx, ME);
1031 }
1032 if (Existing.isValid() && !ForceReplace && isEqualOrWorse(Attr, Existing))
1033 return Attribute();
1034 return Attr;
1035 }
1036
1037 if (Attr.isConstantRangeAttribute())
1038 return !ForceReplace && Existing.isValid() ? Attribute() : Attr;
1039
1040 llvm_unreachable("Expected enum or string attribute!");
1041}
1042
1045 return cast<Argument>(&getAnchorValue());
1046
1047 // Not an Argument and no argument number means this is not a call site
1048 // argument, thus we cannot find a callback argument to return.
1049 int ArgNo = getCallSiteArgNo();
1050 if (ArgNo < 0)
1051 return nullptr;
1052
1053 // Use abstract call sites to make the connection between the call site
1054 // values and the ones in callbacks. If a callback was found that makes use
1055 // of the underlying call site operand, we want the corresponding callback
1056 // callee argument and not the direct callee argument.
1057 std::optional<Argument *> CBCandidateArg;
1058 SmallVector<const Use *, 4> CallbackUses;
1059 const auto &CB = cast<CallBase>(getAnchorValue());
1060 AbstractCallSite::getCallbackUses(CB, CallbackUses);
1061 for (const Use *U : CallbackUses) {
1062 AbstractCallSite ACS(U);
1063 assert(ACS && ACS.isCallbackCall());
1064 if (!ACS.getCalledFunction())
1065 continue;
1066
1067 for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {
1068
1069 // Test if the underlying call site operand is argument number u of the
1070 // callback callee.
1071 if (ACS.getCallArgOperandNo(u) != ArgNo)
1072 continue;
1073
1074 assert(ACS.getCalledFunction()->arg_size() > u &&
1075 "ACS mapped into var-args arguments!");
1076 if (CBCandidateArg) {
1077 CBCandidateArg = nullptr;
1078 break;
1079 }
1080 CBCandidateArg = ACS.getCalledFunction()->getArg(u);
1081 }
1082 }
1083
1084 // If we found a unique callback candidate argument, return it.
1085 if (CBCandidateArg && *CBCandidateArg)
1086 return *CBCandidateArg;
1087
1088 // If no callbacks were found, or none used the underlying call site operand
1089 // exclusively, use the direct callee argument if available.
1090 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
1091 if (Callee && Callee->arg_size() > unsigned(ArgNo))
1092 return Callee->getArg(ArgNo);
1093
1094 return nullptr;
1095}
1096
1099 if (isStateAtFixpoint())
1100 return HasChanged;
1101
1102 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
1103
1104 HasChanged = updateImpl(A);
1105
1106 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
1107 << "\n");
1108
1109 return HasChanged;
1110}
1111
1113 InformationCache &InfoCache,
1114 AttributorConfig Configuration)
1115 : Allocator(InfoCache.Allocator), Functions(Functions),
1116 InfoCache(InfoCache), Configuration(Configuration) {
1117 if (!isClosedWorldModule())
1118 return;
1119 for (Function *Fn : Functions)
1120 if (Fn->hasAddressTaken(/*PutOffender=*/nullptr,
1121 /*IgnoreCallbackUses=*/false,
1122 /*IgnoreAssumeLikeCalls=*/true,
1123 /*IgnoreLLVMUsed=*/true,
1124 /*IgnoreARCAttachedCall=*/false,
1125 /*IgnoreCastedDirectCall=*/true))
1126 InfoCache.IndirectlyCallableFunctions.push_back(Fn);
1127}
1128
1133 "Did expect a valid position!");
1136 if (!Explorer)
1137 return false;
1138
1139 Value &AssociatedValue = IRP.getAssociatedValue();
1140
1141 const Assume2KnowledgeMap &A2K =
1142 getInfoCache().getKnowledgeMap().lookup({&AssociatedValue, AK});
1143
1144 // Check if we found any potential assume use, if not we don't need to create
1145 // explorer iterators.
1146 if (A2K.empty())
1147 return false;
1148
1149 LLVMContext &Ctx = AssociatedValue.getContext();
1150 unsigned AttrsSize = Attrs.size();
1151 auto EIt = Explorer->begin(IRP.getCtxI()),
1152 EEnd = Explorer->end(IRP.getCtxI());
1153 for (const auto &It : A2K)
1154 if (Explorer->findInContextOf(It.first, EIt, EEnd))
1155 Attrs.push_back(Attribute::get(Ctx, AK, It.second.Max));
1156 return AttrsSize != Attrs.size();
1157}
1158
1159template <typename DescTy>
1161Attributor::updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,
1162 function_ref<bool(const DescTy &, AttributeSet,
1163 AttributeMask &, AttrBuilder &)>
1164 CB) {
1165 if (AttrDescs.empty())
1167 switch (IRP.getPositionKind()) {
1171 default:
1172 break;
1173 };
1174
1175 AttributeList AL = IRP.getAttrList();
1176 Value *AttrListAnchor = IRP.getAttrListAnchor();
1177 auto [Iter, Inserted] = AttrsMap.insert({AttrListAnchor, AL});
1178 if (!Inserted)
1179 AL = Iter->second;
1180
1181 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
1182 auto AttrIdx = IRP.getAttrIdx();
1183 AttributeSet AS = AL.getAttributes(AttrIdx);
1184 AttributeMask AM;
1185 AttrBuilder AB(Ctx);
1186
1188 for (const DescTy &AttrDesc : AttrDescs)
1189 if (CB(AttrDesc, AS, AM, AB))
1190 HasChanged = ChangeStatus::CHANGED;
1191
1192 if (HasChanged == ChangeStatus::UNCHANGED)
1194
1195 if (!AM.empty())
1196 AL = AL.removeAttributesAtIndex(Ctx, AttrIdx, AM);
1197 AL = AL.addAttributesAtIndex(Ctx, AttrIdx, AB);
1198
1199 Iter->second = AL;
1200 return HasChanged;
1201}
1202
1205 bool IgnoreSubsumingPositions,
1206 Attribute::AttrKind ImpliedAttributeKind) {
1207 bool Implied = false;
1208 bool HasAttr = false;
1209 auto HasAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,
1210 AttributeMask &, AttrBuilder &) {
1211 if (AttrSet.hasAttribute(Kind)) {
1212 Implied |= Kind != ImpliedAttributeKind;
1213 HasAttr = true;
1214 }
1215 return false;
1216 };
1217 for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {
1218 updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, HasAttrCB);
1219 if (HasAttr)
1220 break;
1221 // The first position returned by the SubsumingPositionIterator is
1222 // always the position itself. If we ignore subsuming positions we
1223 // are done after the first iteration.
1224 if (IgnoreSubsumingPositions)
1225 break;
1226 Implied = true;
1227 }
1228 if (!HasAttr) {
1229 Implied = true;
1230 // Most modules have no assume knowledge.
1231 if (!InfoCache.getKnowledgeMap().empty()) {
1233 for (Attribute::AttrKind AK : AttrKinds)
1234 if (getAttrsFromAssumes(IRP, AK, Attrs)) {
1235 HasAttr = true;
1236 break;
1237 }
1238 }
1239 }
1240
1241 // Check if we should manifest the implied attribute kind at the IRP.
1242 if (ImpliedAttributeKind != Attribute::None && HasAttr && Implied)
1244 ImpliedAttributeKind)});
1245 return HasAttr;
1246}
1247
1251 bool IgnoreSubsumingPositions) {
1252 auto CollectAttrCB = [&](const Attribute::AttrKind &Kind,
1253 AttributeSet AttrSet, AttributeMask &,
1254 AttrBuilder &) {
1255 if (AttrSet.hasAttribute(Kind))
1256 Attrs.push_back(AttrSet.getAttribute(Kind));
1257 return false;
1258 };
1259 for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {
1260 updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, CollectAttrCB);
1261 // The first position returned by the SubsumingPositionIterator is
1262 // always the position itself. If we ignore subsuming positions we
1263 // are done after the first iteration.
1264 if (IgnoreSubsumingPositions)
1265 break;
1266 }
1267 if (!InfoCache.getKnowledgeMap().empty()) {
1268 for (Attribute::AttrKind AK : AttrKinds)
1269 getAttrsFromAssumes(IRP, AK, Attrs);
1270 }
1271}
1272
1275 auto RemoveAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,
1276 AttributeMask &AM, AttrBuilder &) {
1277 if (!AttrSet.hasAttribute(Kind))
1278 return false;
1279 AM.addAttribute(Kind);
1280 return true;
1281 };
1282 return updateAttrMap<Attribute::AttrKind>(IRP, AttrKinds, RemoveAttrCB);
1283}
1284
1286 ArrayRef<StringRef> Attrs) {
1287 auto RemoveAttrCB = [&](StringRef Attr, AttributeSet AttrSet,
1288 AttributeMask &AM, AttrBuilder &) -> bool {
1289 if (!AttrSet.hasAttribute(Attr))
1290 return false;
1291 AM.addAttribute(Attr);
1292 return true;
1293 };
1294
1295 return updateAttrMap<StringRef>(IRP, Attrs, RemoveAttrCB);
1296}
1297
1299 ArrayRef<Attribute> Attrs,
1300 bool ForceReplace) {
1301 if (Attrs.empty())
1303
1304 switch (IRP.getPositionKind()) {
1308 default:
1309 break;
1310 }
1311
1312 AttributeList AL = IRP.getAttrList();
1313 auto [Iter, Inserted] = AttrsMap.insert({IRP.getAttrListAnchor(), AL});
1314 if (!Inserted)
1315 AL = Iter->second;
1316
1317 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
1318 auto AttrIdx = IRP.getAttrIdx();
1319 AttributeSet AS = AL.getAttributes(AttrIdx);
1321 for (Attribute Attr : Attrs) {
1322 Attribute Existing = Attr.isStringAttribute()
1323 ? AS.getAttribute(Attr.getKindAsString())
1324 : AS.getAttribute(Attr.getKindAsEnum());
1325 if (Attribute New = getAttrToAdd(Ctx, Attr, Existing, ForceReplace);
1326 New.isValid())
1327 Added.push_back(New);
1328 }
1329
1330 if (Added.empty())
1332
1333 // Added keeps the order of Attrs, so it is sorted with distinct kinds too.
1334 AL = AL.addSortedAttributesAtIndex(Ctx, AttrIdx, Added);
1335 Iter->second = AL;
1336 return ChangeStatus::CHANGED;
1337}
1338
1340 IRPositions.emplace_back(IRP);
1341
1342 // Helper to determine if operand bundles on a call site are benign or
1343 // potentially problematic. We handle only llvm.assume for now.
1344 auto CanIgnoreOperandBundles = [](const CallBase &CB) {
1345 return (isa<IntrinsicInst>(CB) &&
1346 cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);
1347 };
1348
1349 const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue());
1350 switch (IRP.getPositionKind()) {
1354 return;
1357 IRPositions.emplace_back(IRPosition::function(*IRP.getAnchorScope()));
1358 return;
1360 assert(CB && "Expected call site!");
1361 // TODO: We need to look at the operand bundles similar to the redirection
1362 // in CallBase.
1363 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))
1364 if (auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()))
1365 IRPositions.emplace_back(IRPosition::function(*Callee));
1366 return;
1368 assert(CB && "Expected call site!");
1369 // TODO: We need to look at the operand bundles similar to the redirection
1370 // in CallBase.
1371 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
1372 if (auto *Callee =
1373 dyn_cast_if_present<Function>(CB->getCalledOperand())) {
1374 // The returned position of the callee does not describe the call if
1375 // the call uses a different return type.
1376 bool SameType = Callee->getReturnType() == CB->getType();
1377 if (SameType)
1378 IRPositions.emplace_back(IRPosition::returned(*Callee));
1379 IRPositions.emplace_back(IRPosition::function(*Callee));
1380 for (const Argument &Arg : Callee->args())
1381 if (SameType && Arg.hasReturnedAttr()) {
1382 IRPositions.emplace_back(
1383 IRPosition::callsite_argument(*CB, Arg.getArgNo()));
1384 IRPositions.emplace_back(
1385 IRPosition::value(*CB->getArgOperand(Arg.getArgNo())));
1386 IRPositions.emplace_back(IRPosition::argument(Arg));
1387 }
1388 }
1389 }
1390 IRPositions.emplace_back(IRPosition::callsite_function(*CB));
1391 return;
1393 assert(CB && "Expected call site!");
1394 // TODO: We need to look at the operand bundles similar to the redirection
1395 // in CallBase.
1396 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
1397 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
1398 if (Callee) {
1399 if (Argument *Arg = IRP.getAssociatedArgument())
1400 IRPositions.emplace_back(IRPosition::argument(*Arg));
1401 IRPositions.emplace_back(IRPosition::function(*Callee));
1402 }
1403 }
1404 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
1405 return;
1406 }
1407 }
1408}
1409
1410#ifdef EXPENSIVE_CHECKS
1411void IRPosition::verify() {
1412 switch (getPositionKind()) {
1413 case IRP_INVALID:
1414 assert((CBContext == nullptr) &&
1415 "Invalid position must not have CallBaseContext!");
1416 assert(!Enc.getOpaqueValue() &&
1417 "Expected a nullptr for an invalid position!");
1418 return;
1419 case IRP_FLOAT:
1421 "Expected specialized kind for argument values!");
1422 return;
1423 case IRP_RETURNED:
1424 assert(isa<Function>(getAsValuePtr()) &&
1425 "Expected function for a 'returned' position!");
1426 assert(getAsValuePtr() == &getAssociatedValue() &&
1427 "Associated value mismatch!");
1428 return;
1430 assert((CBContext == nullptr) &&
1431 "'call site returned' position must not have CallBaseContext!");
1432 assert((isa<CallBase>(getAsValuePtr())) &&
1433 "Expected call base for 'call site returned' position!");
1434 assert(getAsValuePtr() == &getAssociatedValue() &&
1435 "Associated value mismatch!");
1436 return;
1437 case IRP_CALL_SITE:
1438 assert((CBContext == nullptr) &&
1439 "'call site function' position must not have CallBaseContext!");
1440 assert((isa<CallBase>(getAsValuePtr())) &&
1441 "Expected call base for 'call site function' position!");
1442 assert(getAsValuePtr() == &getAssociatedValue() &&
1443 "Associated value mismatch!");
1444 return;
1445 case IRP_FUNCTION:
1446 assert(isa<Function>(getAsValuePtr()) &&
1447 "Expected function for a 'function' position!");
1448 assert(getAsValuePtr() == &getAssociatedValue() &&
1449 "Associated value mismatch!");
1450 return;
1451 case IRP_ARGUMENT:
1452 assert(isa<Argument>(getAsValuePtr()) &&
1453 "Expected argument for a 'argument' position!");
1454 assert(getAsValuePtr() == &getAssociatedValue() &&
1455 "Associated value mismatch!");
1456 return;
1458 assert((CBContext == nullptr) &&
1459 "'call site argument' position must not have CallBaseContext!");
1460 Use *U = getAsUsePtr();
1461 (void)U; // Silence unused variable warning.
1462 assert(U && "Expected use for a 'call site argument' position!");
1463 assert(isa<CallBase>(U->getUser()) &&
1464 "Expected call base user for a 'call site argument' position!");
1465 assert(cast<CallBase>(U->getUser())->isArgOperand(U) &&
1466 "Expected call base argument operand for a 'call site argument' "
1467 "position");
1468 assert(cast<CallBase>(U->getUser())->getArgOperandNo(U) ==
1469 unsigned(getCallSiteArgNo()) &&
1470 "Argument number mismatch!");
1471 assert(U->get() == &getAssociatedValue() && "Associated value mismatch!");
1472 return;
1473 }
1474 }
1475}
1476#endif
1477
1478std::optional<Constant *>
1480 const AbstractAttribute &AA,
1481 bool &UsedAssumedInformation) {
1482 // First check all callbacks provided by outside AAs. If any of them returns
1483 // a non-null value that is different from the associated value, or
1484 // std::nullopt, we assume it's simplified.
1485 for (auto &CB : SimplificationCallbacks.lookup(IRP)) {
1486 std::optional<Value *> SimplifiedV = CB(IRP, &AA, UsedAssumedInformation);
1487 if (!SimplifiedV)
1488 return std::nullopt;
1489 if (isa_and_nonnull<Constant>(*SimplifiedV))
1490 return cast<Constant>(*SimplifiedV);
1491 return nullptr;
1492 }
1493 if (auto *C = dyn_cast<Constant>(&IRP.getAssociatedValue()))
1494 return C;
1498 UsedAssumedInformation)) {
1499 if (Values.empty())
1500 return std::nullopt;
1501 if (auto *C = dyn_cast_or_null<Constant>(
1503 return C;
1504 }
1505 return nullptr;
1506}
1507
1509 const IRPosition &IRP, const AbstractAttribute *AA,
1510 bool &UsedAssumedInformation, AA::ValueScope S) {
1511 // First check all callbacks provided by outside AAs. If any of them returns
1512 // a non-null value that is different from the associated value, or
1513 // std::nullopt, we assume it's simplified.
1514 for (auto &CB : SimplificationCallbacks.lookup(IRP))
1515 return CB(IRP, AA, UsedAssumedInformation);
1516
1518 if (!getAssumedSimplifiedValues(IRP, AA, Values, S, UsedAssumedInformation))
1519 return &IRP.getAssociatedValue();
1520 if (Values.empty())
1521 return std::nullopt;
1522 if (AA)
1523 if (Value *V = AAPotentialValues::getSingleValue(*this, *AA, IRP, Values))
1524 return V;
1527 return nullptr;
1528 return &IRP.getAssociatedValue();
1529}
1530
1532 const IRPosition &InitialIRP, const AbstractAttribute *AA,
1534 bool &UsedAssumedInformation, bool RecurseForSelectAndPHI) {
1537 Worklist.push_back(InitialIRP);
1538 while (!Worklist.empty()) {
1539 const IRPosition &IRP = Worklist.pop_back_val();
1540
1541 // First check all callbacks provided by outside AAs. If any of them returns
1542 // a non-null value that is different from the associated value, or
1543 // std::nullopt, we assume it's simplified.
1544 int NV = Values.size();
1545 const auto &SimplificationCBs = SimplificationCallbacks.lookup(IRP);
1546 for (const auto &CB : SimplificationCBs) {
1547 std::optional<Value *> CBResult = CB(IRP, AA, UsedAssumedInformation);
1548 if (!CBResult.has_value())
1549 continue;
1550 Value *V = *CBResult;
1551 if (!V)
1552 return false;
1555 Values.push_back(AA::ValueAndContext{*V, nullptr});
1556 else
1557 return false;
1558 }
1559 if (SimplificationCBs.empty()) {
1560 // If no high-level/outside simplification occurred, use
1561 // AAPotentialValues.
1562 const auto *PotentialValuesAA =
1564 if (PotentialValuesAA &&
1565 PotentialValuesAA->getAssumedSimplifiedValues(*this, Values, S)) {
1566 UsedAssumedInformation |= !PotentialValuesAA->isAtFixpoint();
1567 } else if (IRP.getPositionKind() != IRPosition::IRP_RETURNED) {
1568 Values.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
1569 } else {
1570 // TODO: We could visit all returns and add the operands.
1571 return false;
1572 }
1573 }
1574
1575 if (!RecurseForSelectAndPHI)
1576 break;
1577
1578 for (int I = NV, E = Values.size(); I < E; ++I) {
1579 Value *V = Values[I].getValue();
1580 if (!isa<PHINode>(V) && !isa<SelectInst>(V))
1581 continue;
1582 if (!Seen.insert(V).second)
1583 continue;
1584 // Move the last element to this slot.
1585 Values[I] = Values[E - 1];
1586 // Eliminate the last slot, adjust the indices.
1587 Values.pop_back();
1588 --E;
1589 --I;
1590 // Add a new value (select or phi) to the worklist.
1591 Worklist.push_back(IRPosition::value(*V));
1592 }
1593 }
1594 return true;
1595}
1596
1598 std::optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,
1599 bool &UsedAssumedInformation) {
1600 if (!V)
1601 return V;
1602 if (*V == nullptr || isa<Constant>(*V))
1603 return V;
1604 if (auto *Arg = dyn_cast<Argument>(*V))
1605 if (CB.getCalledOperand() == Arg->getParent() &&
1606 CB.arg_size() > Arg->getArgNo())
1607 if (!Arg->hasPointeeInMemoryValueAttr())
1608 return getAssumedSimplified(
1609 IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,
1610 UsedAssumedInformation, AA::Intraprocedural);
1611 return nullptr;
1612}
1613
1615 // The abstract attributes are allocated via the BumpPtrAllocator Allocator,
1616 // thus we cannot delete them. We can, and want to, destruct them though.
1617 for (auto &It : AAMap) {
1618 AbstractAttribute *AA = It.getSecond();
1619 AA->~AbstractAttribute();
1620 }
1621}
1622
1624 const AAIsDead *FnLivenessAA,
1625 bool &UsedAssumedInformation,
1626 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1627 if (!Configuration.UseLiveness)
1628 return false;
1629 const IRPosition &IRP = AA.getIRPosition();
1630 if (!Functions.count(IRP.getAnchorScope()))
1631 return false;
1632 return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,
1633 CheckBBLivenessOnly, DepClass);
1634}
1635
1637 const AbstractAttribute *QueryingAA,
1638 const AAIsDead *FnLivenessAA,
1639 bool &UsedAssumedInformation,
1640 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1641 if (!Configuration.UseLiveness)
1642 return false;
1643 Instruction *UserI = dyn_cast<Instruction>(U.getUser());
1644 if (!UserI)
1645 return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
1646 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1647
1648 if (auto *CB = dyn_cast<CallBase>(UserI)) {
1649 // For call site argument uses we can check if the argument is
1650 // unused/dead.
1651 if (CB->isArgOperand(&U)) {
1652 const IRPosition &CSArgPos =
1653 IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
1654 return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
1655 UsedAssumedInformation, CheckBBLivenessOnly,
1656 DepClass);
1657 }
1658 } else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
1659 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
1660 return isAssumedDead(RetPos, QueryingAA, FnLivenessAA,
1661 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1662 } else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
1663 BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
1664 return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
1665 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1666 } else if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) {
1667 if (!CheckBBLivenessOnly && SI->getPointerOperand() != U.get()) {
1668 const IRPosition IRP = IRPosition::inst(*SI);
1669 const AAIsDead *IsDeadAA =
1671 if (IsDeadAA && IsDeadAA->isRemovableStore()) {
1672 if (QueryingAA)
1673 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1674 if (!IsDeadAA->isKnown(AAIsDead::IS_REMOVABLE))
1675 UsedAssumedInformation = true;
1676 return true;
1677 }
1678 }
1679 }
1680
1681 return isAssumedDead(IRPosition::inst(*UserI), QueryingAA, FnLivenessAA,
1682 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1683}
1684
1686 const AbstractAttribute *QueryingAA,
1687 const AAIsDead *FnLivenessAA,
1688 bool &UsedAssumedInformation,
1689 bool CheckBBLivenessOnly, DepClassTy DepClass,
1690 bool CheckForDeadStore) {
1691 if (!Configuration.UseLiveness)
1692 return false;
1693 const IRPosition::CallBaseContext *CBCtx =
1694 QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;
1695
1696 if (ManifestAddedBlocks.contains(I.getParent()))
1697 return false;
1698
1699 const Function &F = *I.getFunction();
1700 if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)
1701 FnLivenessAA = getOrCreateAAFor<AAIsDead>(IRPosition::function(F, CBCtx),
1702 QueryingAA, DepClassTy::NONE);
1703
1704 // Don't use recursive reasoning.
1705 if (!FnLivenessAA || QueryingAA == FnLivenessAA)
1706 return false;
1707
1708 // If we have a context instruction and a liveness AA we use it.
1709 if (CheckBBLivenessOnly ? FnLivenessAA->isAssumedDead(I.getParent())
1710 : FnLivenessAA->isAssumedDead(&I)) {
1711 if (QueryingAA)
1712 recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
1713 if (!FnLivenessAA->isKnownDead(&I))
1714 UsedAssumedInformation = true;
1715 return true;
1716 }
1717
1718 if (CheckBBLivenessOnly)
1719 return false;
1720
1721 const IRPosition IRP = IRPosition::inst(I, CBCtx);
1722 const AAIsDead *IsDeadAA =
1724
1725 // Don't use recursive reasoning.
1726 if (!IsDeadAA || QueryingAA == IsDeadAA)
1727 return false;
1728
1729 if (IsDeadAA->isAssumedDead()) {
1730 if (QueryingAA)
1731 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1732 if (!IsDeadAA->isKnownDead())
1733 UsedAssumedInformation = true;
1734 return true;
1735 }
1736
1737 if (CheckForDeadStore && isa<StoreInst>(I) && IsDeadAA->isRemovableStore()) {
1738 if (QueryingAA)
1739 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1740 if (!IsDeadAA->isKnownDead())
1741 UsedAssumedInformation = true;
1742 return true;
1743 }
1744
1745 return false;
1746}
1747
1749 const AbstractAttribute *QueryingAA,
1750 const AAIsDead *FnLivenessAA,
1751 bool &UsedAssumedInformation,
1752 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1753 if (!Configuration.UseLiveness)
1754 return false;
1755 // Don't check liveness for constants, e.g. functions, used as (floating)
1756 // values since the context instruction and such is here meaningless.
1759 return false;
1760 }
1761
1762 Instruction *CtxI = IRP.getCtxI();
1763 if (CtxI &&
1764 isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,
1765 /* CheckBBLivenessOnly */ true,
1766 CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
1767 return true;
1768
1769 if (CheckBBLivenessOnly)
1770 return false;
1771
1772 // If we haven't succeeded we query the specific liveness info for the IRP.
1773 const AAIsDead *IsDeadAA;
1775 IsDeadAA = getOrCreateAAFor<AAIsDead>(
1777 QueryingAA, DepClassTy::NONE);
1778 else
1779 IsDeadAA = getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);
1780
1781 // Don't use recursive reasoning.
1782 if (!IsDeadAA || QueryingAA == IsDeadAA)
1783 return false;
1784
1785 if (IsDeadAA->isAssumedDead()) {
1786 if (QueryingAA)
1787 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1788 if (!IsDeadAA->isKnownDead())
1789 UsedAssumedInformation = true;
1790 return true;
1791 }
1792
1793 return false;
1794}
1795
1797 const AbstractAttribute *QueryingAA,
1798 const AAIsDead *FnLivenessAA,
1799 DepClassTy DepClass) {
1800 if (!Configuration.UseLiveness)
1801 return false;
1802 const Function &F = *BB.getParent();
1803 if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)
1805 QueryingAA, DepClassTy::NONE);
1806
1807 // Don't use recursive reasoning.
1808 if (!FnLivenessAA || QueryingAA == FnLivenessAA)
1809 return false;
1810
1811 if (FnLivenessAA->isAssumedDead(&BB)) {
1812 if (QueryingAA)
1813 recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
1814 return true;
1815 }
1816
1817 return false;
1818}
1819
1822 const AbstractAttribute &QueryingAA, const CallBase &CB) {
1823 if (const Function *Callee = dyn_cast<Function>(CB.getCalledOperand()))
1824 return Pred(Callee);
1825
1826 const auto *CallEdgesAA = getAAFor<AACallEdges>(
1828 if (!CallEdgesAA || CallEdgesAA->hasUnknownCallee())
1829 return false;
1830
1831 const auto &Callees = CallEdgesAA->getOptimisticEdges();
1832 return Pred(Callees.getArrayRef());
1833}
1834
1835bool canMarkAsVisited(const User *Usr) {
1836 return isa<PHINode>(Usr) || !isa<Instruction>(Usr);
1837}
1838
1840 function_ref<bool(const Use &, bool &)> Pred,
1841 const AbstractAttribute &QueryingAA, const Value &V,
1842 bool CheckBBLivenessOnly, DepClassTy LivenessDepClass,
1843 bool IgnoreDroppableUses,
1844 function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB) {
1845
1846 // Check virtual uses first.
1847 for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&V))
1848 if (!CB(*this, &QueryingAA))
1849 return false;
1850
1851 if (isa<ConstantData>(V))
1852 return false;
1853
1854 // Check the trivial case first as it catches void values.
1855 if (V.use_empty())
1856 return true;
1857
1858 const IRPosition &IRP = QueryingAA.getIRPosition();
1861
1862 auto AddUsers = [&](const Value &V, const Use *OldUse) {
1863 for (const Use &UU : V.uses()) {
1864 if (OldUse && EquivalentUseCB && !EquivalentUseCB(*OldUse, UU)) {
1865 LLVM_DEBUG(dbgs() << "[Attributor] Potential copy was "
1866 "rejected by the equivalence call back: "
1867 << *UU << "!\n");
1868 return false;
1869 }
1870
1871 Worklist.push_back(&UU);
1872 }
1873 return true;
1874 };
1875
1876 AddUsers(V, /* OldUse */ nullptr);
1877
1878 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
1879 << " initial uses to check\n");
1880
1881 const Function *ScopeFn = IRP.getAnchorScope();
1882 const auto *LivenessAA =
1883 ScopeFn ? getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
1885 : nullptr;
1886
1887 while (!Worklist.empty()) {
1888 const Use *U = Worklist.pop_back_val();
1889 if (canMarkAsVisited(U->getUser()) && !Visited.insert(U).second)
1890 continue;
1892 if (auto *Fn = dyn_cast<Function>(U->getUser()))
1893 dbgs() << "[Attributor] Check use: " << **U << " in " << Fn->getName()
1894 << "\n";
1895 else
1896 dbgs() << "[Attributor] Check use: " << **U << " in " << *U->getUser()
1897 << "\n";
1898 });
1899 bool UsedAssumedInformation = false;
1900 if (isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,
1901 CheckBBLivenessOnly, LivenessDepClass)) {
1903 dbgs() << "[Attributor] Dead use, skip!\n");
1904 continue;
1905 }
1906 if (IgnoreDroppableUses && U->getUser()->isDroppable()) {
1908 dbgs() << "[Attributor] Droppable user, skip!\n");
1909 continue;
1910 }
1911
1912 if (auto *SI = dyn_cast<StoreInst>(U->getUser())) {
1913 if (&SI->getOperandUse(0) == U) {
1914 if (!Visited.insert(U).second)
1915 continue;
1916 SmallSetVector<Value *, 4> PotentialCopies;
1918 *this, *SI, PotentialCopies, QueryingAA, UsedAssumedInformation,
1919 /* OnlyExact */ true)) {
1921 dbgs()
1922 << "[Attributor] Value is stored, continue with "
1923 << PotentialCopies.size()
1924 << " potential copies instead!\n");
1925 for (Value *PotentialCopy : PotentialCopies)
1926 if (!AddUsers(*PotentialCopy, U))
1927 return false;
1928 continue;
1929 }
1930 }
1931 }
1932
1933 bool Follow = false;
1934 if (!Pred(*U, Follow))
1935 return false;
1936 if (!Follow)
1937 continue;
1938
1939 User &Usr = *U->getUser();
1940 AddUsers(Usr, /* OldUse */ nullptr);
1941 }
1942
1943 return true;
1944}
1945
1947 const AbstractAttribute &QueryingAA,
1948 bool RequireAllCallSites,
1949 bool &UsedAssumedInformation) {
1950 // We can try to determine information from
1951 // the call sites. However, this is only possible all call sites are known,
1952 // hence the function has internal linkage.
1953 const IRPosition &IRP = QueryingAA.getIRPosition();
1954 const Function *AssociatedFunction = IRP.getAssociatedFunction();
1955 if (!AssociatedFunction) {
1956 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
1957 << "\n");
1958 return false;
1959 }
1960
1961 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
1962 &QueryingAA, UsedAssumedInformation);
1963}
1964
1966 const Function &Fn,
1967 bool RequireAllCallSites,
1968 const AbstractAttribute *QueryingAA,
1969 bool &UsedAssumedInformation,
1970 bool CheckPotentiallyDead) {
1971 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
1972 LLVM_DEBUG(
1973 dbgs()
1974 << "[Attributor] Function " << Fn.getName()
1975 << " has no internal linkage, hence not all call sites are known\n");
1976 return false;
1977 }
1978 // Check virtual uses first.
1979 for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&Fn))
1980 if (!CB(*this, QueryingAA))
1981 return false;
1982
1984 for (unsigned u = 0; u < Uses.size(); ++u) {
1985 const Use &U = *Uses[u];
1987 if (auto *Fn = dyn_cast<Function>(U))
1988 dbgs() << "[Attributor] Check use: " << Fn->getName() << " in "
1989 << *U.getUser() << "\n";
1990 else
1991 dbgs() << "[Attributor] Check use: " << *U << " in " << *U.getUser()
1992 << "\n";
1993 });
1994 if (!CheckPotentiallyDead &&
1995 isAssumedDead(U, QueryingAA, nullptr, UsedAssumedInformation,
1996 /* CheckBBLivenessOnly */ true)) {
1998 dbgs() << "[Attributor] Dead use, skip!\n");
1999 continue;
2000 }
2001 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
2002 if (CE->isCast() && CE->getType()->isPointerTy()) {
2004 dbgs() << "[Attributor] Use, is constant cast expression, add "
2005 << CE->getNumUses() << " uses of that expression instead!\n";
2006 });
2007 for (const Use &CEU : CE->uses())
2008 Uses.push_back(&CEU);
2009 continue;
2010 }
2011 }
2012
2013 AbstractCallSite ACS(&U);
2014 if (!ACS) {
2015 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
2016 << " has non call site use " << *U.get() << " in "
2017 << *U.getUser() << "\n");
2018 return false;
2019 }
2020
2021 const Use *EffectiveUse =
2022 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
2023 if (!ACS.isCallee(EffectiveUse)) {
2024 if (!RequireAllCallSites) {
2025 LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()
2026 << " is not a call of " << Fn.getName()
2027 << ", skip use\n");
2028 continue;
2029 }
2030 LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()
2031 << " is an invalid use of " << Fn.getName() << "\n");
2032 return false;
2033 }
2034
2035 // Make sure the arguments that can be matched between the call site and the
2036 // callee argee on their type. It is unlikely they do not and it doesn't
2037 // make sense for all attributes to know/care about this.
2038 assert(&Fn == ACS.getCalledFunction() && "Expected known callee");
2039 unsigned MinArgsParams =
2040 std::min(size_t(ACS.getNumArgOperands()), Fn.arg_size());
2041 for (unsigned u = 0; u < MinArgsParams; ++u) {
2042 Value *CSArgOp = ACS.getCallArgOperand(u);
2043 if (CSArgOp && Fn.getArg(u)->getType() != CSArgOp->getType()) {
2044 LLVM_DEBUG(
2045 dbgs() << "[Attributor] Call site / callee argument type mismatch ["
2046 << u << "@" << Fn.getName() << ": "
2047 << *Fn.getArg(u)->getType() << " vs. "
2048 << *ACS.getCallArgOperand(u)->getType() << "\n");
2049 return false;
2050 }
2051 }
2052
2053 if (Pred(ACS))
2054 continue;
2055
2056 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
2057 << *ACS.getInstruction() << "\n");
2058 return false;
2059 }
2060
2061 return true;
2062}
2063
2064bool Attributor::shouldPropagateCallBaseContext(const IRPosition &IRP) {
2065 // TODO: Maintain a cache of Values that are
2066 // on the pathway from a Argument to a Instruction that would effect the
2067 // liveness/return state etc.
2069}
2070
2072 const AbstractAttribute &QueryingAA,
2074 bool RecurseForSelectAndPHI) {
2075
2076 const IRPosition &IRP = QueryingAA.getIRPosition();
2077 const Function *AssociatedFunction = IRP.getAssociatedFunction();
2078 if (!AssociatedFunction)
2079 return false;
2080
2081 bool UsedAssumedInformation = false;
2084 IRPosition::returned(*AssociatedFunction), &QueryingAA, Values, S,
2085 UsedAssumedInformation, RecurseForSelectAndPHI))
2086 return false;
2087
2088 return llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
2089 return Pred(*VAC.getValue());
2090 });
2091}
2092
2095 function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,
2096 const AAIsDead *LivenessAA, ArrayRef<unsigned> Opcodes,
2097 bool &UsedAssumedInformation, bool CheckBBLivenessOnly = false,
2098 bool CheckPotentiallyDead = false) {
2099 for (unsigned Opcode : Opcodes) {
2100 // Check if we have instructions with this opcode at all first.
2101 auto *Insts = OpcodeInstMap[Opcode];
2102 if (!Insts)
2103 continue;
2104
2105 for (Instruction *I : *Insts) {
2106 // Skip dead instructions.
2107 if (A && !CheckPotentiallyDead &&
2108 A->isAssumedDead(IRPosition::inst(*I), QueryingAA, LivenessAA,
2109 UsedAssumedInformation, CheckBBLivenessOnly)) {
2111 dbgs() << "[Attributor] Instruction " << *I
2112 << " is potentially dead, skip!\n";);
2113 continue;
2114 }
2115
2116 if (!Pred(*I))
2117 return false;
2118 }
2119 }
2120 return true;
2121}
2122
2124 const Function *Fn,
2125 const AbstractAttribute *QueryingAA,
2126 ArrayRef<unsigned> Opcodes,
2127 bool &UsedAssumedInformation,
2128 bool CheckBBLivenessOnly,
2129 bool CheckPotentiallyDead) {
2130 // Since we need to provide instructions we have to have an exact definition.
2131 if (!Fn || Fn->isDeclaration())
2132 return false;
2133
2134 const IRPosition &QueryIRP = IRPosition::function(*Fn);
2135 const auto *LivenessAA =
2136 CheckPotentiallyDead && QueryingAA
2137 ? (getAAFor<AAIsDead>(*QueryingAA, QueryIRP, DepClassTy::NONE))
2138 : nullptr;
2139
2140 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
2141 if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, QueryingAA,
2142 LivenessAA, Opcodes, UsedAssumedInformation,
2143 CheckBBLivenessOnly, CheckPotentiallyDead))
2144 return false;
2145
2146 return true;
2147}
2148
2150 const AbstractAttribute &QueryingAA,
2151 ArrayRef<unsigned> Opcodes,
2152 bool &UsedAssumedInformation,
2153 bool CheckBBLivenessOnly,
2154 bool CheckPotentiallyDead) {
2155 const IRPosition &IRP = QueryingAA.getIRPosition();
2156 const Function *AssociatedFunction = IRP.getAssociatedFunction();
2157 return checkForAllInstructions(Pred, AssociatedFunction, &QueryingAA, Opcodes,
2158 UsedAssumedInformation, CheckBBLivenessOnly,
2159 CheckPotentiallyDead);
2160}
2161
2163 function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA,
2164 bool &UsedAssumedInformation) {
2165 TimeTraceScope TS("checkForAllReadWriteInstructions");
2166
2167 const Function *AssociatedFunction =
2168 QueryingAA.getIRPosition().getAssociatedFunction();
2169 if (!AssociatedFunction)
2170 return false;
2171
2172 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
2173 const auto *LivenessAA =
2174 getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE);
2175
2176 for (Instruction *I :
2177 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
2178 // Skip dead instructions.
2179 if (isAssumedDead(IRPosition::inst(*I), &QueryingAA, LivenessAA,
2180 UsedAssumedInformation))
2181 continue;
2182
2183 if (!Pred(*I))
2184 return false;
2185 }
2186
2187 return true;
2188}
2189
2190void Attributor::runTillFixpoint() {
2191 TimeTraceScope TimeScope("Attributor::runTillFixpoint");
2192 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
2193 << DG.SyntheticRoot.Deps.size()
2194 << " abstract attributes.\n");
2195
2196 // Now that all abstract attributes are collected and initialized we start
2197 // the abstract analysis.
2198
2199 unsigned IterationCounter = 1;
2200 unsigned MaxIterations =
2201 Configuration.MaxFixpointIterations.value_or(SetFixpointIterations);
2202
2204 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
2205 Worklist.reserve(DG.SyntheticRoot.Deps.size());
2206 Worklist.insert_range(DG.SyntheticRoot);
2207
2208 do {
2209 // Remember the size to determine new attributes.
2210 size_t NumAAs = DG.SyntheticRoot.Deps.size();
2211 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
2212 << ", Worklist size: " << Worklist.size() << "\n");
2213
2214 // For invalid AAs we can fix dependent AAs that have a required dependence,
2215 // thereby folding long dependence chains in a single step without the need
2216 // to run updates.
2217 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
2218 AbstractAttribute *InvalidAA = InvalidAAs[u];
2219
2220 // Check the dependences to fast track invalidation.
2222 dbgs() << "[Attributor] InvalidAA: " << *InvalidAA
2223 << " has " << InvalidAA->Deps.size()
2224 << " required & optional dependences\n");
2225 for (auto &DepIt : InvalidAA->Deps) {
2226 AbstractAttribute *DepAA = cast<AbstractAttribute>(DepIt.getPointer());
2227 if (DepIt.getInt() == unsigned(DepClassTy::OPTIONAL)) {
2229 dbgs() << " - recompute: " << *DepAA);
2230 Worklist.insert(DepAA);
2231 continue;
2232 }
2234 << " - invalidate: " << *DepAA);
2236 assert(DepAA->getState().isAtFixpoint() && "Expected fixpoint state!");
2237 if (!DepAA->getState().isValidState())
2238 InvalidAAs.insert(DepAA);
2239 else
2240 ChangedAAs.push_back(DepAA);
2241 }
2242 InvalidAA->Deps.clear();
2243 }
2244
2245 // Add all abstract attributes that are potentially dependent on one that
2246 // changed to the work list.
2247 for (AbstractAttribute *ChangedAA : ChangedAAs) {
2248 for (auto &DepIt : ChangedAA->Deps)
2249 Worklist.insert(cast<AbstractAttribute>(DepIt.getPointer()));
2250 ChangedAA->Deps.clear();
2251 }
2252
2253 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
2254 << ", Worklist+Dependent size: " << Worklist.size()
2255 << "\n");
2256
2257 // Reset the changed and invalid set.
2258 ChangedAAs.clear();
2259 InvalidAAs.clear();
2260
2261 // Update all abstract attribute in the work list and record the ones that
2262 // changed.
2263 for (AbstractAttribute *AA : Worklist) {
2264 if (!AA->isStateAtFixpoint())
2265 if (updateAA(*AA) == ChangeStatus::CHANGED)
2266 ChangedAAs.push_back(AA);
2267
2268 // Use the InvalidAAs vector to propagate invalid states fast transitively
2269 // without requiring updates.
2270 if (!AA->getState().isValidState())
2271 InvalidAAs.insert(AA);
2272 }
2273
2274 // Add attributes to the changed set if they have been created in the last
2275 // iteration.
2276 ChangedAAs.append(DG.SyntheticRoot.begin() + NumAAs,
2277 DG.SyntheticRoot.end());
2278
2279 // Reset the work list and repopulate with the changed abstract attributes.
2280 // Note that dependent ones are added above.
2281 Worklist.clear();
2282 Worklist.insert_range(ChangedAAs);
2283 Worklist.insert_range(QueryAAsAwaitingUpdate);
2284 QueryAAsAwaitingUpdate.clear();
2285
2286 } while (!Worklist.empty() && (IterationCounter++ < MaxIterations));
2287
2288 if (IterationCounter > MaxIterations && !Functions.empty()) {
2289 auto Remark = [&](OptimizationRemarkMissed ORM) {
2290 return ORM << "Attributor did not reach a fixpoint after "
2291 << ore::NV("Iterations", MaxIterations) << " iterations.";
2292 };
2293 Function *F = Functions.front();
2295 }
2296
2297 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
2298 << IterationCounter << "/" << MaxIterations
2299 << " iterations\n");
2300
2301 // Reset abstract arguments not settled in a sound fixpoint by now. This
2302 // happens when we stopped the fixpoint iteration early. Note that only the
2303 // ones marked as "changed" *and* the ones transitively depending on them
2304 // need to be reverted to a pessimistic state. Others might not be in a
2305 // fixpoint state but we can use the optimistic results for them anyway.
2306 SmallPtrSet<AbstractAttribute *, 32> Visited;
2307 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
2308 AbstractAttribute *ChangedAA = ChangedAAs[u];
2309 if (!Visited.insert(ChangedAA).second)
2310 continue;
2311
2312 AbstractState &State = ChangedAA->getState();
2313 if (!State.isAtFixpoint()) {
2315
2316 NumAttributesTimedOut++;
2317 }
2318
2319 for (auto &DepIt : ChangedAA->Deps)
2320 ChangedAAs.push_back(cast<AbstractAttribute>(DepIt.getPointer()));
2321 ChangedAA->Deps.clear();
2322 }
2323
2324 LLVM_DEBUG({
2325 if (!Visited.empty())
2326 dbgs() << "\n[Attributor] Finalized " << Visited.size()
2327 << " abstract attributes.\n";
2328 });
2329}
2330
2332 assert(AA.isQueryAA() &&
2333 "Non-query AAs should not be required to register for updates!");
2334 QueryAAsAwaitingUpdate.insert(&AA);
2335}
2336
2337ChangeStatus Attributor::manifestAttributes() {
2338 TimeTraceScope TimeScope("Attributor::manifestAttributes");
2339 size_t NumFinalAAs = DG.SyntheticRoot.Deps.size();
2340
2341 unsigned NumManifested = 0;
2342 unsigned NumAtFixpoint = 0;
2343 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
2344 for (auto &DepAA : DG.SyntheticRoot.Deps) {
2345 AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
2346 AbstractState &State = AA->getState();
2347
2348 // If there is not already a fixpoint reached, we can now take the
2349 // optimistic state. This is correct because we enforced a pessimistic one
2350 // on abstract attributes that were transitively dependent on a changed one
2351 // already above.
2352 if (!AA->isStateAtFixpoint())
2353 State.indicateOptimisticFixpoint();
2354
2355 // We must not manifest Attributes that use Callbase info.
2356 if (AA->hasCallBaseContext())
2357 continue;
2358 // If the state is invalid, we do not try to manifest it.
2359 if (!State.isValidState())
2360 continue;
2361
2362 if (AA->getCtxI() && !isRunOn(*AA->getAnchorScope()))
2363 continue;
2364
2365 // Skip dead code.
2366 bool UsedAssumedInformation = false;
2367 if (isAssumedDead(*AA, nullptr, UsedAssumedInformation,
2368 /* CheckBBLivenessOnly */ true))
2369 continue;
2370 // Check if the manifest debug counter that allows skipping manifestation of
2371 // AAs
2372 if (!DebugCounter::shouldExecute(ManifestDBGCounter))
2373 continue;
2374 // Manifest the state and record if we changed the IR.
2375 ChangeStatus LocalChange = AA->manifest(*this);
2376 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
2377 AA->trackStatistics();
2378 LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA
2379 << "\n");
2380
2381 ManifestChange = ManifestChange | LocalChange;
2382
2383 NumAtFixpoint++;
2384 NumManifested += (LocalChange == ChangeStatus::CHANGED);
2385 }
2386
2387 (void)NumManifested;
2388 (void)NumAtFixpoint;
2389 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
2390 << " arguments while " << NumAtFixpoint
2391 << " were in a valid fixpoint state\n");
2392
2393 NumAttributesManifested += NumManifested;
2394 NumAttributesValidFixpoint += NumAtFixpoint;
2395
2396 (void)NumFinalAAs;
2397 if (NumFinalAAs != DG.SyntheticRoot.Deps.size()) {
2398 auto DepIt = DG.SyntheticRoot.Deps.begin();
2399 for (unsigned u = 0; u < NumFinalAAs; ++u)
2400 ++DepIt;
2401 for (unsigned u = NumFinalAAs; u < DG.SyntheticRoot.Deps.size();
2402 ++u, ++DepIt) {
2403 errs() << "Unexpected abstract attribute: "
2404 << cast<AbstractAttribute>(DepIt->getPointer()) << " :: "
2405 << cast<AbstractAttribute>(DepIt->getPointer())
2406 ->getIRPosition()
2407 .getAssociatedValue()
2408 << "\n";
2409 }
2410 llvm_unreachable("Expected the final number of abstract attributes to "
2411 "remain unchanged!");
2412 }
2413
2414 for (auto &It : AttrsMap) {
2415 AttributeList &AL = It.getSecond();
2416 const IRPosition &IRP =
2417 isa<Function>(It.getFirst())
2418 ? IRPosition::function(*cast<Function>(It.getFirst()))
2419 : IRPosition::callsite_function(*cast<CallBase>(It.getFirst()));
2420 if (IRP.getAttrList() == AL)
2421 continue;
2422 IRP.setAttrList(AL);
2423 AttrModifiedFunctions.insert(IRP.getAnchorScope());
2424 }
2425
2426 return ManifestChange;
2427}
2428
2429void Attributor::identifyDeadInternalFunctions() {
2430 // Early exit if we don't intend to delete functions.
2431 if (!Configuration.DeleteFns)
2432 return;
2433
2434 // To avoid triggering an assertion in the lazy call graph we will not delete
2435 // any internal library functions. We should modify the assertion though and
2436 // allow internals to be deleted.
2437 const auto *TLI =
2438 isModulePass()
2439 ? nullptr
2440 : getInfoCache().getTargetLibraryInfoForFunction(*Functions.back());
2441
2442 // Identify dead internal functions and delete them. This happens outside
2443 // the other fixpoint analysis as we might treat potentially dead functions
2444 // as live to lower the number of iterations. If they happen to be dead, the
2445 // below fixpoint loop will identify and eliminate them.
2446
2447 SmallVector<Function *, 8> InternalFns;
2448 for (Function *F : Functions)
2449 if (F->hasLocalLinkage() &&
2450 (isModulePass() || TLI->getLibFunc(*F) == NotLibFunc))
2451 InternalFns.push_back(F);
2452
2453 SmallPtrSet<Function *, 8> LiveInternalFns;
2454 bool FoundLiveInternal = true;
2455 while (FoundLiveInternal) {
2456 FoundLiveInternal = false;
2457 for (Function *&F : InternalFns) {
2458 if (!F)
2459 continue;
2460
2461 bool UsedAssumedInformation = false;
2463 [&](AbstractCallSite ACS) {
2465 return ToBeDeletedFunctions.count(Callee) ||
2466 (Functions.count(Callee) && Callee->hasLocalLinkage() &&
2467 !LiveInternalFns.count(Callee));
2468 },
2469 *F, true, nullptr, UsedAssumedInformation)) {
2470 continue;
2471 }
2472
2473 LiveInternalFns.insert(F);
2474 F = nullptr;
2475 FoundLiveInternal = true;
2476 }
2477 }
2478
2479 for (Function *F : InternalFns)
2480 if (F)
2481 ToBeDeletedFunctions.insert(F);
2482}
2483
2484ChangeStatus Attributor::cleanupIR() {
2485 TimeTraceScope TimeScope("Attributor::cleanupIR");
2486 // Delete stuff at the end to avoid invalid references and a nice order.
2487 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete/replace at least "
2488 << ToBeDeletedFunctions.size() << " functions and "
2489 << ToBeDeletedBlocks.size() << " blocks and "
2490 << ToBeDeletedInsts.size() << " instructions and "
2491 << ToBeChangedValues.size() << " values and "
2492 << ToBeChangedUses.size() << " uses. To insert "
2493 << ToBeChangedToUnreachableInsts.size()
2494 << " unreachables.\n"
2495 << "Preserve manifest added " << ManifestAddedBlocks.size()
2496 << " blocks\n");
2497
2499 SmallVector<Instruction *, 32> TerminatorsToFold;
2500
2501 auto ReplaceUse = [&](Use *U, Value *NewV) {
2502 Value *OldV = U->get();
2503
2504 // If we plan to replace NewV we need to update it at this point.
2505 do {
2506 const auto &Entry = ToBeChangedValues.lookup(NewV);
2507 if (!get<0>(Entry))
2508 break;
2509 NewV = get<0>(Entry);
2510 } while (true);
2511
2512 Instruction *I = dyn_cast<Instruction>(U->getUser());
2513 assert((!I || isRunOn(*I->getFunction())) &&
2514 "Cannot replace an instruction outside the current SCC!");
2515
2516 // Do not replace uses in returns if the value is a must-tail call we will
2517 // not delete.
2518 if (auto *RI = dyn_cast_or_null<ReturnInst>(I)) {
2519 if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))
2520 if (CI->isMustTailCall() && !ToBeDeletedInsts.count(CI))
2521 return;
2522 // If we rewrite a return and the new value is not an argument, strip the
2523 // `returned` attribute as it is wrong now.
2524 if (!isa<Argument>(NewV))
2525 for (auto &Arg : RI->getFunction()->args())
2526 Arg.removeAttr(Attribute::Returned);
2527 }
2528
2529 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
2530 << " instead of " << *OldV << "\n");
2531 U->set(NewV);
2532
2533 // The new value may reference a function, e.g., if an argument is replaced
2534 // by a function pointer, so the call graph of the user's function changes.
2535 if (I) {
2536 CGModifiedFunctions.insert(I->getFunction());
2537 if (auto *C = dyn_cast<Constant>(NewV))
2538 Configuration.CGUpdater.addReferences(*I->getFunction(), *C);
2539 }
2540 if (Instruction *OldI = dyn_cast<Instruction>(OldV)) {
2541 if (!isa<PHINode>(OldI) && !ToBeDeletedInsts.count(OldI) &&
2543 DeadInsts.push_back(OldI);
2544 }
2545 if (isa<UndefValue>(NewV) && isa<CallBase>(U->getUser())) {
2546 auto *CB = cast<CallBase>(U->getUser());
2547 if (CB->isArgOperand(U)) {
2548 unsigned Idx = CB->getArgOperandNo(U);
2549 // Drop all attributes that make passing undef UB, e.g., dereferenceable
2550 // implies noundef.
2551 AttributeMask UBImplying = AttributeFuncs::getUBImplyingAttributes();
2552 CB->removeParamAttrs(Idx, UBImplying);
2553 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
2554 if (Callee && Callee->arg_size() > Idx)
2555 Callee->removeParamAttrs(Idx, UBImplying);
2556 }
2557 }
2558 if (isa<Constant>(NewV) && isa<CondBrInst>(U->getUser())) {
2559 Instruction *UserI = cast<Instruction>(U->getUser());
2560 if (isa<UndefValue>(NewV)) {
2561 ToBeChangedToUnreachableInsts.insert(UserI);
2562 } else {
2563 TerminatorsToFold.push_back(UserI);
2564 }
2565 }
2566 };
2567
2568 for (auto &It : ToBeChangedUses) {
2569 Use *U = It.first;
2570 Value *NewV = It.second;
2571 ReplaceUse(U, NewV);
2572 }
2573
2575 for (auto &It : ToBeChangedValues) {
2576 Value *OldV = It.first;
2577 auto [NewV, Done] = It.second;
2578 Uses.clear();
2579 for (auto &U : OldV->uses())
2580 if (Done || !U.getUser()->isDroppable())
2581 Uses.push_back(&U);
2582 for (Use *U : Uses) {
2583 if (auto *I = dyn_cast<Instruction>(U->getUser()))
2584 if (!isRunOn(*I->getFunction()))
2585 continue;
2586 ReplaceUse(U, NewV);
2587 }
2588 }
2589
2590 for (const auto &V : InvokeWithDeadSuccessor)
2591 if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
2592 assert(isRunOn(*II->getFunction()) &&
2593 "Cannot replace an invoke outside the current SCC!");
2594 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
2595 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
2596 bool Invoke2CallAllowed =
2598 assert((UnwindBBIsDead || NormalBBIsDead) &&
2599 "Invoke does not have dead successors!");
2600 BasicBlock *BB = II->getParent();
2601 BasicBlock *NormalDestBB = II->getNormalDest();
2602 if (UnwindBBIsDead) {
2603 Instruction *NormalNextIP = &NormalDestBB->front();
2604 if (Invoke2CallAllowed) {
2606 NormalNextIP = BB->getTerminator();
2607 }
2608 if (NormalBBIsDead)
2609 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
2610 } else {
2611 assert(NormalBBIsDead && "Broken invariant!");
2612 if (!NormalDestBB->getUniquePredecessor())
2613 NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2614 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
2615 }
2616 }
2617 for (Instruction *I : TerminatorsToFold) {
2618 assert(isRunOn(*I->getFunction()) &&
2619 "Cannot replace a terminator outside the current SCC!");
2620 CGModifiedFunctions.insert(I->getFunction());
2621 ConstantFoldTerminator(I->getParent());
2622 }
2623 for (const auto &V : ToBeChangedToUnreachableInsts)
2624 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
2625 LLVM_DEBUG(dbgs() << "[Attributor] Change to unreachable: " << *I
2626 << "\n");
2627 assert(isRunOn(*I->getFunction()) &&
2628 "Cannot replace an instruction outside the current SCC!");
2629 CGModifiedFunctions.insert(I->getFunction());
2631 }
2632
2633 for (const auto &V : ToBeDeletedInsts) {
2634 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
2636 isRunOn(*I->getFunction())) &&
2637 "Cannot delete an instruction outside the current SCC!");
2638 I->dropDroppableUses();
2639 CGModifiedFunctions.insert(I->getFunction());
2640 if (!I->getType()->isVoidTy())
2641 I->replaceAllUsesWith(UndefValue::get(I->getType()));
2643 DeadInsts.push_back(I);
2644 else
2645 I->eraseFromParent();
2646 }
2647 }
2648
2649 llvm::erase_if(DeadInsts, [&](WeakTrackingVH I) { return !I; });
2650
2651 LLVM_DEBUG({
2652 dbgs() << "[Attributor] DeadInsts size: " << DeadInsts.size() << "\n";
2653 for (auto &I : DeadInsts)
2654 if (I)
2655 dbgs() << " - " << *I << "\n";
2656 });
2657
2659
2660 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
2661 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
2662 ToBeDeletedBBs.reserve(NumDeadBlocks);
2663 for (BasicBlock *BB : ToBeDeletedBlocks) {
2664 assert(isRunOn(*BB->getParent()) &&
2665 "Cannot delete a block outside the current SCC!");
2666 CGModifiedFunctions.insert(BB->getParent());
2667 // Do not delete BBs added during manifests of AAs.
2668 if (ManifestAddedBlocks.contains(BB))
2669 continue;
2670 ToBeDeletedBBs.push_back(BB);
2671 }
2672 // Actually we do not delete the blocks but squash them into a single
2673 // unreachable but untangling branches that jump here is something we need
2674 // to do in a more generic way.
2675 detachDeadBlocks(ToBeDeletedBBs, nullptr);
2676 }
2677
2678 identifyDeadInternalFunctions();
2679
2680 // Rewrite the functions as requested during manifest.
2681 ChangeStatus ManifestChange = rewriteFunctionSignatures(CGModifiedFunctions);
2682
2683 for (Function *Fn : CGModifiedFunctions)
2684 if (!ToBeDeletedFunctions.count(Fn) && Functions.count(Fn))
2685 Configuration.CGUpdater.reanalyzeFunction(*Fn);
2686
2687 for (Function *Fn : ToBeDeletedFunctions) {
2688 if (!Functions.count(Fn))
2689 continue;
2690 Configuration.CGUpdater.removeFunction(*Fn);
2691 }
2692
2693 if (!ToBeChangedUses.empty())
2694 ManifestChange = ChangeStatus::CHANGED;
2695
2696 if (!ToBeChangedToUnreachableInsts.empty())
2697 ManifestChange = ChangeStatus::CHANGED;
2698
2699 if (!ToBeDeletedFunctions.empty())
2700 ManifestChange = ChangeStatus::CHANGED;
2701
2702 if (!ToBeDeletedBlocks.empty())
2703 ManifestChange = ChangeStatus::CHANGED;
2704
2705 if (!ToBeDeletedInsts.empty())
2706 ManifestChange = ChangeStatus::CHANGED;
2707
2708 if (!InvokeWithDeadSuccessor.empty())
2709 ManifestChange = ChangeStatus::CHANGED;
2710
2711 if (!DeadInsts.empty())
2712 ManifestChange = ChangeStatus::CHANGED;
2713
2714 NumFnDeleted += ToBeDeletedFunctions.size();
2715
2716 LLVM_DEBUG(dbgs() << "[Attributor] Deleted " << ToBeDeletedFunctions.size()
2717 << " functions after manifest.\n");
2718
2719#ifdef EXPENSIVE_CHECKS
2720 for (Function *F : Functions) {
2721 if (ToBeDeletedFunctions.count(F))
2722 continue;
2723 assert(!verifyFunction(*F, &errs()) && "Module verification failed!");
2724 }
2725#endif
2726
2727 return ManifestChange;
2728}
2729
2731 TimeTraceScope TimeScope("Attributor::run");
2732 AttributorCallGraph ACallGraph(*this);
2733
2734 if (PrintCallGraph)
2735 ACallGraph.populateAll();
2736
2737 Phase = AttributorPhase::UPDATE;
2738 runTillFixpoint();
2739
2740 // dump graphs on demand
2741 if (DumpDepGraph)
2742 DG.dumpGraph();
2743
2744 if (ViewDepGraph)
2745 DG.viewGraph();
2746
2748 DG.print();
2749
2750 Phase = AttributorPhase::MANIFEST;
2751 ChangeStatus ManifestChange = manifestAttributes();
2752
2753 Phase = AttributorPhase::CLEANUP;
2754 ChangeStatus CleanupChange = cleanupIR();
2755
2756 if (PrintCallGraph)
2757 ACallGraph.print();
2758
2759 return ManifestChange | CleanupChange;
2760}
2761
2762ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {
2763 std::optional<TimeTraceScope> TimeScope;
2764 if (TimeTraceEnabled) {
2765 TimeScope.emplace("updateAA", [&]() {
2766 return AA.getName().str() +
2767 std::to_string(AA.getIRPosition().getPositionKind());
2768 });
2769 }
2770
2771 assert(Phase == AttributorPhase::UPDATE &&
2772 "We can update AA only in the update stage!");
2773
2774 // Use a new dependence vector for this update.
2775 DependenceVector DV;
2776 DependenceStack.push_back(&DV);
2777
2778 auto &AAState = AA.getState();
2780 bool UsedAssumedInformation = false;
2781 if (!isAssumedDead(AA, nullptr, UsedAssumedInformation,
2782 /* CheckBBLivenessOnly */ true))
2783 CS = AA.update(*this);
2784
2785 if (!AA.isQueryAA() && DV.empty() && !AA.isStateAtFixpoint()) {
2786 // If the AA did not rely on outside information but changed, we run it
2787 // again to see if it found a fixpoint. Most AAs do but we don't require
2788 // them to. Hence, it might take the AA multiple iterations to get to a
2789 // fixpoint even if it does not rely on outside information, which is fine.
2791 if (CS == ChangeStatus::CHANGED)
2792 RerunCS = AA.update(*this);
2793
2794 // If the attribute did not change during the run or rerun, and it still did
2795 // not query any non-fix information, the state will not change and we can
2796 // indicate that right at this point.
2797 if (RerunCS == ChangeStatus::UNCHANGED && !AA.isQueryAA() && DV.empty())
2798 AAState.indicateOptimisticFixpoint();
2799 }
2800
2801 if (!AA.isStateAtFixpoint())
2802 rememberDependences();
2803
2804 // Verify the stack was used properly, that is we pop the dependence vector we
2805 // put there earlier.
2806 DependenceVector *PoppedDV = DependenceStack.pop_back_val();
2807 (void)PoppedDV;
2808 assert(PoppedDV == &DV && "Inconsistent usage of the dependence stack!");
2809
2810 return CS;
2811}
2812
2814 assert(!F.isDeclaration() && "Cannot create a wrapper around a declaration!");
2815
2816 Module &M = *F.getParent();
2817 LLVMContext &Ctx = M.getContext();
2818 FunctionType *FnTy = F.getFunctionType();
2819
2820 Function *Wrapper =
2821 Function::Create(FnTy, F.getLinkage(), F.getAddressSpace(), F.getName());
2822 F.setName(""); // set the inside function anonymous
2823 M.getFunctionList().insert(F.getIterator(), Wrapper);
2824
2825 F.setLinkage(GlobalValue::InternalLinkage);
2826
2827 F.replaceAllUsesWith(Wrapper);
2828 assert(F.use_empty() && "Uses remained after wrapper was created!");
2829
2830 // Move the COMDAT section to the wrapper.
2831 // TODO: Check if we need to keep it for F as well.
2832 Wrapper->setComdat(F.getComdat());
2833 F.setComdat(nullptr);
2834
2835 // Copy all metadata and attributes but keep them on F as well.
2837 F.getAllMetadata(MDs);
2838 for (auto MDIt : MDs)
2839 Wrapper->addMetadata(MDIt.first, *MDIt.second);
2840 Wrapper->setAttributes(F.getAttributes());
2841
2842 // Create the call in the wrapper.
2843 BasicBlock *EntryBB = BasicBlock::Create(Ctx, "entry", Wrapper);
2844
2846 Argument *FArgIt = F.arg_begin();
2847 for (Argument &Arg : Wrapper->args()) {
2848 Args.push_back(&Arg);
2849 Arg.setName((FArgIt++)->getName());
2850 }
2851
2852 CallInst *CI = CallInst::Create(&F, Args, "", EntryBB);
2853 CI->setTailCall(true);
2854 CI->addFnAttr(Attribute::NoInline);
2855 ReturnInst::Create(Ctx, CI->getType()->isVoidTy() ? nullptr : CI, EntryBB);
2856
2857 NumFnShallowWrappersCreated++;
2858}
2859
2861 if (F.isDeclaration() || F.hasLocalLinkage() ||
2863 return false;
2864 return true;
2865}
2866
2868 if (!AllowDeepWrapper && !Force)
2869 return nullptr;
2870 if (!isInternalizable(F))
2871 return nullptr;
2872
2873 SmallPtrSet<Function *, 2> FnSet = {&F};
2874 DenseMap<Function *, Function *> InternalizedFns;
2875 internalizeFunctions(FnSet, InternalizedFns);
2876
2877 return InternalizedFns[&F];
2878}
2879
2882 for (Function *F : FnSet)
2884 return false;
2885
2886 FnMap.clear();
2887 // Generate the internalized version of each function.
2888 for (Function *F : FnSet) {
2889 Module &M = *F->getParent();
2890 FunctionType *FnTy = F->getFunctionType();
2891
2892 // Create a copy of the current function
2893 Function *Copied =
2894 Function::Create(FnTy, F->getLinkage(), F->getAddressSpace(),
2895 F->getName() + ".internalized");
2896 ValueToValueMapTy VMap;
2897 auto *NewFArgIt = Copied->arg_begin();
2898 for (auto &Arg : F->args()) {
2899 auto ArgName = Arg.getName();
2900 NewFArgIt->setName(ArgName);
2901 VMap[&Arg] = &(*NewFArgIt++);
2902 }
2904
2905 // Copy the body of the original function to the new one
2906 CloneFunctionInto(Copied, F, VMap,
2908
2909 // Set the linakage and visibility late as CloneFunctionInto has some
2910 // implicit requirements.
2913
2914 // Copy metadata
2916 F->getAllMetadata(MDs);
2917 for (auto MDIt : MDs)
2918 if (!Copied->hasMetadata())
2919 Copied->addMetadata(MDIt.first, *MDIt.second);
2920
2921 M.getFunctionList().insert(F->getIterator(), Copied);
2922 Copied->setDSOLocal(true);
2923 FnMap[F] = Copied;
2924 }
2925
2926 // Replace all uses of the old function with the new internalized function
2927 // unless the caller is a function that was just internalized.
2928 for (Function *F : FnSet) {
2929 auto &InternalizedFn = FnMap[F];
2930 auto IsNotInternalized = [&](Use &U) -> bool {
2931 if (auto *CB = dyn_cast<CallBase>(U.getUser()))
2932 return !FnMap.lookup(CB->getCaller());
2933 return false;
2934 };
2935 F->replaceUsesWithIf(InternalizedFn, IsNotInternalized);
2936 }
2937
2938 return true;
2939}
2940
2942 Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
2943
2944 if (!Configuration.RewriteSignatures)
2945 return false;
2946
2947 Function *Fn = Arg.getParent();
2948 auto CallSiteCanBeChanged = [Fn](AbstractCallSite ACS) {
2949 // Forbid the call site to cast the function return type. If we need to
2950 // rewrite these functions we need to re-create a cast for the new call site
2951 // (if the old had uses).
2952 if (!ACS.getCalledFunction() ||
2953 ACS.getInstruction()->getType() !=
2955 return false;
2956 if (cast<CallBase>(ACS.getInstruction())->getCalledOperand()->getType() !=
2957 Fn->getType())
2958 return false;
2959 if (ACS.getNumArgOperands() != Fn->arg_size())
2960 return false;
2961 // Forbid must-tail calls for now.
2962 return !ACS.isCallbackCall() && !ACS.getInstruction()->isMustTailCall();
2963 };
2964
2965 // Avoid var-arg functions for now.
2966 if (Fn->isVarArg()) {
2967 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
2968 return false;
2969 }
2970
2971 // Avoid functions with complicated argument passing semantics.
2972 AttributeList FnAttributeList = Fn->getAttributes();
2973 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
2974 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
2975 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca) ||
2976 FnAttributeList.hasAttrSomewhere(Attribute::Preallocated)) {
2977 LLVM_DEBUG(
2978 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
2979 return false;
2980 }
2981
2982 // Avoid callbacks for now.
2983 bool UsedAssumedInformation = false;
2984 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,
2985 UsedAssumedInformation,
2986 /* CheckPotentiallyDead */ true)) {
2987 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
2988 return false;
2989 }
2990
2991 auto InstPred = [](Instruction &I) {
2992 if (auto *CI = dyn_cast<CallInst>(&I))
2993 return !CI->isMustTailCall();
2994 return true;
2995 };
2996
2997 // Forbid must-tail calls for now.
2998 // TODO:
2999 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
3000 if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
3001 nullptr, {Instruction::Call},
3002 UsedAssumedInformation)) {
3003 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
3004 return false;
3005 }
3006
3007 return true;
3008}
3009
3011 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
3014 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
3015 << Arg.getParent()->getName() << " with "
3016 << ReplacementTypes.size() << " replacements\n");
3017 assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&
3018 "Cannot register an invalid rewrite");
3019
3020 Function *Fn = Arg.getParent();
3022 ArgumentReplacementMap[Fn];
3023 if (ARIs.empty())
3024 ARIs.resize(Fn->arg_size());
3025
3026 // If we have a replacement already with less than or equal new arguments,
3027 // ignore this request.
3028 std::unique_ptr<ArgumentReplacementInfo> &ARI = ARIs[Arg.getArgNo()];
3029 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
3030 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
3031 return false;
3032 }
3033
3034 // If we have a replacement already but we like the new one better, delete
3035 // the old.
3036 ARI.reset();
3037
3038 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
3039 << Arg.getParent()->getName() << " with "
3040 << ReplacementTypes.size() << " replacements\n");
3041
3042 // Remember the replacement.
3043 ARI.reset(new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
3044 std::move(CalleeRepairCB),
3045 std::move(ACSRepairCB)));
3046
3047 return true;
3048}
3049
3050bool Attributor::shouldSeedAttribute(AbstractAttribute &AA) {
3051 bool Result = true;
3052#ifndef NDEBUG
3053 if (SeedAllowList.size() != 0)
3054 Result = llvm::is_contained(SeedAllowList, AA.getName());
3055 Function *Fn = AA.getAnchorScope();
3056 if (FunctionSeedAllowList.size() != 0 && Fn)
3058#endif
3059 return Result;
3060}
3061
3062ChangeStatus Attributor::rewriteFunctionSignatures(
3063 SmallSetVector<Function *, 8> &ModifiedFns) {
3065
3066 for (auto &It : ArgumentReplacementMap) {
3067 Function *OldFn = It.first;
3068
3069 // Deleted functions do not require rewrites.
3070 if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))
3071 continue;
3072
3074 It.second;
3075 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
3076
3077 SmallVector<Type *, 16> NewArgumentTypes;
3078 SmallVector<AttributeSet, 16> NewArgumentAttributes;
3079
3080 // Collect replacement argument types and copy over existing attributes.
3081 AttributeList OldFnAttributeList = OldFn->getAttributes();
3082 for (Argument &Arg : OldFn->args()) {
3083 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3084 ARIs[Arg.getArgNo()]) {
3085 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
3086 ARI->ReplacementTypes.end());
3087 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
3088 AttributeSet());
3089 } else {
3090 NewArgumentTypes.push_back(Arg.getType());
3091 NewArgumentAttributes.push_back(
3092 OldFnAttributeList.getParamAttrs(Arg.getArgNo()));
3093 }
3094 }
3095
3096 uint64_t LargestVectorWidth = 0;
3097 for (auto *I : NewArgumentTypes)
3098 if (auto *VT = dyn_cast<llvm::VectorType>(I))
3099 LargestVectorWidth =
3100 std::max(LargestVectorWidth,
3101 VT->getPrimitiveSizeInBits().getKnownMinValue());
3102
3103 FunctionType *OldFnTy = OldFn->getFunctionType();
3104 Type *RetTy = OldFnTy->getReturnType();
3105
3106 // Construct the new function type using the new arguments types.
3107 FunctionType *NewFnTy =
3108 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
3109
3110 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
3111 << "' from " << *OldFn->getFunctionType() << " to "
3112 << *NewFnTy << "\n");
3113
3114 // Create the new function body and insert it into the module.
3115 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
3116 OldFn->getAddressSpace(), "");
3117 Functions.insert(NewFn);
3118 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
3119 NewFn->takeName(OldFn);
3120 NewFn->copyAttributesFrom(OldFn);
3121
3122 // Patch the pointer to LLVM function in debug info descriptor.
3123 NewFn->setSubprogram(OldFn->getSubprogram());
3124 OldFn->setSubprogram(nullptr);
3125
3126 // Recompute the parameter attributes list based on the new arguments for
3127 // the function.
3128 LLVMContext &Ctx = OldFn->getContext();
3129 NewFn->setAttributes(AttributeList::get(
3130 Ctx, OldFnAttributeList.getFnAttrs(), OldFnAttributeList.getRetAttrs(),
3131 NewArgumentAttributes));
3132 AttributeFuncs::updateMinLegalVectorWidthAttr(*NewFn, LargestVectorWidth);
3133
3134 // Remove argmem from the memory effects if we have no more pointer
3135 // arguments, or they are readnone.
3136 MemoryEffects ME = NewFn->getMemoryEffects();
3137 int ArgNo = -1;
3138 if (ME.doesAccessArgPointees() && all_of(NewArgumentTypes, [&](Type *T) {
3139 ++ArgNo;
3140 return !T->isPtrOrPtrVectorTy() ||
3141 NewFn->hasParamAttribute(ArgNo, Attribute::ReadNone);
3142 })) {
3144 }
3145
3146 // Since we have now created the new function, splice the body of the old
3147 // function right into the new function, leaving the old rotting hulk of the
3148 // function empty.
3149 NewFn->splice(NewFn->begin(), OldFn);
3150
3151 // Set of all "call-like" instructions that invoke the old function mapped
3152 // to their new replacements.
3154
3155 // Callback to create a new "call-like" instruction for a given one.
3156 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
3157 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
3158 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
3159
3160 // Collect the new argument operands for the replacement call site.
3161 SmallVector<Value *, 16> NewArgOperands;
3162 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
3163 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
3164 unsigned NewFirstArgNum = NewArgOperands.size();
3165 (void)NewFirstArgNum; // only used inside assert.
3166 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3167 ARIs[OldArgNum]) {
3168 if (ARI->ACSRepairCB)
3169 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
3170 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
3171 NewArgOperands.size() &&
3172 "ACS repair callback did not provide as many operand as new "
3173 "types were registered!");
3174 // TODO: Exose the attribute set to the ACS repair callback
3175 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
3176 AttributeSet());
3177 } else {
3178 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
3179 NewArgOperandAttributes.push_back(
3180 OldCallAttributeList.getParamAttrs(OldArgNum));
3181 }
3182 }
3183
3184 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
3185 "Mismatch # argument operands vs. # argument operand attributes!");
3186 assert(NewArgOperands.size() == NewFn->arg_size() &&
3187 "Mismatch # argument operands vs. # function arguments!");
3188
3189 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
3190 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
3191
3192 // Create a new call or invoke instruction to replace the old one.
3193 CallBase *NewCB;
3194 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
3195 NewCB = InvokeInst::Create(NewFn, II->getNormalDest(),
3196 II->getUnwindDest(), NewArgOperands,
3197 OperandBundleDefs, "", OldCB->getIterator());
3198 } else {
3199 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
3200 "", OldCB->getIterator());
3201 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
3202 NewCB = NewCI;
3203 }
3204
3205 // Copy over various properties and the new attributes.
3206 NewCB->copyProfileAndDebugMetadata(*OldCB);
3207 NewCB->setCallingConv(OldCB->getCallingConv());
3208 NewCB->takeName(OldCB);
3209 NewCB->setAttributes(AttributeList::get(
3210 Ctx, OldCallAttributeList.getFnAttrs(),
3211 OldCallAttributeList.getRetAttrs(), NewArgOperandAttributes));
3212
3213 AttributeFuncs::updateMinLegalVectorWidthAttr(*NewCB->getCaller(),
3214 LargestVectorWidth);
3215
3216 CallSitePairs.push_back({OldCB, NewCB});
3217 return true;
3218 };
3219
3220 // Use the CallSiteReplacementCreator to create replacement call sites.
3221 bool UsedAssumedInformation = false;
3222 bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,
3223 true, nullptr, UsedAssumedInformation,
3224 /* CheckPotentiallyDead */ true);
3225 (void)Success;
3226 assert(Success && "Assumed call site replacement to succeed!");
3227
3228 // Rewire the arguments.
3229 Argument *OldFnArgIt = OldFn->arg_begin();
3230 Argument *NewFnArgIt = NewFn->arg_begin();
3231 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
3232 ++OldArgNum, ++OldFnArgIt) {
3233 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3234 ARIs[OldArgNum]) {
3235 if (ARI->CalleeRepairCB)
3236 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
3237 if (ARI->ReplacementTypes.empty())
3238 OldFnArgIt->replaceAllUsesWith(
3239 PoisonValue::get(OldFnArgIt->getType()));
3240 NewFnArgIt += ARI->ReplacementTypes.size();
3241 } else {
3242 NewFnArgIt->takeName(&*OldFnArgIt);
3243 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
3244 ++NewFnArgIt;
3245 }
3246 }
3247
3248 // Eliminate the instructions *after* we visited all of them.
3249 for (auto &CallSitePair : CallSitePairs) {
3250 CallBase &OldCB = *CallSitePair.first;
3251 CallBase &NewCB = *CallSitePair.second;
3252 assert(OldCB.getType() == NewCB.getType() &&
3253 "Cannot handle call sites with different types!");
3254 ModifiedFns.insert(OldCB.getFunction());
3255 OldCB.replaceAllUsesWith(&NewCB);
3256 OldCB.eraseFromParent();
3257 }
3258
3259 // Replace the function in the call graph (if any).
3260 Configuration.CGUpdater.replaceFunctionWith(*OldFn, *NewFn);
3261
3262 // If the old function was modified and needed to be reanalyzed, the new one
3263 // does now.
3264 if (ModifiedFns.remove(OldFn))
3265 ModifiedFns.insert(NewFn);
3266
3268 }
3269
3270 return Changed;
3271}
3272
3273void InformationCache::initializeInformationCache(const Function &CF,
3274 FunctionInfo &FI) {
3275 // As we do not modify the function here we can remove the const
3276 // withouth breaking implicit assumptions. At the end of the day, we could
3277 // initialize the cache eagerly which would look the same to the users.
3278 Function &F = const_cast<Function &>(CF);
3279
3280 FI.IsKernel = F.hasFnAttribute("kernel");
3281
3282 // Walk all instructions to find interesting instructions that might be
3283 // queried by abstract attributes during their initialization or update.
3284 // This has to happen before we create attributes.
3285
3286 for (Instruction &I : instructions(&F)) {
3287 bool IsInterestingOpcode = false;
3288
3289 // To allow easy access to all instructions in a function with a given
3290 // opcode we store them in the InfoCache. As not all opcodes are interesting
3291 // to concrete attributes we only cache the ones that are as identified in
3292 // the following switch.
3293 // Note: There are no concrete attributes now so this is initially empty.
3294 switch (I.getOpcode()) {
3295 default:
3296 assert(!isa<CallBase>(&I) &&
3297 "New call base instruction type needs to be known in the "
3298 "Attributor.");
3299 break;
3300 case Instruction::Call:
3301 // Calls are interesting on their own, additionally:
3302 // For `llvm.assume` calls we also fill the KnowledgeMap as we find them.
3303 // For `must-tail` calls we remember the caller and callee.
3304 if (auto *Assume = dyn_cast<AssumeInst>(&I)) {
3305 fillMapFromAssume(*Assume, KnowledgeMap);
3306 } else if (cast<CallInst>(I).isMustTailCall()) {
3307 FI.ContainsMustTailCall = true;
3308 if (auto *Callee = dyn_cast_if_present<Function>(
3309 cast<CallInst>(I).getCalledOperand()))
3310 getFunctionInfo(*Callee).CalledViaMustTail = true;
3311 }
3312 [[fallthrough]];
3313 case Instruction::CallBr:
3314 case Instruction::Invoke:
3315 case Instruction::CleanupRet:
3316 case Instruction::CatchSwitch:
3317 case Instruction::AtomicRMW:
3318 case Instruction::AtomicCmpXchg:
3319 case Instruction::UncondBr:
3320 case Instruction::CondBr:
3321 case Instruction::Resume:
3322 case Instruction::Ret:
3323 case Instruction::Load:
3324 // The alignment of a pointer is interesting for loads.
3325 case Instruction::Store:
3326 // The alignment of a pointer is interesting for stores.
3327 case Instruction::Alloca:
3328 case Instruction::AddrSpaceCast:
3329 IsInterestingOpcode = true;
3330 }
3331 if (IsInterestingOpcode) {
3332 auto *&Insts = FI.OpcodeInstMap[I.getOpcode()];
3333 if (!Insts)
3334 Insts = new (Allocator) InstructionVectorTy();
3335 Insts->push_back(&I);
3336 }
3337 if (I.mayReadOrWriteMemory())
3338 FI.RWInsts.push_back(&I);
3339 }
3340
3341 if (F.hasFnAttribute(Attribute::AlwaysInline) &&
3342 isInlineViable(F).isSuccess())
3343 InlineableFunctions.insert(&F);
3344}
3345
3346void InformationCache::collectAssumeOnlyValues(FunctionInfo &FI) {
3347 FI.AssumeOnlyValuesCollected = true;
3348 InstructionVectorTy *Calls = FI.OpcodeInstMap[Instruction::Call];
3349 if (!Calls)
3350 return;
3351
3352 DenseMap<const Value *, std::optional<short>> AssumeUsesMap;
3353
3354 // Add \p V to the assume uses map which track the number of uses outside of
3355 // "visited" assumes. If no outside uses are left the value is added to the
3356 // assume only use vector.
3357 auto AddToAssumeUsesMap = [&](const Value &V) -> void {
3358 SmallVector<const Instruction *> Worklist;
3359 if (auto *I = dyn_cast<Instruction>(&V))
3360 Worklist.push_back(I);
3361 while (!Worklist.empty()) {
3362 const Instruction *I = Worklist.pop_back_val();
3363 std::optional<short> &NumUses = AssumeUsesMap[I];
3364 if (!NumUses)
3365 NumUses = I->getNumUses();
3366 NumUses = *NumUses - /* this assume */ 1;
3367 if (*NumUses != 0)
3368 continue;
3369 AssumeOnlyValues.insert(I);
3370 for (const Instruction *OpI : make_isa_range<Instruction>(I->operands()))
3371 Worklist.push_back(OpI);
3372 }
3373 };
3374
3375 for (AssumeInst *Assume : make_isa_range<AssumeInst>(*Calls)) {
3376 AssumeOnlyValues.insert(Assume);
3377 AddToAssumeUsesMap(*Assume->getArgOperand(0));
3378 }
3379}
3380
3381InformationCache::FunctionInfo::~FunctionInfo() {
3382 // The instruction vectors are allocated using a BumpPtrAllocator, we need to
3383 // manually destroy them.
3384 for (InstructionVectorTy *Insts : OpcodeInstMap) {
3385 if (Insts)
3386 Insts->~InstructionVectorTy();
3387 }
3388}
3389
3392 assert(A.isClosedWorldModule() && "Cannot see all indirect callees!");
3393 return IndirectlyCallableFunctions;
3394}
3395
3396std::optional<unsigned> InformationCache::getFlatAddressSpace() const {
3397 if (IsTargetGPU())
3398 return 0;
3399 return std::nullopt;
3400}
3401
3403 const AbstractAttribute &ToAA,
3404 DepClassTy DepClass) {
3405 if (DepClass == DepClassTy::NONE)
3406 return;
3407 // If we are outside of an update, thus before the actual fixpoint iteration
3408 // started (= when we create AAs), we do not track dependences because we will
3409 // put all AAs into the initial worklist anyway.
3410 if (DependenceStack.empty())
3411 return;
3412 if (FromAA.isStateAtFixpoint())
3413 return;
3414 DependenceStack.back()->push_back({&FromAA, &ToAA, DepClass});
3415}
3416
3417void Attributor::rememberDependences() {
3418 assert(!DependenceStack.empty() && "No dependences to remember!");
3419
3420 for (DepInfo &DI : *DependenceStack.back()) {
3421 assert((DI.DepClass == DepClassTy::REQUIRED ||
3422 DI.DepClass == DepClassTy::OPTIONAL) &&
3423 "Expected required or optional dependence (1 bit)!");
3424 auto &DepAAs = const_cast<AbstractAttribute &>(*DI.FromAA).Deps;
3425 DepAAs.insert(AbstractAttribute::DepTy(
3426 const_cast<AbstractAttribute *>(DI.ToAA), unsigned(DI.DepClass)));
3427 }
3428}
3429
3430template <Attribute::AttrKind AK, typename AAType>
3431void Attributor::checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs,
3432 bool SkipHasAttrCheck) {
3433 bool IsKnown;
3434 if (SkipHasAttrCheck || !Attrs.hasAttribute(AK))
3435 if (!Configuration.Allowed || Configuration.Allowed->contains<AAType>())
3436 if (!AA::hasAssumedIRAttr<AK>(*this, nullptr, IRP, DepClassTy::NONE,
3437 IsKnown))
3438 getOrCreateAAFor<AAType>(IRP);
3439}
3440
3442 assert(!F.isDeclaration());
3443
3444 if (!VisitedFunctions.insert(&F).second)
3445 return;
3446
3447 // In non-module runs we need to look at the call sites of a function to
3448 // determine if it is part of a must-tail call edge. This will influence what
3449 // attributes we can derive.
3450 InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(F);
3451 if (!isModulePass() && !FI.CalledViaMustTail) {
3452 for (const Use &U : F.uses())
3453 if (const auto *CB = dyn_cast<CallBase>(U.getUser()))
3454 if (CB->isCallee(&U) && CB->isMustTailCall())
3455 FI.CalledViaMustTail = true;
3456 }
3457
3459 bool IsIPOAmendable = isFunctionIPOAmendable(F);
3460 auto Attrs = F.getAttributes();
3461 auto FnAttrs = Attrs.getFnAttrs();
3462
3463 // Check for dead BasicBlocks in every function.
3464 // We need dead instruction detection because we do not want to deal with
3465 // broken IR in which SSA rules do not apply.
3467
3468 // Every function might contain instructions that cause "undefined
3469 // behavior".
3471
3472 // Every function might be applicable for Heap-To-Stack conversion.
3475
3476 // Every function might be "must-progress".
3477 checkAndQueryIRAttr<Attribute::MustProgress, AAMustProgress>(FPos, FnAttrs);
3478
3479 // Every function might be "no-free".
3480 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(FPos, FnAttrs);
3481
3482 // Every function might be "will-return".
3483 checkAndQueryIRAttr<Attribute::WillReturn, AAWillReturn>(FPos, FnAttrs);
3484
3485 // Every function might be marked "nosync"
3486 checkAndQueryIRAttr<Attribute::NoSync, AANoSync>(FPos, FnAttrs);
3487
3488 // Everything that is visible from the outside (=function, argument, return
3489 // positions), cannot be changed if the function is not IPO amendable. We can
3490 // however analyse the code inside.
3491 if (IsIPOAmendable) {
3492
3493 // Every function can be nounwind.
3494 checkAndQueryIRAttr<Attribute::NoUnwind, AANoUnwind>(FPos, FnAttrs);
3495
3496 // Every function might be "no-return".
3497 checkAndQueryIRAttr<Attribute::NoReturn, AANoReturn>(FPos, FnAttrs);
3498
3499 // Every function might be "no-recurse".
3500 checkAndQueryIRAttr<Attribute::NoRecurse, AANoRecurse>(FPos, FnAttrs);
3501
3502 // Every function can be "non-convergent".
3503 if (Attrs.hasFnAttr(Attribute::Convergent))
3505
3506 // Every function might be "readnone/readonly/writeonly/...".
3508
3509 // Every function can be "readnone/argmemonly/inaccessiblememonly/...".
3511
3512 // Every function can track active assumptions.
3514
3515 // If we're not using a dynamic mode for float, there's nothing worthwhile
3516 // to infer. This misses the edge case denormal-fp-math="dynamic" and
3517 // denormal-fp-math-f32=something, but that likely has no real world use.
3518 DenormalMode Mode = F.getDenormalMode(APFloat::IEEEsingle());
3519 if (Mode.Input == DenormalMode::Dynamic ||
3520 Mode.Output == DenormalMode::Dynamic)
3522
3523 // Return attributes are only appropriate if the return type is non void.
3524 Type *ReturnType = F.getReturnType();
3525 if (!ReturnType->isVoidTy()) {
3527 AttributeSet RetAttrs = Attrs.getRetAttrs();
3528
3529 // Every returned value might be dead.
3531
3532 // Every function might be simplified.
3533 bool UsedAssumedInformation = false;
3534 getAssumedSimplified(RetPos, nullptr, UsedAssumedInformation,
3536
3537 // Every returned value might be marked noundef.
3538 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(RetPos, RetAttrs);
3539
3540 if (ReturnType->isPointerTy()) {
3541
3542 // Every function with pointer return type might be marked align.
3544
3545 // Every function with pointer return type might be marked nonnull.
3546 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(RetPos, RetAttrs);
3547
3548 // Every function with pointer return type might be marked noalias.
3549 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(RetPos, RetAttrs);
3550
3551 // Every function with pointer return type might be marked
3552 // dereferenceable.
3554 } else if (AttributeFuncs::isNoFPClassCompatibleType(ReturnType)) {
3556 }
3557 }
3558 }
3559
3560 for (Argument &Arg : F.args()) {
3561 IRPosition ArgPos = IRPosition::argument(Arg);
3562 auto ArgNo = Arg.getArgNo();
3563 AttributeSet ArgAttrs = Attrs.getParamAttrs(ArgNo);
3564
3565 if (!IsIPOAmendable) {
3566 if (Arg.getType()->isPointerTy())
3567 // Every argument with pointer type might be marked nofree.
3568 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);
3569 continue;
3570 }
3571
3572 // Every argument might be simplified. We have to go through the
3573 // Attributor interface though as outside AAs can register custom
3574 // simplification callbacks.
3575 bool UsedAssumedInformation = false;
3576 getAssumedSimplified(ArgPos, /* AA */ nullptr, UsedAssumedInformation,
3578
3579 // Every argument might be dead.
3581
3582 // Every argument might be marked noundef.
3583 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(ArgPos, ArgAttrs);
3584
3585 if (Arg.getType()->isPointerTy()) {
3586 // Every argument with pointer type might be marked nonnull.
3587 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(ArgPos, ArgAttrs);
3588
3589 // Every argument with pointer type might be marked noalias.
3590 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(ArgPos, ArgAttrs);
3591
3592 // Every argument with pointer type might be marked dereferenceable.
3594
3595 // Every argument with pointer type might be marked align.
3597
3598 // Every argument with pointer type might be marked nocapture.
3599 checkAndQueryIRAttr<Attribute::Captures, AANoCapture>(
3600 ArgPos, ArgAttrs, /*SkipHasAttrCheck=*/true);
3601
3602 // Every argument with pointer type might be marked
3603 // "readnone/readonly/writeonly/..."
3605
3606 // Every argument with pointer type might be marked nofree.
3607 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);
3608
3609 // Every argument with pointer type might be privatizable (or
3610 // promotable)
3612 } else if (AttributeFuncs::isNoFPClassCompatibleType(Arg.getType())) {
3614 }
3615 }
3616
3617 auto CallSitePred = [&](Instruction &I) -> bool {
3618 auto &CB = cast<CallBase>(I);
3619 IRPosition CBInstPos = IRPosition::inst(CB);
3621
3622 // Call sites might be dead if they do not have side effects and no live
3623 // users. The return value might be dead if there are no live users.
3624 getOrCreateAAFor<AAIsDead>(CBInstPos);
3625
3626 Function *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
3627 // TODO: Even if the callee is not known now we might be able to simplify
3628 // the call/callee.
3629 if (!Callee) {
3631 return true;
3632 }
3633
3634 // Every call site can track active assumptions.
3636
3637 // Skip declarations except if annotations on their call sites were
3638 // explicitly requested.
3639 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
3640 !Callee->hasMetadata(LLVMContext::MD_callback))
3641 return true;
3642
3643 if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
3645 bool UsedAssumedInformation = false;
3646 getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation,
3648
3649 if (AttributeFuncs::isNoFPClassCompatibleType(Callee->getReturnType()))
3651 }
3652
3653 const AttributeList &CBAttrs = CBFnPos.getAttrList();
3654 for (int I = 0, E = CB.arg_size(); I < E; ++I) {
3655
3657 AttributeSet CBArgAttrs = CBAttrs.getParamAttrs(I);
3658
3659 // Every call site argument might be dead.
3661
3662 // Call site argument might be simplified. We have to go through the
3663 // Attributor interface though as outside AAs can register custom
3664 // simplification callbacks.
3665 bool UsedAssumedInformation = false;
3666 getAssumedSimplified(CBArgPos, /* AA */ nullptr, UsedAssumedInformation,
3668
3669 // Every call site argument might be marked "noundef".
3670 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(CBArgPos, CBArgAttrs);
3671
3672 Type *ArgTy = CB.getArgOperand(I)->getType();
3673
3674 if (!ArgTy->isPointerTy()) {
3675 if (AttributeFuncs::isNoFPClassCompatibleType(ArgTy))
3677
3678 continue;
3679 }
3680
3681 // Call site argument attribute "non-null".
3682 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(CBArgPos, CBArgAttrs);
3683
3684 // Call site argument attribute "captures(none)".
3685 checkAndQueryIRAttr<Attribute::Captures, AANoCapture>(
3686 CBArgPos, CBArgAttrs, /*SkipHasAttrCheck=*/true);
3687
3688 // Call site argument attribute "no-alias".
3689 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(CBArgPos, CBArgAttrs);
3690
3691 // Call site argument attribute "dereferenceable".
3693
3694 // Call site argument attribute "align".
3695 getOrCreateAAFor<AAAlign>(CBArgPos);
3696
3697 // Call site argument attribute
3698 // "readnone/readonly/writeonly/..."
3699 if (!CBAttrs.hasParamAttr(I, Attribute::ReadNone))
3701
3702 // Call site argument attribute "nofree".
3703 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(CBArgPos, CBArgAttrs);
3704 }
3705 return true;
3706 };
3707
3708 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
3709 [[maybe_unused]] bool Success;
3710 bool UsedAssumedInformation = false;
3712 nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
3713 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
3714 (unsigned)Instruction::Call},
3715 UsedAssumedInformation);
3716 assert(Success && "Expected the check call to be successful!");
3717
3718 auto LoadStorePred = [&](Instruction &I) -> bool {
3719 if (auto *LI = dyn_cast<LoadInst>(&I)) {
3720 getOrCreateAAFor<AAAlign>(IRPosition::value(*LI->getPointerOperand()));
3721 if (SimplifyAllLoads)
3723 UsedAssumedInformation, AA::Intraprocedural);
3725 IRPosition::value(*LI->getPointerOperand()));
3726 if (InfoCache.getFlatAddressSpace().has_value()) {
3728 IRPosition::value(*LI->getPointerOperand()));
3729 }
3730 } else {
3731 auto &SI = cast<StoreInst>(I);
3733 getAssumedSimplified(IRPosition::value(*SI.getValueOperand()), nullptr,
3734 UsedAssumedInformation, AA::Intraprocedural);
3735 getOrCreateAAFor<AAAlign>(IRPosition::value(*SI.getPointerOperand()));
3736 if (InfoCache.getFlatAddressSpace().has_value()) {
3738 IRPosition::value(*SI.getPointerOperand()));
3739 }
3740 }
3741 return true;
3742 };
3744 nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
3745 {(unsigned)Instruction::Load, (unsigned)Instruction::Store},
3746 UsedAssumedInformation);
3747 assert(Success && "Expected the check call to be successful!");
3748
3749 // AllocaInstPredicate
3750 auto AAAllocationInfoPred = [&](Instruction &I) -> bool {
3752 return true;
3753 };
3754
3756 nullptr, OpcodeInstMap, AAAllocationInfoPred, nullptr, nullptr,
3757 {(unsigned)Instruction::Alloca}, UsedAssumedInformation);
3758 assert(Success && "Expected the check call to be successful!");
3759}
3760
3762 if (CloseWorldAssumption.getNumOccurrences())
3763 return CloseWorldAssumption;
3764 return isModulePass() && Configuration.IsClosedWorldModule;
3765}
3766
3767/// Helpers to ease debugging through output streams and print calls.
3768///
3769///{
3771 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
3772}
3773
3775 switch (AP) {
3777 return OS << "inv";
3779 return OS << "flt";
3781 return OS << "fn_ret";
3783 return OS << "cs_ret";
3785 return OS << "fn";
3787 return OS << "cs";
3789 return OS << "arg";
3791 return OS << "cs_arg";
3792 }
3793 llvm_unreachable("Unknown attribute position!");
3794}
3795
3797 const Value &AV = Pos.getAssociatedValue();
3798 OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
3799 << Pos.getAnchorValue().getName() << "@" << Pos.getCallSiteArgNo() << "]";
3800
3801 if (Pos.hasCallBaseContext())
3802 OS << "[cb_context:" << *Pos.getCallBaseContext() << "]";
3803 return OS << "}";
3804}
3805
3807 OS << "range-state(" << S.getBitWidth() << ")<";
3808 S.getKnown().print(OS);
3809 OS << " / ";
3810 S.getAssumed().print(OS);
3811 OS << ">";
3812
3813 return OS << static_cast<const AbstractState &>(S);
3814}
3815
3817 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
3818}
3819
3821 AA.print(OS);
3822 return OS;
3823}
3824
3827 OS << "set-state(< {";
3828 if (!S.isValidState())
3829 OS << "full-set";
3830 else {
3831 for (const auto &It : S.getAssumedSet())
3832 OS << It << ", ";
3833 if (S.undefIsContained())
3834 OS << "undef ";
3835 }
3836 OS << "} >)";
3837
3838 return OS;
3839}
3840
3842 const PotentialLLVMValuesState &S) {
3843 OS << "set-state(< {";
3844 if (!S.isValidState())
3845 OS << "full-set";
3846 else {
3847 for (const auto &It : S.getAssumedSet()) {
3848 if (auto *F = dyn_cast<Function>(It.first.getValue()))
3849 OS << "@" << F->getName() << "[" << int(It.second) << "], ";
3850 else
3851 OS << *It.first.getValue() << "[" << int(It.second) << "], ";
3852 }
3853 if (S.undefIsContained())
3854 OS << "undef ";
3855 }
3856 OS << "} >)";
3857
3858 return OS;
3859}
3860
3862 OS << "[";
3863 OS << getName();
3864 OS << "] for CtxI ";
3865
3866 if (auto *I = getCtxI()) {
3867 OS << "'";
3868 I->print(OS);
3869 OS << "'";
3870 } else
3871 OS << "<<null inst>>";
3872
3873 OS << " at position " << getIRPosition() << " with state " << getAsStr(A)
3874 << '\n';
3875}
3876
3878 print(OS);
3879
3880 for (const auto &DepAA : Deps) {
3881 auto *AA = DepAA.getPointer();
3882 OS << " updates ";
3883 AA->print(OS);
3884 }
3885
3886 OS << '\n';
3887}
3888
3890 const AAPointerInfo::Access &Acc) {
3891 OS << " [" << Acc.getKind() << "] " << *Acc.getRemoteInst();
3892 if (Acc.getLocalInst() != Acc.getRemoteInst())
3893 OS << " via " << *Acc.getLocalInst();
3894 if (Acc.getContent()) {
3895 if (*Acc.getContent())
3896 OS << " [" << **Acc.getContent() << "]";
3897 else
3898 OS << " [ <unknown> ]";
3899 }
3900 return OS;
3901}
3902///}
3903
3904/// ----------------------------------------------------------------------------
3905/// Pass (Manager) Boilerplate
3906/// ----------------------------------------------------------------------------
3907
3909 SetVector<Function *> &Functions,
3910 CallGraphUpdater &CGUpdater,
3912 bool DeleteFns, bool IsModulePass) {
3913 if (Functions.empty())
3914 return false;
3915
3916 LLVM_DEBUG({
3917 dbgs() << "[Attributor] Run on module with " << Functions.size()
3918 << " functions:\n";
3919 for (Function *Fn : Functions)
3920 dbgs() << " - " << Fn->getName() << "\n";
3921 });
3922
3923 // Create an Attributor and initially empty information cache that is filled
3924 // while we identify default attribute opportunities.
3925 AttributorConfig AC(CGUpdater);
3926 AC.IsModulePass = IsModulePass;
3927 AC.DeleteFns = DeleteFns;
3928 auto OREGetter = [&FAM](Function *F) -> OptimizationRemarkEmitter & {
3929 return FAM.getResult<OptimizationRemarkEmitterAnalysis>(*F);
3930 };
3931 AC.OREGetter = OREGetter;
3932 AC.PassName = DEBUG_TYPE;
3933
3934 /// Tracking callback for specialization of indirect calls.
3936 IndirectCalleeTrackingMap;
3937 if (MaxSpecializationPerCB.getNumOccurrences()) {
3938 AC.IndirectCalleeSpecializationCallback =
3939 [&](Attributor &, const AbstractAttribute &AA, CallBase &CB,
3940 Function &Callee, unsigned) {
3941 if (MaxSpecializationPerCB == 0)
3942 return false;
3943 auto &Set = IndirectCalleeTrackingMap[&CB];
3944 if (!Set)
3945 Set = std::make_unique<SmallPtrSet<Function *, 8>>();
3946 if (Set->size() >= MaxSpecializationPerCB)
3947 return Set->contains(&Callee);
3948 Set->insert(&Callee);
3949 return true;
3950 };
3951 }
3952
3953 Attributor A(Functions, InfoCache, AC);
3954
3955 // Create shallow wrappers for all functions that are not IPO amendable
3957 for (Function *F : Functions)
3958 if (!A.isFunctionIPOAmendable(*F))
3960
3961 // Internalize non-exact functions
3962 // TODO: for now we eagerly internalize functions without calculating the
3963 // cost, we need a cost interface to determine whether internalizing
3964 // a function is "beneficial"
3965 if (AllowDeepWrapper) {
3966 unsigned FunSize = Functions.size();
3967 for (unsigned u = 0; u < FunSize; u++) {
3968 Function *F = Functions[u];
3969 if (!F->isDeclaration() && !F->isDefinitionExact() && !F->use_empty() &&
3970 !GlobalValue::isInterposableLinkage(F->getLinkage())) {
3972 assert(NewF && "Could not internalize function.");
3973 Functions.insert(NewF);
3974
3975 // Update call graph
3976 CGUpdater.replaceFunctionWith(*F, *NewF);
3977 for (const Use &U : NewF->uses())
3978 if (CallBase *CB = dyn_cast<CallBase>(U.getUser())) {
3979 auto *CallerF = CB->getCaller();
3980 CGUpdater.reanalyzeFunction(*CallerF);
3981 }
3982 }
3983 }
3984 }
3985
3986 for (Function *F : Functions) {
3987 if (F->isDeclaration())
3988 continue;
3989
3990 if (F->hasExactDefinition())
3991 NumFnWithExactDefinition++;
3992 else
3993 NumFnWithoutExactDefinition++;
3994
3995 // We look at internal functions only on-demand but if any use is not a
3996 // direct call or outside the current set of analyzed functions, we have
3997 // to do it eagerly.
3998 if (F->hasLocalLinkage()) {
3999 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
4000 const auto *CB = dyn_cast<CallBase>(U.getUser());
4001 return CB && CB->isCallee(&U) &&
4002 Functions.count(const_cast<Function *>(CB->getCaller()));
4003 }))
4004 continue;
4005 }
4006
4007 // Populate the Attributor with abstract attribute opportunities in the
4008 // function and the information cache with IR information.
4009 A.identifyDefaultAbstractAttributes(*F);
4010 }
4011
4012 ChangeStatus Changed = A.run();
4013
4014 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
4015 << " functions, result: " << Changed << ".\n");
4017}
4018
4020 SetVector<Function *> &Functions,
4021 CallGraphUpdater &CGUpdater,
4023 bool IsModulePass) {
4024 if (Functions.empty())
4025 return false;
4026
4027 LLVM_DEBUG({
4028 dbgs() << "[AttributorLight] Run on module with " << Functions.size()
4029 << " functions:\n";
4030 for (Function *Fn : Functions)
4031 dbgs() << " - " << Fn->getName() << "\n";
4032 });
4033
4034 // Create an Attributor and initially empty information cache that is filled
4035 // while we identify default attribute opportunities.
4036 AttributorConfig AC(CGUpdater);
4037 AC.IsModulePass = IsModulePass;
4038 AC.DeleteFns = false;
4039 static constexpr AAKindSet Allowed =
4047 AC.Allowed = Allowed;
4048 AC.UseLiveness = false;
4049
4050 Attributor A(Functions, InfoCache, AC);
4051
4052 for (Function *F : Functions) {
4053 if (F->isDeclaration())
4054 continue;
4055
4056 if (F->hasExactDefinition())
4057 NumFnWithExactDefinition++;
4058 else
4059 NumFnWithoutExactDefinition++;
4060
4061 // We look at internal functions only on-demand but if any use is not a
4062 // direct call or outside the current set of analyzed functions, we have
4063 // to do it eagerly.
4064 if (AC.UseLiveness && F->hasLocalLinkage()) {
4065 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
4066 const auto *CB = dyn_cast<CallBase>(U.getUser());
4067 return CB && CB->isCallee(&U) &&
4068 Functions.count(const_cast<Function *>(CB->getCaller()));
4069 }))
4070 continue;
4071 }
4072
4073 // Populate the Attributor with abstract attribute opportunities in the
4074 // function and the information cache with IR information.
4075 A.identifyDefaultAbstractAttributes(*F);
4076 }
4077
4078 ChangeStatus Changed = A.run();
4079
4081 // Invalidate analyses for modified functions so that we don't have to
4082 // invalidate all analyses for all functions in this SCC.
4083 PreservedAnalyses FuncPA;
4084 // We haven't changed the CFG for modified functions.
4085 FuncPA.preserveSet<CFGAnalyses>();
4086 // Functions whose instructions did not change do not need to be simplified
4087 // again if their SCC is revisited.
4088 PreservedAnalyses AttrOnlyPA = FuncPA;
4090
4091 const SmallSetVector<Function *, 8> &IRModified = A.getModifiedFunctions();
4092
4093 // Also invalidate any direct callers of changed functions since analyses
4094 // may care about attributes of direct callees. For example, MemorySSA
4095 // cares about whether or not a call's callee modifies memory and queries
4096 // that through function attributes.
4097 auto InvalidateCallers = [&](Function &Changed) {
4098 for (auto *U : Changed.users()) {
4099 auto *Call = dyn_cast<CallBase>(U);
4100 if (Call && Call->getCalledFunction() == &Changed)
4101 FAM.invalidate(*Call->getFunction(), AttrOnlyPA);
4102 }
4103 };
4104
4105 for (Function *Changed : IRModified) {
4106 FAM.invalidate(*Changed, FuncPA);
4107 InvalidateCallers(*Changed);
4108 }
4109
4110 for (Function *Changed : A.getAttrModifiedFunctions()) {
4111 if (IRModified.contains(Changed))
4112 continue;
4113 FAM.invalidate(*Changed, AttrOnlyPA);
4114 InvalidateCallers(*Changed);
4115 }
4116 }
4117 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
4118 << " functions, result: " << Changed << ".\n");
4120}
4121
4122void AADepGraph::viewGraph() { llvm::ViewGraph(this, "Dependency Graph"); }
4123
4125 static std::atomic<int> CallTimes;
4126 std::string Prefix;
4127
4128 if (!DepGraphDotFileNamePrefix.empty())
4130 else
4131 Prefix = "dep_graph";
4132 std::string Filename =
4133 Prefix + "_" + std::to_string(CallTimes.load()) + ".dot";
4134
4135 outs() << "Dependency graph dump to " << Filename << ".\n";
4136
4137 std::error_code EC;
4138
4140 if (!EC)
4141 llvm::WriteGraph(File, this);
4142
4143 CallTimes++;
4144}
4145
4147 for (auto DepAA : SyntheticRoot.Deps)
4148 cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(outs());
4149}
4150
4154 AnalysisGetter AG(FAM);
4155
4156 SetVector<Function *> Functions;
4157 Functions.reserve(M.size());
4158 for (Function &F : M)
4159 Functions.insert(&F);
4160
4161 CallGraphUpdater CGUpdater;
4162 BumpPtrAllocator Allocator;
4163 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);
4164 if (runAttributorOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4165 /* DeleteFns */ true, /* IsModulePass */ true)) {
4166 // FIXME: Think about passes we will preserve and add them here.
4167 return PreservedAnalyses::none();
4168 }
4169 return PreservedAnalyses::all();
4170}
4171
4174 LazyCallGraph &CG,
4175 CGSCCUpdateResult &UR) {
4177 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
4178 AnalysisGetter AG(FAM);
4179
4180 SetVector<Function *> Functions;
4181 Functions.reserve(C.size());
4182 for (LazyCallGraph::Node &N : C)
4183 Functions.insert(&N.getFunction());
4184
4185 if (Functions.empty())
4186 return PreservedAnalyses::all();
4187
4188 Module &M = *Functions.back()->getParent();
4189 CallGraphUpdater CGUpdater;
4190 CGUpdater.initialize(CG, C, AM, UR);
4191 BumpPtrAllocator Allocator;
4192 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
4193 if (runAttributorOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4194 /* DeleteFns */ false,
4195 /* IsModulePass */ false)) {
4196 // FIXME: Think about passes we will preserve and add them here.
4199 return PA;
4200 }
4201 return PreservedAnalyses::all();
4202}
4203
4208 AnalysisGetter AG(FAM, /* CachedOnly */ true);
4209
4210 SetVector<Function *> Functions;
4211 Functions.reserve(M.size());
4212 for (Function &F : M)
4213 Functions.insert(&F);
4214
4215 CallGraphUpdater CGUpdater;
4216 BumpPtrAllocator Allocator;
4217 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);
4218 if (runAttributorLightOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4219 /* IsModulePass */ true)) {
4221 // We have not added or removed functions.
4223 // We already invalidated all relevant function analyses above.
4225 return PA;
4226 }
4227 return PreservedAnalyses::all();
4228}
4229
4232 LazyCallGraph &CG,
4233 CGSCCUpdateResult &UR) {
4235 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
4236 AnalysisGetter AG(FAM);
4237
4238 SetVector<Function *> Functions;
4239 for (LazyCallGraph::Node &N : C)
4240 Functions.insert(&N.getFunction());
4241
4242 if (Functions.empty())
4243 return PreservedAnalyses::all();
4244
4245 Module &M = *Functions.back()->getParent();
4246 CallGraphUpdater CGUpdater;
4247 CGUpdater.initialize(CG, C, AM, UR);
4248 BumpPtrAllocator Allocator;
4249 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
4250 if (runAttributorLightOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4251 /* IsModulePass */ false)) {
4253 // We have not added or removed functions.
4255 // We already invalidated all relevant function analyses above.
4257 return PA;
4258 }
4259 return PreservedAnalyses::all();
4260}
4261namespace llvm {
4262
4279
4280template <>
4282 static NodeRef getEntryNode(AADepGraph *DG) { return DG->GetEntryNode(); }
4283
4286
4287 static nodes_iterator nodes_begin(AADepGraph *DG) { return DG->begin(); }
4288
4289 static nodes_iterator nodes_end(AADepGraph *DG) { return DG->end(); }
4290};
4291
4292template <> struct DOTGraphTraits<AADepGraph *> : public DefaultDOTGraphTraits {
4294
4295 static std::string getNodeLabel(const AADepGraphNode *Node,
4296 const AADepGraph *DG) {
4297 std::string AAString;
4298 raw_string_ostream O(AAString);
4299 Node->print(O);
4300 return AAString;
4301 }
4302};
4303
4304} // 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
A set of kinds of abstract attributes, given by their IDs.
static constexpr AAKindSet get()
Return the set of the kinds with the IDs KindIDs.
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.
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
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
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
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:2657
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...
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
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:2592
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
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
virtual bool isStateAtFixpoint() const
Return true if the state is at a fixpoint, like getState().isAtFixpoint() but with a single virtual c...
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:839
unsigned getAttrIdx() const
Return the index in the attribute list for this position.
Definition Attributor.h:804
bool hasCallBaseContext() const
Check if the position has any call base context.
Definition Attributor.h:899
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:832
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:896
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:825
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:799
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:846
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.