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