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 Attribute Existing = AttrSet.getAttribute(Attr.getKindAsString());
1021 if (Existing.isValid() && (!ForceReplace || Existing == Attr))
1022 return false;
1023 AB.addAttribute(Attr);
1024 return true;
1025 }
1026 if (Attr.isIntAttribute()) {
1027 Attribute::AttrKind Kind = Attr.getKindAsEnum();
1028 if (!ForceReplace && Kind == Attribute::Memory) {
1029 MemoryEffects ME = Attr.getMemoryEffects() & AttrSet.getMemoryEffects();
1030 if (ME == AttrSet.getMemoryEffects())
1031 return false;
1032 AB.addMemoryAttr(ME);
1033 return true;
1034 }
1035 if (AttrSet.hasAttribute(Kind)) {
1036 if (!ForceReplace && isEqualOrWorse(Attr, AttrSet.getAttribute(Kind)))
1037 return false;
1038 }
1039 AB.addAttribute(Attr);
1040 return true;
1041 }
1042 if (Attr.isConstantRangeAttribute()) {
1043 Attribute::AttrKind Kind = Attr.getKindAsEnum();
1044 if (!ForceReplace && AttrSet.hasAttribute(Kind))
1045 return false;
1046 AB.addAttribute(Attr);
1047 return true;
1048 }
1049
1050 llvm_unreachable("Expected enum or string attribute!");
1051}
1052
1055 return cast<Argument>(&getAnchorValue());
1056
1057 // Not an Argument and no argument number means this is not a call site
1058 // argument, thus we cannot find a callback argument to return.
1059 int ArgNo = getCallSiteArgNo();
1060 if (ArgNo < 0)
1061 return nullptr;
1062
1063 // Use abstract call sites to make the connection between the call site
1064 // values and the ones in callbacks. If a callback was found that makes use
1065 // of the underlying call site operand, we want the corresponding callback
1066 // callee argument and not the direct callee argument.
1067 std::optional<Argument *> CBCandidateArg;
1068 SmallVector<const Use *, 4> CallbackUses;
1069 const auto &CB = cast<CallBase>(getAnchorValue());
1070 AbstractCallSite::getCallbackUses(CB, CallbackUses);
1071 for (const Use *U : CallbackUses) {
1072 AbstractCallSite ACS(U);
1073 assert(ACS && ACS.isCallbackCall());
1074 if (!ACS.getCalledFunction())
1075 continue;
1076
1077 for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {
1078
1079 // Test if the underlying call site operand is argument number u of the
1080 // callback callee.
1081 if (ACS.getCallArgOperandNo(u) != ArgNo)
1082 continue;
1083
1084 assert(ACS.getCalledFunction()->arg_size() > u &&
1085 "ACS mapped into var-args arguments!");
1086 if (CBCandidateArg) {
1087 CBCandidateArg = nullptr;
1088 break;
1089 }
1090 CBCandidateArg = ACS.getCalledFunction()->getArg(u);
1091 }
1092 }
1093
1094 // If we found a unique callback candidate argument, return it.
1095 if (CBCandidateArg && *CBCandidateArg)
1096 return *CBCandidateArg;
1097
1098 // If no callbacks were found, or none used the underlying call site operand
1099 // exclusively, use the direct callee argument if available.
1100 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
1101 if (Callee && Callee->arg_size() > unsigned(ArgNo))
1102 return Callee->getArg(ArgNo);
1103
1104 return nullptr;
1105}
1106
1109 if (getState().isAtFixpoint())
1110 return HasChanged;
1111
1112 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
1113
1114 HasChanged = updateImpl(A);
1115
1116 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
1117 << "\n");
1118
1119 return HasChanged;
1120}
1121
1123 InformationCache &InfoCache,
1124 AttributorConfig Configuration)
1125 : Allocator(InfoCache.Allocator), Functions(Functions),
1126 InfoCache(InfoCache), Configuration(Configuration) {
1127 if (!isClosedWorldModule())
1128 return;
1129 for (Function *Fn : Functions)
1130 if (Fn->hasAddressTaken(/*PutOffender=*/nullptr,
1131 /*IgnoreCallbackUses=*/false,
1132 /*IgnoreAssumeLikeCalls=*/true,
1133 /*IgnoreLLVMUsed=*/true,
1134 /*IgnoreARCAttachedCall=*/false,
1135 /*IgnoreCastedDirectCall=*/true))
1136 InfoCache.IndirectlyCallableFunctions.push_back(Fn);
1137}
1138
1143 "Did expect a valid position!");
1146 if (!Explorer)
1147 return false;
1148
1149 Value &AssociatedValue = IRP.getAssociatedValue();
1150
1151 const Assume2KnowledgeMap &A2K =
1152 getInfoCache().getKnowledgeMap().lookup({&AssociatedValue, AK});
1153
1154 // Check if we found any potential assume use, if not we don't need to create
1155 // explorer iterators.
1156 if (A2K.empty())
1157 return false;
1158
1159 LLVMContext &Ctx = AssociatedValue.getContext();
1160 unsigned AttrsSize = Attrs.size();
1161 auto EIt = Explorer->begin(IRP.getCtxI()),
1162 EEnd = Explorer->end(IRP.getCtxI());
1163 for (const auto &It : A2K)
1164 if (Explorer->findInContextOf(It.first, EIt, EEnd))
1165 Attrs.push_back(Attribute::get(Ctx, AK, It.second.Max));
1166 return AttrsSize != Attrs.size();
1167}
1168
1169template <typename DescTy>
1171Attributor::updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,
1172 function_ref<bool(const DescTy &, AttributeSet,
1173 AttributeMask &, AttrBuilder &)>
1174 CB) {
1175 if (AttrDescs.empty())
1177 switch (IRP.getPositionKind()) {
1181 default:
1182 break;
1183 };
1184
1185 AttributeList AL = IRP.getAttrList();
1186 Value *AttrListAnchor = IRP.getAttrListAnchor();
1187 auto [Iter, Inserted] = AttrsMap.insert({AttrListAnchor, AL});
1188 if (!Inserted)
1189 AL = Iter->second;
1190
1191 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
1192 auto AttrIdx = IRP.getAttrIdx();
1193 AttributeSet AS = AL.getAttributes(AttrIdx);
1194 AttributeMask AM;
1195 AttrBuilder AB(Ctx);
1196
1198 for (const DescTy &AttrDesc : AttrDescs)
1199 if (CB(AttrDesc, AS, AM, AB))
1200 HasChanged = ChangeStatus::CHANGED;
1201
1202 if (HasChanged == ChangeStatus::UNCHANGED)
1204
1205 if (!AM.empty())
1206 AL = AL.removeAttributesAtIndex(Ctx, AttrIdx, AM);
1207 AL = AL.addAttributesAtIndex(Ctx, AttrIdx, AB);
1208
1209 Iter->second = AL;
1210 return HasChanged;
1211}
1212
1215 bool IgnoreSubsumingPositions,
1216 Attribute::AttrKind ImpliedAttributeKind) {
1217 bool Implied = false;
1218 bool HasAttr = false;
1219 auto HasAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,
1220 AttributeMask &, AttrBuilder &) {
1221 if (AttrSet.hasAttribute(Kind)) {
1222 Implied |= Kind != ImpliedAttributeKind;
1223 HasAttr = true;
1224 }
1225 return false;
1226 };
1227 for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {
1228 updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, HasAttrCB);
1229 if (HasAttr)
1230 break;
1231 // The first position returned by the SubsumingPositionIterator is
1232 // always the position itself. If we ignore subsuming positions we
1233 // are done after the first iteration.
1234 if (IgnoreSubsumingPositions)
1235 break;
1236 Implied = true;
1237 }
1238 if (!HasAttr) {
1239 Implied = true;
1241 for (Attribute::AttrKind AK : AttrKinds)
1242 if (getAttrsFromAssumes(IRP, AK, Attrs)) {
1243 HasAttr = true;
1244 break;
1245 }
1246 }
1247
1248 // Check if we should manifest the implied attribute kind at the IRP.
1249 if (ImpliedAttributeKind != Attribute::None && HasAttr && Implied)
1251 ImpliedAttributeKind)});
1252 return HasAttr;
1253}
1254
1258 bool IgnoreSubsumingPositions) {
1259 auto CollectAttrCB = [&](const Attribute::AttrKind &Kind,
1260 AttributeSet AttrSet, AttributeMask &,
1261 AttrBuilder &) {
1262 if (AttrSet.hasAttribute(Kind))
1263 Attrs.push_back(AttrSet.getAttribute(Kind));
1264 return false;
1265 };
1266 for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {
1267 updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, CollectAttrCB);
1268 // The first position returned by the SubsumingPositionIterator is
1269 // always the position itself. If we ignore subsuming positions we
1270 // are done after the first iteration.
1271 if (IgnoreSubsumingPositions)
1272 break;
1273 }
1274 for (Attribute::AttrKind AK : AttrKinds)
1275 getAttrsFromAssumes(IRP, AK, Attrs);
1276}
1277
1280 auto RemoveAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,
1281 AttributeMask &AM, AttrBuilder &) {
1282 if (!AttrSet.hasAttribute(Kind))
1283 return false;
1284 AM.addAttribute(Kind);
1285 return true;
1286 };
1287 return updateAttrMap<Attribute::AttrKind>(IRP, AttrKinds, RemoveAttrCB);
1288}
1289
1291 ArrayRef<StringRef> Attrs) {
1292 auto RemoveAttrCB = [&](StringRef Attr, AttributeSet AttrSet,
1293 AttributeMask &AM, AttrBuilder &) -> bool {
1294 if (!AttrSet.hasAttribute(Attr))
1295 return false;
1296 AM.addAttribute(Attr);
1297 return true;
1298 };
1299
1300 return updateAttrMap<StringRef>(IRP, Attrs, RemoveAttrCB);
1301}
1302
1304 ArrayRef<Attribute> Attrs,
1305 bool ForceReplace) {
1306 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
1307 auto AddAttrCB = [&](const Attribute &Attr, AttributeSet AttrSet,
1308 AttributeMask &, AttrBuilder &AB) {
1309 return addIfNotExistent(Ctx, Attr, AttrSet, ForceReplace, AB);
1310 };
1311 return updateAttrMap<Attribute>(IRP, Attrs, AddAttrCB);
1312}
1313
1315 IRPositions.emplace_back(IRP);
1316
1317 // Helper to determine if operand bundles on a call site are benign or
1318 // potentially problematic. We handle only llvm.assume for now.
1319 auto CanIgnoreOperandBundles = [](const CallBase &CB) {
1320 return (isa<IntrinsicInst>(CB) &&
1321 cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);
1322 };
1323
1324 const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue());
1325 switch (IRP.getPositionKind()) {
1329 return;
1332 IRPositions.emplace_back(IRPosition::function(*IRP.getAnchorScope()));
1333 return;
1335 assert(CB && "Expected call site!");
1336 // TODO: We need to look at the operand bundles similar to the redirection
1337 // in CallBase.
1338 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))
1339 if (auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()))
1340 IRPositions.emplace_back(IRPosition::function(*Callee));
1341 return;
1343 assert(CB && "Expected call site!");
1344 // TODO: We need to look at the operand bundles similar to the redirection
1345 // in CallBase.
1346 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
1347 if (auto *Callee =
1348 dyn_cast_if_present<Function>(CB->getCalledOperand())) {
1349 IRPositions.emplace_back(IRPosition::returned(*Callee));
1350 IRPositions.emplace_back(IRPosition::function(*Callee));
1351 for (const Argument &Arg : Callee->args())
1352 if (Arg.hasReturnedAttr()) {
1353 IRPositions.emplace_back(
1354 IRPosition::callsite_argument(*CB, Arg.getArgNo()));
1355 IRPositions.emplace_back(
1356 IRPosition::value(*CB->getArgOperand(Arg.getArgNo())));
1357 IRPositions.emplace_back(IRPosition::argument(Arg));
1358 }
1359 }
1360 }
1361 IRPositions.emplace_back(IRPosition::callsite_function(*CB));
1362 return;
1364 assert(CB && "Expected call site!");
1365 // TODO: We need to look at the operand bundles similar to the redirection
1366 // in CallBase.
1367 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
1368 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
1369 if (Callee) {
1370 if (Argument *Arg = IRP.getAssociatedArgument())
1371 IRPositions.emplace_back(IRPosition::argument(*Arg));
1372 IRPositions.emplace_back(IRPosition::function(*Callee));
1373 }
1374 }
1375 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
1376 return;
1377 }
1378 }
1379}
1380
1381void IRPosition::verify() {
1382#ifdef EXPENSIVE_CHECKS
1383 switch (getPositionKind()) {
1384 case IRP_INVALID:
1385 assert((CBContext == nullptr) &&
1386 "Invalid position must not have CallBaseContext!");
1387 assert(!Enc.getOpaqueValue() &&
1388 "Expected a nullptr for an invalid position!");
1389 return;
1390 case IRP_FLOAT:
1392 "Expected specialized kind for argument values!");
1393 return;
1394 case IRP_RETURNED:
1395 assert(isa<Function>(getAsValuePtr()) &&
1396 "Expected function for a 'returned' position!");
1397 assert(getAsValuePtr() == &getAssociatedValue() &&
1398 "Associated value mismatch!");
1399 return;
1401 assert((CBContext == nullptr) &&
1402 "'call site returned' position must not have CallBaseContext!");
1403 assert((isa<CallBase>(getAsValuePtr())) &&
1404 "Expected call base for 'call site returned' position!");
1405 assert(getAsValuePtr() == &getAssociatedValue() &&
1406 "Associated value mismatch!");
1407 return;
1408 case IRP_CALL_SITE:
1409 assert((CBContext == nullptr) &&
1410 "'call site function' position must not have CallBaseContext!");
1411 assert((isa<CallBase>(getAsValuePtr())) &&
1412 "Expected call base for 'call site function' position!");
1413 assert(getAsValuePtr() == &getAssociatedValue() &&
1414 "Associated value mismatch!");
1415 return;
1416 case IRP_FUNCTION:
1417 assert(isa<Function>(getAsValuePtr()) &&
1418 "Expected function for a 'function' position!");
1419 assert(getAsValuePtr() == &getAssociatedValue() &&
1420 "Associated value mismatch!");
1421 return;
1422 case IRP_ARGUMENT:
1423 assert(isa<Argument>(getAsValuePtr()) &&
1424 "Expected argument for a 'argument' position!");
1425 assert(getAsValuePtr() == &getAssociatedValue() &&
1426 "Associated value mismatch!");
1427 return;
1429 assert((CBContext == nullptr) &&
1430 "'call site argument' position must not have CallBaseContext!");
1431 Use *U = getAsUsePtr();
1432 (void)U; // Silence unused variable warning.
1433 assert(U && "Expected use for a 'call site argument' position!");
1434 assert(isa<CallBase>(U->getUser()) &&
1435 "Expected call base user for a 'call site argument' position!");
1436 assert(cast<CallBase>(U->getUser())->isArgOperand(U) &&
1437 "Expected call base argument operand for a 'call site argument' "
1438 "position");
1439 assert(cast<CallBase>(U->getUser())->getArgOperandNo(U) ==
1440 unsigned(getCallSiteArgNo()) &&
1441 "Argument number mismatch!");
1442 assert(U->get() == &getAssociatedValue() && "Associated value mismatch!");
1443 return;
1444 }
1445 }
1446#endif
1447}
1448
1449std::optional<Constant *>
1451 const AbstractAttribute &AA,
1452 bool &UsedAssumedInformation) {
1453 // First check all callbacks provided by outside AAs. If any of them returns
1454 // a non-null value that is different from the associated value, or
1455 // std::nullopt, we assume it's simplified.
1456 for (auto &CB : SimplificationCallbacks.lookup(IRP)) {
1457 std::optional<Value *> SimplifiedV = CB(IRP, &AA, UsedAssumedInformation);
1458 if (!SimplifiedV)
1459 return std::nullopt;
1460 if (isa_and_nonnull<Constant>(*SimplifiedV))
1461 return cast<Constant>(*SimplifiedV);
1462 return nullptr;
1463 }
1464 if (auto *C = dyn_cast<Constant>(&IRP.getAssociatedValue()))
1465 return C;
1469 UsedAssumedInformation)) {
1470 if (Values.empty())
1471 return std::nullopt;
1472 if (auto *C = dyn_cast_or_null<Constant>(
1474 return C;
1475 }
1476 return nullptr;
1477}
1478
1480 const IRPosition &IRP, const AbstractAttribute *AA,
1481 bool &UsedAssumedInformation, AA::ValueScope S) {
1482 // First check all callbacks provided by outside AAs. If any of them returns
1483 // a non-null value that is different from the associated value, or
1484 // std::nullopt, we assume it's simplified.
1485 for (auto &CB : SimplificationCallbacks.lookup(IRP))
1486 return CB(IRP, AA, UsedAssumedInformation);
1487
1489 if (!getAssumedSimplifiedValues(IRP, AA, Values, S, UsedAssumedInformation))
1490 return &IRP.getAssociatedValue();
1491 if (Values.empty())
1492 return std::nullopt;
1493 if (AA)
1494 if (Value *V = AAPotentialValues::getSingleValue(*this, *AA, IRP, Values))
1495 return V;
1498 return nullptr;
1499 return &IRP.getAssociatedValue();
1500}
1501
1503 const IRPosition &InitialIRP, const AbstractAttribute *AA,
1505 bool &UsedAssumedInformation, bool RecurseForSelectAndPHI) {
1508 Worklist.push_back(InitialIRP);
1509 while (!Worklist.empty()) {
1510 const IRPosition &IRP = Worklist.pop_back_val();
1511
1512 // First check all callbacks provided by outside AAs. If any of them returns
1513 // a non-null value that is different from the associated value, or
1514 // std::nullopt, we assume it's simplified.
1515 int NV = Values.size();
1516 const auto &SimplificationCBs = SimplificationCallbacks.lookup(IRP);
1517 for (const auto &CB : SimplificationCBs) {
1518 std::optional<Value *> CBResult = CB(IRP, AA, UsedAssumedInformation);
1519 if (!CBResult.has_value())
1520 continue;
1521 Value *V = *CBResult;
1522 if (!V)
1523 return false;
1526 Values.push_back(AA::ValueAndContext{*V, nullptr});
1527 else
1528 return false;
1529 }
1530 if (SimplificationCBs.empty()) {
1531 // If no high-level/outside simplification occurred, use
1532 // AAPotentialValues.
1533 const auto *PotentialValuesAA =
1535 if (PotentialValuesAA &&
1536 PotentialValuesAA->getAssumedSimplifiedValues(*this, Values, S)) {
1537 UsedAssumedInformation |= !PotentialValuesAA->isAtFixpoint();
1538 } else if (IRP.getPositionKind() != IRPosition::IRP_RETURNED) {
1539 Values.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
1540 } else {
1541 // TODO: We could visit all returns and add the operands.
1542 return false;
1543 }
1544 }
1545
1546 if (!RecurseForSelectAndPHI)
1547 break;
1548
1549 for (int I = NV, E = Values.size(); I < E; ++I) {
1550 Value *V = Values[I].getValue();
1551 if (!isa<PHINode>(V) && !isa<SelectInst>(V))
1552 continue;
1553 if (!Seen.insert(V).second)
1554 continue;
1555 // Move the last element to this slot.
1556 Values[I] = Values[E - 1];
1557 // Eliminate the last slot, adjust the indices.
1558 Values.pop_back();
1559 --E;
1560 --I;
1561 // Add a new value (select or phi) to the worklist.
1562 Worklist.push_back(IRPosition::value(*V));
1563 }
1564 }
1565 return true;
1566}
1567
1569 std::optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,
1570 bool &UsedAssumedInformation) {
1571 if (!V)
1572 return V;
1573 if (*V == nullptr || isa<Constant>(*V))
1574 return V;
1575 if (auto *Arg = dyn_cast<Argument>(*V))
1576 if (CB.getCalledOperand() == Arg->getParent() &&
1577 CB.arg_size() > Arg->getArgNo())
1578 if (!Arg->hasPointeeInMemoryValueAttr())
1579 return getAssumedSimplified(
1580 IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,
1581 UsedAssumedInformation, AA::Intraprocedural);
1582 return nullptr;
1583}
1584
1586 // The abstract attributes are allocated via the BumpPtrAllocator Allocator,
1587 // thus we cannot delete them. We can, and want to, destruct them though.
1588 for (auto &It : AAMap) {
1589 AbstractAttribute *AA = It.getSecond();
1590 AA->~AbstractAttribute();
1591 }
1592}
1593
1595 const AAIsDead *FnLivenessAA,
1596 bool &UsedAssumedInformation,
1597 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1598 if (!Configuration.UseLiveness)
1599 return false;
1600 const IRPosition &IRP = AA.getIRPosition();
1601 if (!Functions.count(IRP.getAnchorScope()))
1602 return false;
1603 return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,
1604 CheckBBLivenessOnly, DepClass);
1605}
1606
1608 const AbstractAttribute *QueryingAA,
1609 const AAIsDead *FnLivenessAA,
1610 bool &UsedAssumedInformation,
1611 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1612 if (!Configuration.UseLiveness)
1613 return false;
1614 Instruction *UserI = dyn_cast<Instruction>(U.getUser());
1615 if (!UserI)
1616 return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
1617 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1618
1619 if (auto *CB = dyn_cast<CallBase>(UserI)) {
1620 // For call site argument uses we can check if the argument is
1621 // unused/dead.
1622 if (CB->isArgOperand(&U)) {
1623 const IRPosition &CSArgPos =
1624 IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
1625 return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
1626 UsedAssumedInformation, CheckBBLivenessOnly,
1627 DepClass);
1628 }
1629 } else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
1630 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
1631 return isAssumedDead(RetPos, QueryingAA, FnLivenessAA,
1632 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1633 } else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
1634 BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
1635 return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
1636 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1637 } else if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) {
1638 if (!CheckBBLivenessOnly && SI->getPointerOperand() != U.get()) {
1639 const IRPosition IRP = IRPosition::inst(*SI);
1640 const AAIsDead *IsDeadAA =
1642 if (IsDeadAA && IsDeadAA->isRemovableStore()) {
1643 if (QueryingAA)
1644 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1645 if (!IsDeadAA->isKnown(AAIsDead::IS_REMOVABLE))
1646 UsedAssumedInformation = true;
1647 return true;
1648 }
1649 }
1650 }
1651
1652 return isAssumedDead(IRPosition::inst(*UserI), QueryingAA, FnLivenessAA,
1653 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1654}
1655
1657 const AbstractAttribute *QueryingAA,
1658 const AAIsDead *FnLivenessAA,
1659 bool &UsedAssumedInformation,
1660 bool CheckBBLivenessOnly, DepClassTy DepClass,
1661 bool CheckForDeadStore) {
1662 if (!Configuration.UseLiveness)
1663 return false;
1664 const IRPosition::CallBaseContext *CBCtx =
1665 QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;
1666
1667 if (ManifestAddedBlocks.contains(I.getParent()))
1668 return false;
1669
1670 const Function &F = *I.getFunction();
1671 if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)
1672 FnLivenessAA = getOrCreateAAFor<AAIsDead>(IRPosition::function(F, CBCtx),
1673 QueryingAA, DepClassTy::NONE);
1674
1675 // Don't use recursive reasoning.
1676 if (!FnLivenessAA || QueryingAA == FnLivenessAA)
1677 return false;
1678
1679 // If we have a context instruction and a liveness AA we use it.
1680 if (CheckBBLivenessOnly ? FnLivenessAA->isAssumedDead(I.getParent())
1681 : FnLivenessAA->isAssumedDead(&I)) {
1682 if (QueryingAA)
1683 recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
1684 if (!FnLivenessAA->isKnownDead(&I))
1685 UsedAssumedInformation = true;
1686 return true;
1687 }
1688
1689 if (CheckBBLivenessOnly)
1690 return false;
1691
1692 const IRPosition IRP = IRPosition::inst(I, CBCtx);
1693 const AAIsDead *IsDeadAA =
1695
1696 // Don't use recursive reasoning.
1697 if (!IsDeadAA || QueryingAA == IsDeadAA)
1698 return false;
1699
1700 if (IsDeadAA->isAssumedDead()) {
1701 if (QueryingAA)
1702 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1703 if (!IsDeadAA->isKnownDead())
1704 UsedAssumedInformation = true;
1705 return true;
1706 }
1707
1708 if (CheckForDeadStore && isa<StoreInst>(I) && IsDeadAA->isRemovableStore()) {
1709 if (QueryingAA)
1710 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1711 if (!IsDeadAA->isKnownDead())
1712 UsedAssumedInformation = true;
1713 return true;
1714 }
1715
1716 return false;
1717}
1718
1720 const AbstractAttribute *QueryingAA,
1721 const AAIsDead *FnLivenessAA,
1722 bool &UsedAssumedInformation,
1723 bool CheckBBLivenessOnly, DepClassTy DepClass) {
1724 if (!Configuration.UseLiveness)
1725 return false;
1726 // Don't check liveness for constants, e.g. functions, used as (floating)
1727 // values since the context instruction and such is here meaningless.
1730 return false;
1731 }
1732
1733 Instruction *CtxI = IRP.getCtxI();
1734 if (CtxI &&
1735 isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,
1736 /* CheckBBLivenessOnly */ true,
1737 CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
1738 return true;
1739
1740 if (CheckBBLivenessOnly)
1741 return false;
1742
1743 // If we haven't succeeded we query the specific liveness info for the IRP.
1744 const AAIsDead *IsDeadAA;
1746 IsDeadAA = getOrCreateAAFor<AAIsDead>(
1748 QueryingAA, DepClassTy::NONE);
1749 else
1750 IsDeadAA = getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);
1751
1752 // Don't use recursive reasoning.
1753 if (!IsDeadAA || QueryingAA == IsDeadAA)
1754 return false;
1755
1756 if (IsDeadAA->isAssumedDead()) {
1757 if (QueryingAA)
1758 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1759 if (!IsDeadAA->isKnownDead())
1760 UsedAssumedInformation = true;
1761 return true;
1762 }
1763
1764 return false;
1765}
1766
1768 const AbstractAttribute *QueryingAA,
1769 const AAIsDead *FnLivenessAA,
1770 DepClassTy DepClass) {
1771 if (!Configuration.UseLiveness)
1772 return false;
1773 const Function &F = *BB.getParent();
1774 if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)
1776 QueryingAA, DepClassTy::NONE);
1777
1778 // Don't use recursive reasoning.
1779 if (!FnLivenessAA || QueryingAA == FnLivenessAA)
1780 return false;
1781
1782 if (FnLivenessAA->isAssumedDead(&BB)) {
1783 if (QueryingAA)
1784 recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
1785 return true;
1786 }
1787
1788 return false;
1789}
1790
1793 const AbstractAttribute &QueryingAA, const CallBase &CB) {
1794 if (const Function *Callee = dyn_cast<Function>(CB.getCalledOperand()))
1795 return Pred(Callee);
1796
1797 const auto *CallEdgesAA = getAAFor<AACallEdges>(
1799 if (!CallEdgesAA || CallEdgesAA->hasUnknownCallee())
1800 return false;
1801
1802 const auto &Callees = CallEdgesAA->getOptimisticEdges();
1803 return Pred(Callees.getArrayRef());
1804}
1805
1806bool canMarkAsVisited(const User *Usr) {
1807 return isa<PHINode>(Usr) || !isa<Instruction>(Usr);
1808}
1809
1811 function_ref<bool(const Use &, bool &)> Pred,
1812 const AbstractAttribute &QueryingAA, const Value &V,
1813 bool CheckBBLivenessOnly, DepClassTy LivenessDepClass,
1814 bool IgnoreDroppableUses,
1815 function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB) {
1816
1817 // Check virtual uses first.
1818 for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&V))
1819 if (!CB(*this, &QueryingAA))
1820 return false;
1821
1822 if (isa<ConstantData>(V))
1823 return false;
1824
1825 // Check the trivial case first as it catches void values.
1826 if (V.use_empty())
1827 return true;
1828
1829 const IRPosition &IRP = QueryingAA.getIRPosition();
1832
1833 auto AddUsers = [&](const Value &V, const Use *OldUse) {
1834 for (const Use &UU : V.uses()) {
1835 if (OldUse && EquivalentUseCB && !EquivalentUseCB(*OldUse, UU)) {
1836 LLVM_DEBUG(dbgs() << "[Attributor] Potential copy was "
1837 "rejected by the equivalence call back: "
1838 << *UU << "!\n");
1839 return false;
1840 }
1841
1842 Worklist.push_back(&UU);
1843 }
1844 return true;
1845 };
1846
1847 AddUsers(V, /* OldUse */ nullptr);
1848
1849 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
1850 << " initial uses to check\n");
1851
1852 const Function *ScopeFn = IRP.getAnchorScope();
1853 const auto *LivenessAA =
1854 ScopeFn ? getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
1856 : nullptr;
1857
1858 while (!Worklist.empty()) {
1859 const Use *U = Worklist.pop_back_val();
1860 if (canMarkAsVisited(U->getUser()) && !Visited.insert(U).second)
1861 continue;
1863 if (auto *Fn = dyn_cast<Function>(U->getUser()))
1864 dbgs() << "[Attributor] Check use: " << **U << " in " << Fn->getName()
1865 << "\n";
1866 else
1867 dbgs() << "[Attributor] Check use: " << **U << " in " << *U->getUser()
1868 << "\n";
1869 });
1870 bool UsedAssumedInformation = false;
1871 if (isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,
1872 CheckBBLivenessOnly, LivenessDepClass)) {
1874 dbgs() << "[Attributor] Dead use, skip!\n");
1875 continue;
1876 }
1877 if (IgnoreDroppableUses && U->getUser()->isDroppable()) {
1879 dbgs() << "[Attributor] Droppable user, skip!\n");
1880 continue;
1881 }
1882
1883 if (auto *SI = dyn_cast<StoreInst>(U->getUser())) {
1884 if (&SI->getOperandUse(0) == U) {
1885 if (!Visited.insert(U).second)
1886 continue;
1887 SmallSetVector<Value *, 4> PotentialCopies;
1889 *this, *SI, PotentialCopies, QueryingAA, UsedAssumedInformation,
1890 /* OnlyExact */ true)) {
1892 dbgs()
1893 << "[Attributor] Value is stored, continue with "
1894 << PotentialCopies.size()
1895 << " potential copies instead!\n");
1896 for (Value *PotentialCopy : PotentialCopies)
1897 if (!AddUsers(*PotentialCopy, U))
1898 return false;
1899 continue;
1900 }
1901 }
1902 }
1903
1904 bool Follow = false;
1905 if (!Pred(*U, Follow))
1906 return false;
1907 if (!Follow)
1908 continue;
1909
1910 User &Usr = *U->getUser();
1911 AddUsers(Usr, /* OldUse */ nullptr);
1912 }
1913
1914 return true;
1915}
1916
1918 const AbstractAttribute &QueryingAA,
1919 bool RequireAllCallSites,
1920 bool &UsedAssumedInformation) {
1921 // We can try to determine information from
1922 // the call sites. However, this is only possible all call sites are known,
1923 // hence the function has internal linkage.
1924 const IRPosition &IRP = QueryingAA.getIRPosition();
1925 const Function *AssociatedFunction = IRP.getAssociatedFunction();
1926 if (!AssociatedFunction) {
1927 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
1928 << "\n");
1929 return false;
1930 }
1931
1932 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
1933 &QueryingAA, UsedAssumedInformation);
1934}
1935
1937 const Function &Fn,
1938 bool RequireAllCallSites,
1939 const AbstractAttribute *QueryingAA,
1940 bool &UsedAssumedInformation,
1941 bool CheckPotentiallyDead) {
1942 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
1943 LLVM_DEBUG(
1944 dbgs()
1945 << "[Attributor] Function " << Fn.getName()
1946 << " has no internal linkage, hence not all call sites are known\n");
1947 return false;
1948 }
1949 // Check virtual uses first.
1950 for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&Fn))
1951 if (!CB(*this, QueryingAA))
1952 return false;
1953
1955 for (unsigned u = 0; u < Uses.size(); ++u) {
1956 const Use &U = *Uses[u];
1958 if (auto *Fn = dyn_cast<Function>(U))
1959 dbgs() << "[Attributor] Check use: " << Fn->getName() << " in "
1960 << *U.getUser() << "\n";
1961 else
1962 dbgs() << "[Attributor] Check use: " << *U << " in " << *U.getUser()
1963 << "\n";
1964 });
1965 if (!CheckPotentiallyDead &&
1966 isAssumedDead(U, QueryingAA, nullptr, UsedAssumedInformation,
1967 /* CheckBBLivenessOnly */ true)) {
1969 dbgs() << "[Attributor] Dead use, skip!\n");
1970 continue;
1971 }
1972 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
1973 if (CE->isCast() && CE->getType()->isPointerTy()) {
1975 dbgs() << "[Attributor] Use, is constant cast expression, add "
1976 << CE->getNumUses() << " uses of that expression instead!\n";
1977 });
1978 for (const Use &CEU : CE->uses())
1979 Uses.push_back(&CEU);
1980 continue;
1981 }
1982 }
1983
1984 AbstractCallSite ACS(&U);
1985 if (!ACS) {
1986 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
1987 << " has non call site use " << *U.get() << " in "
1988 << *U.getUser() << "\n");
1989 return false;
1990 }
1991
1992 const Use *EffectiveUse =
1993 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
1994 if (!ACS.isCallee(EffectiveUse)) {
1995 if (!RequireAllCallSites) {
1996 LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()
1997 << " is not a call of " << Fn.getName()
1998 << ", skip use\n");
1999 continue;
2000 }
2001 LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()
2002 << " is an invalid use of " << Fn.getName() << "\n");
2003 return false;
2004 }
2005
2006 // Make sure the arguments that can be matched between the call site and the
2007 // callee argee on their type. It is unlikely they do not and it doesn't
2008 // make sense for all attributes to know/care about this.
2009 assert(&Fn == ACS.getCalledFunction() && "Expected known callee");
2010 unsigned MinArgsParams =
2011 std::min(size_t(ACS.getNumArgOperands()), Fn.arg_size());
2012 for (unsigned u = 0; u < MinArgsParams; ++u) {
2013 Value *CSArgOp = ACS.getCallArgOperand(u);
2014 if (CSArgOp && Fn.getArg(u)->getType() != CSArgOp->getType()) {
2015 LLVM_DEBUG(
2016 dbgs() << "[Attributor] Call site / callee argument type mismatch ["
2017 << u << "@" << Fn.getName() << ": "
2018 << *Fn.getArg(u)->getType() << " vs. "
2019 << *ACS.getCallArgOperand(u)->getType() << "\n");
2020 return false;
2021 }
2022 }
2023
2024 if (Pred(ACS))
2025 continue;
2026
2027 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
2028 << *ACS.getInstruction() << "\n");
2029 return false;
2030 }
2031
2032 return true;
2033}
2034
2035bool Attributor::shouldPropagateCallBaseContext(const IRPosition &IRP) {
2036 // TODO: Maintain a cache of Values that are
2037 // on the pathway from a Argument to a Instruction that would effect the
2038 // liveness/return state etc.
2040}
2041
2043 const AbstractAttribute &QueryingAA,
2045 bool RecurseForSelectAndPHI) {
2046
2047 const IRPosition &IRP = QueryingAA.getIRPosition();
2048 const Function *AssociatedFunction = IRP.getAssociatedFunction();
2049 if (!AssociatedFunction)
2050 return false;
2051
2052 bool UsedAssumedInformation = false;
2055 IRPosition::returned(*AssociatedFunction), &QueryingAA, Values, S,
2056 UsedAssumedInformation, RecurseForSelectAndPHI))
2057 return false;
2058
2059 return llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
2060 return Pred(*VAC.getValue());
2061 });
2062}
2063
2066 function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,
2067 const AAIsDead *LivenessAA, ArrayRef<unsigned> Opcodes,
2068 bool &UsedAssumedInformation, bool CheckBBLivenessOnly = false,
2069 bool CheckPotentiallyDead = false) {
2070 for (unsigned Opcode : Opcodes) {
2071 // Check if we have instructions with this opcode at all first.
2072 auto *Insts = OpcodeInstMap.lookup(Opcode);
2073 if (!Insts)
2074 continue;
2075
2076 for (Instruction *I : *Insts) {
2077 // Skip dead instructions.
2078 if (A && !CheckPotentiallyDead &&
2079 A->isAssumedDead(IRPosition::inst(*I), QueryingAA, LivenessAA,
2080 UsedAssumedInformation, CheckBBLivenessOnly)) {
2082 dbgs() << "[Attributor] Instruction " << *I
2083 << " is potentially dead, skip!\n";);
2084 continue;
2085 }
2086
2087 if (!Pred(*I))
2088 return false;
2089 }
2090 }
2091 return true;
2092}
2093
2095 const Function *Fn,
2096 const AbstractAttribute *QueryingAA,
2097 ArrayRef<unsigned> Opcodes,
2098 bool &UsedAssumedInformation,
2099 bool CheckBBLivenessOnly,
2100 bool CheckPotentiallyDead) {
2101 // Since we need to provide instructions we have to have an exact definition.
2102 if (!Fn || Fn->isDeclaration())
2103 return false;
2104
2105 const IRPosition &QueryIRP = IRPosition::function(*Fn);
2106 const auto *LivenessAA =
2107 CheckPotentiallyDead && QueryingAA
2108 ? (getAAFor<AAIsDead>(*QueryingAA, QueryIRP, DepClassTy::NONE))
2109 : nullptr;
2110
2111 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
2112 if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, QueryingAA,
2113 LivenessAA, Opcodes, UsedAssumedInformation,
2114 CheckBBLivenessOnly, CheckPotentiallyDead))
2115 return false;
2116
2117 return true;
2118}
2119
2121 const AbstractAttribute &QueryingAA,
2122 ArrayRef<unsigned> Opcodes,
2123 bool &UsedAssumedInformation,
2124 bool CheckBBLivenessOnly,
2125 bool CheckPotentiallyDead) {
2126 const IRPosition &IRP = QueryingAA.getIRPosition();
2127 const Function *AssociatedFunction = IRP.getAssociatedFunction();
2128 return checkForAllInstructions(Pred, AssociatedFunction, &QueryingAA, Opcodes,
2129 UsedAssumedInformation, CheckBBLivenessOnly,
2130 CheckPotentiallyDead);
2131}
2132
2134 function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA,
2135 bool &UsedAssumedInformation) {
2136 TimeTraceScope TS("checkForAllReadWriteInstructions");
2137
2138 const Function *AssociatedFunction =
2139 QueryingAA.getIRPosition().getAssociatedFunction();
2140 if (!AssociatedFunction)
2141 return false;
2142
2143 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
2144 const auto *LivenessAA =
2145 getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE);
2146
2147 for (Instruction *I :
2148 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
2149 // Skip dead instructions.
2150 if (isAssumedDead(IRPosition::inst(*I), &QueryingAA, LivenessAA,
2151 UsedAssumedInformation))
2152 continue;
2153
2154 if (!Pred(*I))
2155 return false;
2156 }
2157
2158 return true;
2159}
2160
2161void Attributor::runTillFixpoint() {
2162 TimeTraceScope TimeScope("Attributor::runTillFixpoint");
2163 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
2164 << DG.SyntheticRoot.Deps.size()
2165 << " abstract attributes.\n");
2166
2167 // Now that all abstract attributes are collected and initialized we start
2168 // the abstract analysis.
2169
2170 unsigned IterationCounter = 1;
2171 unsigned MaxIterations =
2172 Configuration.MaxFixpointIterations.value_or(SetFixpointIterations);
2173
2175 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
2176 Worklist.insert_range(DG.SyntheticRoot);
2177
2178 do {
2179 // Remember the size to determine new attributes.
2180 size_t NumAAs = DG.SyntheticRoot.Deps.size();
2181 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
2182 << ", Worklist size: " << Worklist.size() << "\n");
2183
2184 // For invalid AAs we can fix dependent AAs that have a required dependence,
2185 // thereby folding long dependence chains in a single step without the need
2186 // to run updates.
2187 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
2188 AbstractAttribute *InvalidAA = InvalidAAs[u];
2189
2190 // Check the dependences to fast track invalidation.
2192 dbgs() << "[Attributor] InvalidAA: " << *InvalidAA
2193 << " has " << InvalidAA->Deps.size()
2194 << " required & optional dependences\n");
2195 for (auto &DepIt : InvalidAA->Deps) {
2196 AbstractAttribute *DepAA = cast<AbstractAttribute>(DepIt.getPointer());
2197 if (DepIt.getInt() == unsigned(DepClassTy::OPTIONAL)) {
2199 dbgs() << " - recompute: " << *DepAA);
2200 Worklist.insert(DepAA);
2201 continue;
2202 }
2204 << " - invalidate: " << *DepAA);
2206 assert(DepAA->getState().isAtFixpoint() && "Expected fixpoint state!");
2207 if (!DepAA->getState().isValidState())
2208 InvalidAAs.insert(DepAA);
2209 else
2210 ChangedAAs.push_back(DepAA);
2211 }
2212 InvalidAA->Deps.clear();
2213 }
2214
2215 // Add all abstract attributes that are potentially dependent on one that
2216 // changed to the work list.
2217 for (AbstractAttribute *ChangedAA : ChangedAAs) {
2218 for (auto &DepIt : ChangedAA->Deps)
2219 Worklist.insert(cast<AbstractAttribute>(DepIt.getPointer()));
2220 ChangedAA->Deps.clear();
2221 }
2222
2223 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
2224 << ", Worklist+Dependent size: " << Worklist.size()
2225 << "\n");
2226
2227 // Reset the changed and invalid set.
2228 ChangedAAs.clear();
2229 InvalidAAs.clear();
2230
2231 // Update all abstract attribute in the work list and record the ones that
2232 // changed.
2233 for (AbstractAttribute *AA : Worklist) {
2234 const auto &AAState = AA->getState();
2235 if (!AAState.isAtFixpoint())
2236 if (updateAA(*AA) == ChangeStatus::CHANGED)
2237 ChangedAAs.push_back(AA);
2238
2239 // Use the InvalidAAs vector to propagate invalid states fast transitively
2240 // without requiring updates.
2241 if (!AAState.isValidState())
2242 InvalidAAs.insert(AA);
2243 }
2244
2245 // Add attributes to the changed set if they have been created in the last
2246 // iteration.
2247 ChangedAAs.append(DG.SyntheticRoot.begin() + NumAAs,
2248 DG.SyntheticRoot.end());
2249
2250 // Reset the work list and repopulate with the changed abstract attributes.
2251 // Note that dependent ones are added above.
2252 Worklist.clear();
2253 Worklist.insert_range(ChangedAAs);
2254 Worklist.insert_range(QueryAAsAwaitingUpdate);
2255 QueryAAsAwaitingUpdate.clear();
2256
2257 } while (!Worklist.empty() && (IterationCounter++ < MaxIterations));
2258
2259 if (IterationCounter > MaxIterations && !Functions.empty()) {
2260 auto Remark = [&](OptimizationRemarkMissed ORM) {
2261 return ORM << "Attributor did not reach a fixpoint after "
2262 << ore::NV("Iterations", MaxIterations) << " iterations.";
2263 };
2264 Function *F = Functions.front();
2266 }
2267
2268 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
2269 << IterationCounter << "/" << MaxIterations
2270 << " iterations\n");
2271
2272 // Reset abstract arguments not settled in a sound fixpoint by now. This
2273 // happens when we stopped the fixpoint iteration early. Note that only the
2274 // ones marked as "changed" *and* the ones transitively depending on them
2275 // need to be reverted to a pessimistic state. Others might not be in a
2276 // fixpoint state but we can use the optimistic results for them anyway.
2277 SmallPtrSet<AbstractAttribute *, 32> Visited;
2278 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
2279 AbstractAttribute *ChangedAA = ChangedAAs[u];
2280 if (!Visited.insert(ChangedAA).second)
2281 continue;
2282
2283 AbstractState &State = ChangedAA->getState();
2284 if (!State.isAtFixpoint()) {
2286
2287 NumAttributesTimedOut++;
2288 }
2289
2290 for (auto &DepIt : ChangedAA->Deps)
2291 ChangedAAs.push_back(cast<AbstractAttribute>(DepIt.getPointer()));
2292 ChangedAA->Deps.clear();
2293 }
2294
2295 LLVM_DEBUG({
2296 if (!Visited.empty())
2297 dbgs() << "\n[Attributor] Finalized " << Visited.size()
2298 << " abstract attributes.\n";
2299 });
2300}
2301
2303 assert(AA.isQueryAA() &&
2304 "Non-query AAs should not be required to register for updates!");
2305 QueryAAsAwaitingUpdate.insert(&AA);
2306}
2307
2308ChangeStatus Attributor::manifestAttributes() {
2309 TimeTraceScope TimeScope("Attributor::manifestAttributes");
2310 size_t NumFinalAAs = DG.SyntheticRoot.Deps.size();
2311
2312 unsigned NumManifested = 0;
2313 unsigned NumAtFixpoint = 0;
2314 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
2315 for (auto &DepAA : DG.SyntheticRoot.Deps) {
2316 AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
2317 AbstractState &State = AA->getState();
2318
2319 // If there is not already a fixpoint reached, we can now take the
2320 // optimistic state. This is correct because we enforced a pessimistic one
2321 // on abstract attributes that were transitively dependent on a changed one
2322 // already above.
2323 if (!State.isAtFixpoint())
2324 State.indicateOptimisticFixpoint();
2325
2326 // We must not manifest Attributes that use Callbase info.
2327 if (AA->hasCallBaseContext())
2328 continue;
2329 // If the state is invalid, we do not try to manifest it.
2330 if (!State.isValidState())
2331 continue;
2332
2333 if (AA->getCtxI() && !isRunOn(*AA->getAnchorScope()))
2334 continue;
2335
2336 // Skip dead code.
2337 bool UsedAssumedInformation = false;
2338 if (isAssumedDead(*AA, nullptr, UsedAssumedInformation,
2339 /* CheckBBLivenessOnly */ true))
2340 continue;
2341 // Check if the manifest debug counter that allows skipping manifestation of
2342 // AAs
2343 if (!DebugCounter::shouldExecute(ManifestDBGCounter))
2344 continue;
2345 // Manifest the state and record if we changed the IR.
2346 ChangeStatus LocalChange = AA->manifest(*this);
2347 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
2348 AA->trackStatistics();
2349 LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA
2350 << "\n");
2351
2352 ManifestChange = ManifestChange | LocalChange;
2353
2354 NumAtFixpoint++;
2355 NumManifested += (LocalChange == ChangeStatus::CHANGED);
2356 }
2357
2358 (void)NumManifested;
2359 (void)NumAtFixpoint;
2360 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
2361 << " arguments while " << NumAtFixpoint
2362 << " were in a valid fixpoint state\n");
2363
2364 NumAttributesManifested += NumManifested;
2365 NumAttributesValidFixpoint += NumAtFixpoint;
2366
2367 (void)NumFinalAAs;
2368 if (NumFinalAAs != DG.SyntheticRoot.Deps.size()) {
2369 auto DepIt = DG.SyntheticRoot.Deps.begin();
2370 for (unsigned u = 0; u < NumFinalAAs; ++u)
2371 ++DepIt;
2372 for (unsigned u = NumFinalAAs; u < DG.SyntheticRoot.Deps.size();
2373 ++u, ++DepIt) {
2374 errs() << "Unexpected abstract attribute: "
2375 << cast<AbstractAttribute>(DepIt->getPointer()) << " :: "
2376 << cast<AbstractAttribute>(DepIt->getPointer())
2377 ->getIRPosition()
2378 .getAssociatedValue()
2379 << "\n";
2380 }
2381 llvm_unreachable("Expected the final number of abstract attributes to "
2382 "remain unchanged!");
2383 }
2384
2385 for (auto &It : AttrsMap) {
2386 AttributeList &AL = It.getSecond();
2387 const IRPosition &IRP =
2388 isa<Function>(It.getFirst())
2389 ? IRPosition::function(*cast<Function>(It.getFirst()))
2390 : IRPosition::callsite_function(*cast<CallBase>(It.getFirst()));
2391 IRP.setAttrList(AL);
2392 }
2393
2394 return ManifestChange;
2395}
2396
2397void Attributor::identifyDeadInternalFunctions() {
2398 // Early exit if we don't intend to delete functions.
2399 if (!Configuration.DeleteFns)
2400 return;
2401
2402 // To avoid triggering an assertion in the lazy call graph we will not delete
2403 // any internal library functions. We should modify the assertion though and
2404 // allow internals to be deleted.
2405 const auto *TLI =
2406 isModulePass()
2407 ? nullptr
2408 : getInfoCache().getTargetLibraryInfoForFunction(*Functions.back());
2409
2410 // Identify dead internal functions and delete them. This happens outside
2411 // the other fixpoint analysis as we might treat potentially dead functions
2412 // as live to lower the number of iterations. If they happen to be dead, the
2413 // below fixpoint loop will identify and eliminate them.
2414
2415 SmallVector<Function *, 8> InternalFns;
2416 for (Function *F : Functions)
2417 if (F->hasLocalLinkage() &&
2418 (isModulePass() || TLI->getLibFunc(*F) == NotLibFunc))
2419 InternalFns.push_back(F);
2420
2421 SmallPtrSet<Function *, 8> LiveInternalFns;
2422 bool FoundLiveInternal = true;
2423 while (FoundLiveInternal) {
2424 FoundLiveInternal = false;
2425 for (Function *&F : InternalFns) {
2426 if (!F)
2427 continue;
2428
2429 bool UsedAssumedInformation = false;
2431 [&](AbstractCallSite ACS) {
2433 return ToBeDeletedFunctions.count(Callee) ||
2434 (Functions.count(Callee) && Callee->hasLocalLinkage() &&
2435 !LiveInternalFns.count(Callee));
2436 },
2437 *F, true, nullptr, UsedAssumedInformation)) {
2438 continue;
2439 }
2440
2441 LiveInternalFns.insert(F);
2442 F = nullptr;
2443 FoundLiveInternal = true;
2444 }
2445 }
2446
2447 for (Function *F : InternalFns)
2448 if (F)
2449 ToBeDeletedFunctions.insert(F);
2450}
2451
2452ChangeStatus Attributor::cleanupIR() {
2453 TimeTraceScope TimeScope("Attributor::cleanupIR");
2454 // Delete stuff at the end to avoid invalid references and a nice order.
2455 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete/replace at least "
2456 << ToBeDeletedFunctions.size() << " functions and "
2457 << ToBeDeletedBlocks.size() << " blocks and "
2458 << ToBeDeletedInsts.size() << " instructions and "
2459 << ToBeChangedValues.size() << " values and "
2460 << ToBeChangedUses.size() << " uses. To insert "
2461 << ToBeChangedToUnreachableInsts.size()
2462 << " unreachables.\n"
2463 << "Preserve manifest added " << ManifestAddedBlocks.size()
2464 << " blocks\n");
2465
2467 SmallVector<Instruction *, 32> TerminatorsToFold;
2468
2469 auto ReplaceUse = [&](Use *U, Value *NewV) {
2470 Value *OldV = U->get();
2471
2472 // If we plan to replace NewV we need to update it at this point.
2473 do {
2474 const auto &Entry = ToBeChangedValues.lookup(NewV);
2475 if (!get<0>(Entry))
2476 break;
2477 NewV = get<0>(Entry);
2478 } while (true);
2479
2480 Instruction *I = dyn_cast<Instruction>(U->getUser());
2481 assert((!I || isRunOn(*I->getFunction())) &&
2482 "Cannot replace an instruction outside the current SCC!");
2483
2484 // Do not replace uses in returns if the value is a must-tail call we will
2485 // not delete.
2486 if (auto *RI = dyn_cast_or_null<ReturnInst>(I)) {
2487 if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))
2488 if (CI->isMustTailCall() && !ToBeDeletedInsts.count(CI))
2489 return;
2490 // If we rewrite a return and the new value is not an argument, strip the
2491 // `returned` attribute as it is wrong now.
2492 if (!isa<Argument>(NewV))
2493 for (auto &Arg : RI->getFunction()->args())
2494 Arg.removeAttr(Attribute::Returned);
2495 }
2496
2497 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
2498 << " instead of " << *OldV << "\n");
2499 U->set(NewV);
2500
2501 if (Instruction *I = dyn_cast<Instruction>(OldV)) {
2502 CGModifiedFunctions.insert(I->getFunction());
2503 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
2505 DeadInsts.push_back(I);
2506 }
2507 if (isa<UndefValue>(NewV) && isa<CallBase>(U->getUser())) {
2508 auto *CB = cast<CallBase>(U->getUser());
2509 if (CB->isArgOperand(U)) {
2510 unsigned Idx = CB->getArgOperandNo(U);
2511 // Drop all attributes that make passing undef UB, e.g., dereferenceable
2512 // implies noundef.
2513 AttributeMask UBImplying = AttributeFuncs::getUBImplyingAttributes();
2514 CB->removeParamAttrs(Idx, UBImplying);
2515 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
2516 if (Callee && Callee->arg_size() > Idx)
2517 Callee->removeParamAttrs(Idx, UBImplying);
2518 }
2519 }
2520 if (isa<Constant>(NewV) && isa<CondBrInst>(U->getUser())) {
2521 Instruction *UserI = cast<Instruction>(U->getUser());
2522 if (isa<UndefValue>(NewV)) {
2523 ToBeChangedToUnreachableInsts.insert(UserI);
2524 } else {
2525 TerminatorsToFold.push_back(UserI);
2526 }
2527 }
2528 };
2529
2530 for (auto &It : ToBeChangedUses) {
2531 Use *U = It.first;
2532 Value *NewV = It.second;
2533 ReplaceUse(U, NewV);
2534 }
2535
2537 for (auto &It : ToBeChangedValues) {
2538 Value *OldV = It.first;
2539 auto [NewV, Done] = It.second;
2540 Uses.clear();
2541 for (auto &U : OldV->uses())
2542 if (Done || !U.getUser()->isDroppable())
2543 Uses.push_back(&U);
2544 for (Use *U : Uses) {
2545 if (auto *I = dyn_cast<Instruction>(U->getUser()))
2546 if (!isRunOn(*I->getFunction()))
2547 continue;
2548 ReplaceUse(U, NewV);
2549 }
2550 }
2551
2552 for (const auto &V : InvokeWithDeadSuccessor)
2553 if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
2554 assert(isRunOn(*II->getFunction()) &&
2555 "Cannot replace an invoke outside the current SCC!");
2556 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
2557 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
2558 bool Invoke2CallAllowed =
2560 assert((UnwindBBIsDead || NormalBBIsDead) &&
2561 "Invoke does not have dead successors!");
2562 BasicBlock *BB = II->getParent();
2563 BasicBlock *NormalDestBB = II->getNormalDest();
2564 if (UnwindBBIsDead) {
2565 Instruction *NormalNextIP = &NormalDestBB->front();
2566 if (Invoke2CallAllowed) {
2568 NormalNextIP = BB->getTerminator();
2569 }
2570 if (NormalBBIsDead)
2571 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
2572 } else {
2573 assert(NormalBBIsDead && "Broken invariant!");
2574 if (!NormalDestBB->getUniquePredecessor())
2575 NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2576 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
2577 }
2578 }
2579 for (Instruction *I : TerminatorsToFold) {
2580 assert(isRunOn(*I->getFunction()) &&
2581 "Cannot replace a terminator outside the current SCC!");
2582 CGModifiedFunctions.insert(I->getFunction());
2583 ConstantFoldTerminator(I->getParent());
2584 }
2585 for (const auto &V : ToBeChangedToUnreachableInsts)
2586 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
2587 LLVM_DEBUG(dbgs() << "[Attributor] Change to unreachable: " << *I
2588 << "\n");
2589 assert(isRunOn(*I->getFunction()) &&
2590 "Cannot replace an instruction outside the current SCC!");
2591 CGModifiedFunctions.insert(I->getFunction());
2593 }
2594
2595 for (const auto &V : ToBeDeletedInsts) {
2596 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
2598 isRunOn(*I->getFunction())) &&
2599 "Cannot delete an instruction outside the current SCC!");
2600 I->dropDroppableUses();
2601 CGModifiedFunctions.insert(I->getFunction());
2602 if (!I->getType()->isVoidTy())
2603 I->replaceAllUsesWith(UndefValue::get(I->getType()));
2605 DeadInsts.push_back(I);
2606 else
2607 I->eraseFromParent();
2608 }
2609 }
2610
2611 llvm::erase_if(DeadInsts, [&](WeakTrackingVH I) { return !I; });
2612
2613 LLVM_DEBUG({
2614 dbgs() << "[Attributor] DeadInsts size: " << DeadInsts.size() << "\n";
2615 for (auto &I : DeadInsts)
2616 if (I)
2617 dbgs() << " - " << *I << "\n";
2618 });
2619
2621
2622 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
2623 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
2624 ToBeDeletedBBs.reserve(NumDeadBlocks);
2625 for (BasicBlock *BB : ToBeDeletedBlocks) {
2626 assert(isRunOn(*BB->getParent()) &&
2627 "Cannot delete a block outside the current SCC!");
2628 CGModifiedFunctions.insert(BB->getParent());
2629 // Do not delete BBs added during manifests of AAs.
2630 if (ManifestAddedBlocks.contains(BB))
2631 continue;
2632 ToBeDeletedBBs.push_back(BB);
2633 }
2634 // Actually we do not delete the blocks but squash them into a single
2635 // unreachable but untangling branches that jump here is something we need
2636 // to do in a more generic way.
2637 detachDeadBlocks(ToBeDeletedBBs, nullptr);
2638 }
2639
2640 identifyDeadInternalFunctions();
2641
2642 // Rewrite the functions as requested during manifest.
2643 ChangeStatus ManifestChange = rewriteFunctionSignatures(CGModifiedFunctions);
2644
2645 for (Function *Fn : CGModifiedFunctions)
2646 if (!ToBeDeletedFunctions.count(Fn) && Functions.count(Fn))
2647 Configuration.CGUpdater.reanalyzeFunction(*Fn);
2648
2649 for (Function *Fn : ToBeDeletedFunctions) {
2650 if (!Functions.count(Fn))
2651 continue;
2652 Configuration.CGUpdater.removeFunction(*Fn);
2653 }
2654
2655 if (!ToBeChangedUses.empty())
2656 ManifestChange = ChangeStatus::CHANGED;
2657
2658 if (!ToBeChangedToUnreachableInsts.empty())
2659 ManifestChange = ChangeStatus::CHANGED;
2660
2661 if (!ToBeDeletedFunctions.empty())
2662 ManifestChange = ChangeStatus::CHANGED;
2663
2664 if (!ToBeDeletedBlocks.empty())
2665 ManifestChange = ChangeStatus::CHANGED;
2666
2667 if (!ToBeDeletedInsts.empty())
2668 ManifestChange = ChangeStatus::CHANGED;
2669
2670 if (!InvokeWithDeadSuccessor.empty())
2671 ManifestChange = ChangeStatus::CHANGED;
2672
2673 if (!DeadInsts.empty())
2674 ManifestChange = ChangeStatus::CHANGED;
2675
2676 NumFnDeleted += ToBeDeletedFunctions.size();
2677
2678 LLVM_DEBUG(dbgs() << "[Attributor] Deleted " << ToBeDeletedFunctions.size()
2679 << " functions after manifest.\n");
2680
2681#ifdef EXPENSIVE_CHECKS
2682 for (Function *F : Functions) {
2683 if (ToBeDeletedFunctions.count(F))
2684 continue;
2685 assert(!verifyFunction(*F, &errs()) && "Module verification failed!");
2686 }
2687#endif
2688
2689 return ManifestChange;
2690}
2691
2693 TimeTraceScope TimeScope("Attributor::run");
2694 AttributorCallGraph ACallGraph(*this);
2695
2696 if (PrintCallGraph)
2697 ACallGraph.populateAll();
2698
2699 Phase = AttributorPhase::UPDATE;
2700 runTillFixpoint();
2701
2702 // dump graphs on demand
2703 if (DumpDepGraph)
2704 DG.dumpGraph();
2705
2706 if (ViewDepGraph)
2707 DG.viewGraph();
2708
2710 DG.print();
2711
2712 Phase = AttributorPhase::MANIFEST;
2713 ChangeStatus ManifestChange = manifestAttributes();
2714
2715 Phase = AttributorPhase::CLEANUP;
2716 ChangeStatus CleanupChange = cleanupIR();
2717
2718 if (PrintCallGraph)
2719 ACallGraph.print();
2720
2721 return ManifestChange | CleanupChange;
2722}
2723
2724ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {
2725 TimeTraceScope TimeScope("updateAA", [&]() {
2726 return AA.getName().str() +
2727 std::to_string(AA.getIRPosition().getPositionKind());
2728 });
2729 assert(Phase == AttributorPhase::UPDATE &&
2730 "We can update AA only in the update stage!");
2731
2732 // Use a new dependence vector for this update.
2733 DependenceVector DV;
2734 DependenceStack.push_back(&DV);
2735
2736 auto &AAState = AA.getState();
2738 bool UsedAssumedInformation = false;
2739 if (!isAssumedDead(AA, nullptr, UsedAssumedInformation,
2740 /* CheckBBLivenessOnly */ true))
2741 CS = AA.update(*this);
2742
2743 if (!AA.isQueryAA() && DV.empty() && !AA.getState().isAtFixpoint()) {
2744 // If the AA did not rely on outside information but changed, we run it
2745 // again to see if it found a fixpoint. Most AAs do but we don't require
2746 // them to. Hence, it might take the AA multiple iterations to get to a
2747 // fixpoint even if it does not rely on outside information, which is fine.
2749 if (CS == ChangeStatus::CHANGED)
2750 RerunCS = AA.update(*this);
2751
2752 // If the attribute did not change during the run or rerun, and it still did
2753 // not query any non-fix information, the state will not change and we can
2754 // indicate that right at this point.
2755 if (RerunCS == ChangeStatus::UNCHANGED && !AA.isQueryAA() && DV.empty())
2756 AAState.indicateOptimisticFixpoint();
2757 }
2758
2759 if (!AAState.isAtFixpoint())
2760 rememberDependences();
2761
2762 // Verify the stack was used properly, that is we pop the dependence vector we
2763 // put there earlier.
2764 DependenceVector *PoppedDV = DependenceStack.pop_back_val();
2765 (void)PoppedDV;
2766 assert(PoppedDV == &DV && "Inconsistent usage of the dependence stack!");
2767
2768 return CS;
2769}
2770
2772 assert(!F.isDeclaration() && "Cannot create a wrapper around a declaration!");
2773
2774 Module &M = *F.getParent();
2775 LLVMContext &Ctx = M.getContext();
2776 FunctionType *FnTy = F.getFunctionType();
2777
2778 Function *Wrapper =
2779 Function::Create(FnTy, F.getLinkage(), F.getAddressSpace(), F.getName());
2780 F.setName(""); // set the inside function anonymous
2781 M.getFunctionList().insert(F.getIterator(), Wrapper);
2782
2783 F.setLinkage(GlobalValue::InternalLinkage);
2784
2785 F.replaceAllUsesWith(Wrapper);
2786 assert(F.use_empty() && "Uses remained after wrapper was created!");
2787
2788 // Move the COMDAT section to the wrapper.
2789 // TODO: Check if we need to keep it for F as well.
2790 Wrapper->setComdat(F.getComdat());
2791 F.setComdat(nullptr);
2792
2793 // Copy all metadata and attributes but keep them on F as well.
2795 F.getAllMetadata(MDs);
2796 for (auto MDIt : MDs)
2797 Wrapper->addMetadata(MDIt.first, *MDIt.second);
2798 Wrapper->setAttributes(F.getAttributes());
2799
2800 // Create the call in the wrapper.
2801 BasicBlock *EntryBB = BasicBlock::Create(Ctx, "entry", Wrapper);
2802
2804 Argument *FArgIt = F.arg_begin();
2805 for (Argument &Arg : Wrapper->args()) {
2806 Args.push_back(&Arg);
2807 Arg.setName((FArgIt++)->getName());
2808 }
2809
2810 CallInst *CI = CallInst::Create(&F, Args, "", EntryBB);
2811 CI->setTailCall(true);
2812 CI->addFnAttr(Attribute::NoInline);
2813 ReturnInst::Create(Ctx, CI->getType()->isVoidTy() ? nullptr : CI, EntryBB);
2814
2815 NumFnShallowWrappersCreated++;
2816}
2817
2819 if (F.isDeclaration() || F.hasLocalLinkage() ||
2821 return false;
2822 return true;
2823}
2824
2826 if (!AllowDeepWrapper && !Force)
2827 return nullptr;
2828 if (!isInternalizable(F))
2829 return nullptr;
2830
2831 SmallPtrSet<Function *, 2> FnSet = {&F};
2832 DenseMap<Function *, Function *> InternalizedFns;
2833 internalizeFunctions(FnSet, InternalizedFns);
2834
2835 return InternalizedFns[&F];
2836}
2837
2840 for (Function *F : FnSet)
2842 return false;
2843
2844 FnMap.clear();
2845 // Generate the internalized version of each function.
2846 for (Function *F : FnSet) {
2847 Module &M = *F->getParent();
2848 FunctionType *FnTy = F->getFunctionType();
2849
2850 // Create a copy of the current function
2851 Function *Copied =
2852 Function::Create(FnTy, F->getLinkage(), F->getAddressSpace(),
2853 F->getName() + ".internalized");
2854 ValueToValueMapTy VMap;
2855 auto *NewFArgIt = Copied->arg_begin();
2856 for (auto &Arg : F->args()) {
2857 auto ArgName = Arg.getName();
2858 NewFArgIt->setName(ArgName);
2859 VMap[&Arg] = &(*NewFArgIt++);
2860 }
2862
2863 // Copy the body of the original function to the new one
2864 CloneFunctionInto(Copied, F, VMap,
2866
2867 // Set the linakage and visibility late as CloneFunctionInto has some
2868 // implicit requirements.
2871
2872 // Copy metadata
2874 F->getAllMetadata(MDs);
2875 for (auto MDIt : MDs)
2876 if (!Copied->hasMetadata())
2877 Copied->addMetadata(MDIt.first, *MDIt.second);
2878
2879 M.getFunctionList().insert(F->getIterator(), Copied);
2880 Copied->setDSOLocal(true);
2881 FnMap[F] = Copied;
2882 }
2883
2884 // Replace all uses of the old function with the new internalized function
2885 // unless the caller is a function that was just internalized.
2886 for (Function *F : FnSet) {
2887 auto &InternalizedFn = FnMap[F];
2888 auto IsNotInternalized = [&](Use &U) -> bool {
2889 if (auto *CB = dyn_cast<CallBase>(U.getUser()))
2890 return !FnMap.lookup(CB->getCaller());
2891 return false;
2892 };
2893 F->replaceUsesWithIf(InternalizedFn, IsNotInternalized);
2894 }
2895
2896 return true;
2897}
2898
2900 Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
2901
2902 if (!Configuration.RewriteSignatures)
2903 return false;
2904
2905 Function *Fn = Arg.getParent();
2906 auto CallSiteCanBeChanged = [Fn](AbstractCallSite ACS) {
2907 // Forbid the call site to cast the function return type. If we need to
2908 // rewrite these functions we need to re-create a cast for the new call site
2909 // (if the old had uses).
2910 if (!ACS.getCalledFunction() ||
2911 ACS.getInstruction()->getType() !=
2913 return false;
2914 if (cast<CallBase>(ACS.getInstruction())->getCalledOperand()->getType() !=
2915 Fn->getType())
2916 return false;
2917 if (ACS.getNumArgOperands() != Fn->arg_size())
2918 return false;
2919 // Forbid must-tail calls for now.
2920 return !ACS.isCallbackCall() && !ACS.getInstruction()->isMustTailCall();
2921 };
2922
2923 // Avoid var-arg functions for now.
2924 if (Fn->isVarArg()) {
2925 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
2926 return false;
2927 }
2928
2929 // Avoid functions with complicated argument passing semantics.
2930 AttributeList FnAttributeList = Fn->getAttributes();
2931 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
2932 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
2933 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca) ||
2934 FnAttributeList.hasAttrSomewhere(Attribute::Preallocated)) {
2935 LLVM_DEBUG(
2936 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
2937 return false;
2938 }
2939
2940 // Avoid callbacks for now.
2941 bool UsedAssumedInformation = false;
2942 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,
2943 UsedAssumedInformation,
2944 /* CheckPotentiallyDead */ true)) {
2945 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
2946 return false;
2947 }
2948
2949 auto InstPred = [](Instruction &I) {
2950 if (auto *CI = dyn_cast<CallInst>(&I))
2951 return !CI->isMustTailCall();
2952 return true;
2953 };
2954
2955 // Forbid must-tail calls for now.
2956 // TODO:
2957 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
2958 if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
2959 nullptr, {Instruction::Call},
2960 UsedAssumedInformation)) {
2961 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
2962 return false;
2963 }
2964
2965 return true;
2966}
2967
2969 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
2972 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
2973 << Arg.getParent()->getName() << " with "
2974 << ReplacementTypes.size() << " replacements\n");
2975 assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&
2976 "Cannot register an invalid rewrite");
2977
2978 Function *Fn = Arg.getParent();
2980 ArgumentReplacementMap[Fn];
2981 if (ARIs.empty())
2982 ARIs.resize(Fn->arg_size());
2983
2984 // If we have a replacement already with less than or equal new arguments,
2985 // ignore this request.
2986 std::unique_ptr<ArgumentReplacementInfo> &ARI = ARIs[Arg.getArgNo()];
2987 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
2988 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
2989 return false;
2990 }
2991
2992 // If we have a replacement already but we like the new one better, delete
2993 // the old.
2994 ARI.reset();
2995
2996 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
2997 << Arg.getParent()->getName() << " with "
2998 << ReplacementTypes.size() << " replacements\n");
2999
3000 // Remember the replacement.
3001 ARI.reset(new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
3002 std::move(CalleeRepairCB),
3003 std::move(ACSRepairCB)));
3004
3005 return true;
3006}
3007
3008bool Attributor::shouldSeedAttribute(AbstractAttribute &AA) {
3009 bool Result = true;
3010#ifndef NDEBUG
3011 if (SeedAllowList.size() != 0)
3012 Result = llvm::is_contained(SeedAllowList, AA.getName());
3013 Function *Fn = AA.getAnchorScope();
3014 if (FunctionSeedAllowList.size() != 0 && Fn)
3016#endif
3017 return Result;
3018}
3019
3020ChangeStatus Attributor::rewriteFunctionSignatures(
3021 SmallSetVector<Function *, 8> &ModifiedFns) {
3023
3024 for (auto &It : ArgumentReplacementMap) {
3025 Function *OldFn = It.first;
3026
3027 // Deleted functions do not require rewrites.
3028 if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))
3029 continue;
3030
3032 It.second;
3033 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
3034
3035 SmallVector<Type *, 16> NewArgumentTypes;
3036 SmallVector<AttributeSet, 16> NewArgumentAttributes;
3037
3038 // Collect replacement argument types and copy over existing attributes.
3039 AttributeList OldFnAttributeList = OldFn->getAttributes();
3040 for (Argument &Arg : OldFn->args()) {
3041 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3042 ARIs[Arg.getArgNo()]) {
3043 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
3044 ARI->ReplacementTypes.end());
3045 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
3046 AttributeSet());
3047 } else {
3048 NewArgumentTypes.push_back(Arg.getType());
3049 NewArgumentAttributes.push_back(
3050 OldFnAttributeList.getParamAttrs(Arg.getArgNo()));
3051 }
3052 }
3053
3054 uint64_t LargestVectorWidth = 0;
3055 for (auto *I : NewArgumentTypes)
3056 if (auto *VT = dyn_cast<llvm::VectorType>(I))
3057 LargestVectorWidth =
3058 std::max(LargestVectorWidth,
3059 VT->getPrimitiveSizeInBits().getKnownMinValue());
3060
3061 FunctionType *OldFnTy = OldFn->getFunctionType();
3062 Type *RetTy = OldFnTy->getReturnType();
3063
3064 // Construct the new function type using the new arguments types.
3065 FunctionType *NewFnTy =
3066 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
3067
3068 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
3069 << "' from " << *OldFn->getFunctionType() << " to "
3070 << *NewFnTy << "\n");
3071
3072 // Create the new function body and insert it into the module.
3073 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
3074 OldFn->getAddressSpace(), "");
3075 Functions.insert(NewFn);
3076 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
3077 NewFn->takeName(OldFn);
3078 NewFn->copyAttributesFrom(OldFn);
3079
3080 // Patch the pointer to LLVM function in debug info descriptor.
3081 NewFn->setSubprogram(OldFn->getSubprogram());
3082 OldFn->setSubprogram(nullptr);
3083
3084 // Recompute the parameter attributes list based on the new arguments for
3085 // the function.
3086 LLVMContext &Ctx = OldFn->getContext();
3087 NewFn->setAttributes(AttributeList::get(
3088 Ctx, OldFnAttributeList.getFnAttrs(), OldFnAttributeList.getRetAttrs(),
3089 NewArgumentAttributes));
3090 AttributeFuncs::updateMinLegalVectorWidthAttr(*NewFn, LargestVectorWidth);
3091
3092 // Remove argmem from the memory effects if we have no more pointer
3093 // arguments, or they are readnone.
3094 MemoryEffects ME = NewFn->getMemoryEffects();
3095 int ArgNo = -1;
3096 if (ME.doesAccessArgPointees() && all_of(NewArgumentTypes, [&](Type *T) {
3097 ++ArgNo;
3098 return !T->isPtrOrPtrVectorTy() ||
3099 NewFn->hasParamAttribute(ArgNo, Attribute::ReadNone);
3100 })) {
3102 }
3103
3104 // Since we have now created the new function, splice the body of the old
3105 // function right into the new function, leaving the old rotting hulk of the
3106 // function empty.
3107 NewFn->splice(NewFn->begin(), OldFn);
3108
3109 // Set of all "call-like" instructions that invoke the old function mapped
3110 // to their new replacements.
3112
3113 // Callback to create a new "call-like" instruction for a given one.
3114 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
3115 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
3116 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
3117
3118 // Collect the new argument operands for the replacement call site.
3119 SmallVector<Value *, 16> NewArgOperands;
3120 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
3121 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
3122 unsigned NewFirstArgNum = NewArgOperands.size();
3123 (void)NewFirstArgNum; // only used inside assert.
3124 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3125 ARIs[OldArgNum]) {
3126 if (ARI->ACSRepairCB)
3127 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
3128 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
3129 NewArgOperands.size() &&
3130 "ACS repair callback did not provide as many operand as new "
3131 "types were registered!");
3132 // TODO: Exose the attribute set to the ACS repair callback
3133 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
3134 AttributeSet());
3135 } else {
3136 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
3137 NewArgOperandAttributes.push_back(
3138 OldCallAttributeList.getParamAttrs(OldArgNum));
3139 }
3140 }
3141
3142 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
3143 "Mismatch # argument operands vs. # argument operand attributes!");
3144 assert(NewArgOperands.size() == NewFn->arg_size() &&
3145 "Mismatch # argument operands vs. # function arguments!");
3146
3147 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
3148 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
3149
3150 // Create a new call or invoke instruction to replace the old one.
3151 CallBase *NewCB;
3152 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
3153 NewCB = InvokeInst::Create(NewFn, II->getNormalDest(),
3154 II->getUnwindDest(), NewArgOperands,
3155 OperandBundleDefs, "", OldCB->getIterator());
3156 } else {
3157 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
3158 "", OldCB->getIterator());
3159 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
3160 NewCB = NewCI;
3161 }
3162
3163 // Copy over various properties and the new attributes.
3164 NewCB->copyProfileAndDebugMetadata(*OldCB);
3165 NewCB->setCallingConv(OldCB->getCallingConv());
3166 NewCB->takeName(OldCB);
3167 NewCB->setAttributes(AttributeList::get(
3168 Ctx, OldCallAttributeList.getFnAttrs(),
3169 OldCallAttributeList.getRetAttrs(), NewArgOperandAttributes));
3170
3171 AttributeFuncs::updateMinLegalVectorWidthAttr(*NewCB->getCaller(),
3172 LargestVectorWidth);
3173
3174 CallSitePairs.push_back({OldCB, NewCB});
3175 return true;
3176 };
3177
3178 // Use the CallSiteReplacementCreator to create replacement call sites.
3179 bool UsedAssumedInformation = false;
3180 bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,
3181 true, nullptr, UsedAssumedInformation,
3182 /* CheckPotentiallyDead */ true);
3183 (void)Success;
3184 assert(Success && "Assumed call site replacement to succeed!");
3185
3186 // Rewire the arguments.
3187 Argument *OldFnArgIt = OldFn->arg_begin();
3188 Argument *NewFnArgIt = NewFn->arg_begin();
3189 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
3190 ++OldArgNum, ++OldFnArgIt) {
3191 if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
3192 ARIs[OldArgNum]) {
3193 if (ARI->CalleeRepairCB)
3194 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
3195 if (ARI->ReplacementTypes.empty())
3196 OldFnArgIt->replaceAllUsesWith(
3197 PoisonValue::get(OldFnArgIt->getType()));
3198 NewFnArgIt += ARI->ReplacementTypes.size();
3199 } else {
3200 NewFnArgIt->takeName(&*OldFnArgIt);
3201 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
3202 ++NewFnArgIt;
3203 }
3204 }
3205
3206 // Eliminate the instructions *after* we visited all of them.
3207 for (auto &CallSitePair : CallSitePairs) {
3208 CallBase &OldCB = *CallSitePair.first;
3209 CallBase &NewCB = *CallSitePair.second;
3210 assert(OldCB.getType() == NewCB.getType() &&
3211 "Cannot handle call sites with different types!");
3212 ModifiedFns.insert(OldCB.getFunction());
3213 OldCB.replaceAllUsesWith(&NewCB);
3214 OldCB.eraseFromParent();
3215 }
3216
3217 // Replace the function in the call graph (if any).
3218 Configuration.CGUpdater.replaceFunctionWith(*OldFn, *NewFn);
3219
3220 // If the old function was modified and needed to be reanalyzed, the new one
3221 // does now.
3222 if (ModifiedFns.remove(OldFn))
3223 ModifiedFns.insert(NewFn);
3224
3226 }
3227
3228 return Changed;
3229}
3230
3231void InformationCache::initializeInformationCache(const Function &CF,
3232 FunctionInfo &FI) {
3233 // As we do not modify the function here we can remove the const
3234 // withouth breaking implicit assumptions. At the end of the day, we could
3235 // initialize the cache eagerly which would look the same to the users.
3236 Function &F = const_cast<Function &>(CF);
3237
3238 FI.IsKernel = F.hasFnAttribute("kernel");
3239
3240 // Walk all instructions to find interesting instructions that might be
3241 // queried by abstract attributes during their initialization or update.
3242 // This has to happen before we create attributes.
3243
3244 DenseMap<const Value *, std::optional<short>> AssumeUsesMap;
3245
3246 // Add \p V to the assume uses map which track the number of uses outside of
3247 // "visited" assumes. If no outside uses are left the value is added to the
3248 // assume only use vector.
3249 auto AddToAssumeUsesMap = [&](const Value &V) -> void {
3250 SmallVector<const Instruction *> Worklist;
3251 if (auto *I = dyn_cast<Instruction>(&V))
3252 Worklist.push_back(I);
3253 while (!Worklist.empty()) {
3254 const Instruction *I = Worklist.pop_back_val();
3255 std::optional<short> &NumUses = AssumeUsesMap[I];
3256 if (!NumUses)
3257 NumUses = I->getNumUses();
3258 NumUses = *NumUses - /* this assume */ 1;
3259 if (*NumUses != 0)
3260 continue;
3261 AssumeOnlyValues.insert(I);
3262 for (const Value *Op : I->operands())
3263 if (auto *OpI = dyn_cast<Instruction>(Op))
3264 Worklist.push_back(OpI);
3265 }
3266 };
3267
3268 for (Instruction &I : instructions(&F)) {
3269 bool IsInterestingOpcode = false;
3270
3271 // To allow easy access to all instructions in a function with a given
3272 // opcode we store them in the InfoCache. As not all opcodes are interesting
3273 // to concrete attributes we only cache the ones that are as identified in
3274 // the following switch.
3275 // Note: There are no concrete attributes now so this is initially empty.
3276 switch (I.getOpcode()) {
3277 default:
3278 assert(!isa<CallBase>(&I) &&
3279 "New call base instruction type needs to be known in the "
3280 "Attributor.");
3281 break;
3282 case Instruction::Call:
3283 // Calls are interesting on their own, additionally:
3284 // For `llvm.assume` calls we also fill the KnowledgeMap as we find them.
3285 // For `must-tail` calls we remember the caller and callee.
3286 if (auto *Assume = dyn_cast<AssumeInst>(&I)) {
3287 AssumeOnlyValues.insert(Assume);
3288 fillMapFromAssume(*Assume, KnowledgeMap);
3289 AddToAssumeUsesMap(*Assume->getArgOperand(0));
3290 } else if (cast<CallInst>(I).isMustTailCall()) {
3291 FI.ContainsMustTailCall = true;
3292 if (auto *Callee = dyn_cast_if_present<Function>(
3293 cast<CallInst>(I).getCalledOperand()))
3294 getFunctionInfo(*Callee).CalledViaMustTail = true;
3295 }
3296 [[fallthrough]];
3297 case Instruction::CallBr:
3298 case Instruction::Invoke:
3299 case Instruction::CleanupRet:
3300 case Instruction::CatchSwitch:
3301 case Instruction::AtomicRMW:
3302 case Instruction::AtomicCmpXchg:
3303 case Instruction::UncondBr:
3304 case Instruction::CondBr:
3305 case Instruction::Resume:
3306 case Instruction::Ret:
3307 case Instruction::Load:
3308 // The alignment of a pointer is interesting for loads.
3309 case Instruction::Store:
3310 // The alignment of a pointer is interesting for stores.
3311 case Instruction::Alloca:
3312 case Instruction::AddrSpaceCast:
3313 IsInterestingOpcode = true;
3314 }
3315 if (IsInterestingOpcode) {
3316 auto *&Insts = FI.OpcodeInstMap[I.getOpcode()];
3317 if (!Insts)
3318 Insts = new (Allocator) InstructionVectorTy();
3319 Insts->push_back(&I);
3320 }
3321 if (I.mayReadOrWriteMemory())
3322 FI.RWInsts.push_back(&I);
3323 }
3324
3325 if (F.hasFnAttribute(Attribute::AlwaysInline) &&
3326 isInlineViable(F).isSuccess())
3327 InlineableFunctions.insert(&F);
3328}
3329
3330InformationCache::FunctionInfo::~FunctionInfo() {
3331 // The instruction vectors are allocated using a BumpPtrAllocator, we need to
3332 // manually destroy them.
3333 for (auto &It : OpcodeInstMap)
3334 It.getSecond()->~InstructionVectorTy();
3335}
3336
3339 assert(A.isClosedWorldModule() && "Cannot see all indirect callees!");
3340 return IndirectlyCallableFunctions;
3341}
3342
3343std::optional<unsigned> InformationCache::getFlatAddressSpace() const {
3344 if (IsTargetGPU())
3345 return 0;
3346 return std::nullopt;
3347}
3348
3350 const AbstractAttribute &ToAA,
3351 DepClassTy DepClass) {
3352 if (DepClass == DepClassTy::NONE)
3353 return;
3354 // If we are outside of an update, thus before the actual fixpoint iteration
3355 // started (= when we create AAs), we do not track dependences because we will
3356 // put all AAs into the initial worklist anyway.
3357 if (DependenceStack.empty())
3358 return;
3359 if (FromAA.getState().isAtFixpoint())
3360 return;
3361 DependenceStack.back()->push_back({&FromAA, &ToAA, DepClass});
3362}
3363
3364void Attributor::rememberDependences() {
3365 assert(!DependenceStack.empty() && "No dependences to remember!");
3366
3367 for (DepInfo &DI : *DependenceStack.back()) {
3368 assert((DI.DepClass == DepClassTy::REQUIRED ||
3369 DI.DepClass == DepClassTy::OPTIONAL) &&
3370 "Expected required or optional dependence (1 bit)!");
3371 auto &DepAAs = const_cast<AbstractAttribute &>(*DI.FromAA).Deps;
3372 DepAAs.insert(AbstractAttribute::DepTy(
3373 const_cast<AbstractAttribute *>(DI.ToAA), unsigned(DI.DepClass)));
3374 }
3375}
3376
3377template <Attribute::AttrKind AK, typename AAType>
3378void Attributor::checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs,
3379 bool SkipHasAttrCheck) {
3380 bool IsKnown;
3381 if (SkipHasAttrCheck || !Attrs.hasAttribute(AK))
3382 if (!Configuration.Allowed || Configuration.Allowed->count(&AAType::ID))
3383 if (!AA::hasAssumedIRAttr<AK>(*this, nullptr, IRP, DepClassTy::NONE,
3384 IsKnown))
3385 getOrCreateAAFor<AAType>(IRP);
3386}
3387
3389 assert(!F.isDeclaration());
3390
3391 if (!VisitedFunctions.insert(&F).second)
3392 return;
3393
3394 // In non-module runs we need to look at the call sites of a function to
3395 // determine if it is part of a must-tail call edge. This will influence what
3396 // attributes we can derive.
3397 InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(F);
3398 if (!isModulePass() && !FI.CalledViaMustTail) {
3399 for (const Use &U : F.uses())
3400 if (const auto *CB = dyn_cast<CallBase>(U.getUser()))
3401 if (CB->isCallee(&U) && CB->isMustTailCall())
3402 FI.CalledViaMustTail = true;
3403 }
3404
3406 bool IsIPOAmendable = isFunctionIPOAmendable(F);
3407 auto Attrs = F.getAttributes();
3408 auto FnAttrs = Attrs.getFnAttrs();
3409
3410 // Check for dead BasicBlocks in every function.
3411 // We need dead instruction detection because we do not want to deal with
3412 // broken IR in which SSA rules do not apply.
3414
3415 // Every function might contain instructions that cause "undefined
3416 // behavior".
3418
3419 // Every function might be applicable for Heap-To-Stack conversion.
3422
3423 // Every function might be "must-progress".
3424 checkAndQueryIRAttr<Attribute::MustProgress, AAMustProgress>(FPos, FnAttrs);
3425
3426 // Every function might be "no-free".
3427 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(FPos, FnAttrs);
3428
3429 // Every function might be "will-return".
3430 checkAndQueryIRAttr<Attribute::WillReturn, AAWillReturn>(FPos, FnAttrs);
3431
3432 // Every function might be marked "nosync"
3433 checkAndQueryIRAttr<Attribute::NoSync, AANoSync>(FPos, FnAttrs);
3434
3435 // Everything that is visible from the outside (=function, argument, return
3436 // positions), cannot be changed if the function is not IPO amendable. We can
3437 // however analyse the code inside.
3438 if (IsIPOAmendable) {
3439
3440 // Every function can be nounwind.
3441 checkAndQueryIRAttr<Attribute::NoUnwind, AANoUnwind>(FPos, FnAttrs);
3442
3443 // Every function might be "no-return".
3444 checkAndQueryIRAttr<Attribute::NoReturn, AANoReturn>(FPos, FnAttrs);
3445
3446 // Every function might be "no-recurse".
3447 checkAndQueryIRAttr<Attribute::NoRecurse, AANoRecurse>(FPos, FnAttrs);
3448
3449 // Every function can be "non-convergent".
3450 if (Attrs.hasFnAttr(Attribute::Convergent))
3452
3453 // Every function might be "readnone/readonly/writeonly/...".
3455
3456 // Every function can be "readnone/argmemonly/inaccessiblememonly/...".
3458
3459 // Every function can track active assumptions.
3461
3462 // If we're not using a dynamic mode for float, there's nothing worthwhile
3463 // to infer. This misses the edge case denormal-fp-math="dynamic" and
3464 // denormal-fp-math-f32=something, but that likely has no real world use.
3465 DenormalMode Mode = F.getDenormalMode(APFloat::IEEEsingle());
3466 if (Mode.Input == DenormalMode::Dynamic ||
3467 Mode.Output == DenormalMode::Dynamic)
3469
3470 // Return attributes are only appropriate if the return type is non void.
3471 Type *ReturnType = F.getReturnType();
3472 if (!ReturnType->isVoidTy()) {
3474 AttributeSet RetAttrs = Attrs.getRetAttrs();
3475
3476 // Every returned value might be dead.
3478
3479 // Every function might be simplified.
3480 bool UsedAssumedInformation = false;
3481 getAssumedSimplified(RetPos, nullptr, UsedAssumedInformation,
3483
3484 // Every returned value might be marked noundef.
3485 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(RetPos, RetAttrs);
3486
3487 if (ReturnType->isPointerTy()) {
3488
3489 // Every function with pointer return type might be marked align.
3491
3492 // Every function with pointer return type might be marked nonnull.
3493 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(RetPos, RetAttrs);
3494
3495 // Every function with pointer return type might be marked noalias.
3496 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(RetPos, RetAttrs);
3497
3498 // Every function with pointer return type might be marked
3499 // dereferenceable.
3501 } else if (AttributeFuncs::isNoFPClassCompatibleType(ReturnType)) {
3503 }
3504 }
3505 }
3506
3507 for (Argument &Arg : F.args()) {
3508 IRPosition ArgPos = IRPosition::argument(Arg);
3509 auto ArgNo = Arg.getArgNo();
3510 AttributeSet ArgAttrs = Attrs.getParamAttrs(ArgNo);
3511
3512 if (!IsIPOAmendable) {
3513 if (Arg.getType()->isPointerTy())
3514 // Every argument with pointer type might be marked nofree.
3515 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);
3516 continue;
3517 }
3518
3519 // Every argument might be simplified. We have to go through the
3520 // Attributor interface though as outside AAs can register custom
3521 // simplification callbacks.
3522 bool UsedAssumedInformation = false;
3523 getAssumedSimplified(ArgPos, /* AA */ nullptr, UsedAssumedInformation,
3525
3526 // Every argument might be dead.
3528
3529 // Every argument might be marked noundef.
3530 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(ArgPos, ArgAttrs);
3531
3532 if (Arg.getType()->isPointerTy()) {
3533 // Every argument with pointer type might be marked nonnull.
3534 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(ArgPos, ArgAttrs);
3535
3536 // Every argument with pointer type might be marked noalias.
3537 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(ArgPos, ArgAttrs);
3538
3539 // Every argument with pointer type might be marked dereferenceable.
3541
3542 // Every argument with pointer type might be marked align.
3544
3545 // Every argument with pointer type might be marked nocapture.
3546 checkAndQueryIRAttr<Attribute::Captures, AANoCapture>(
3547 ArgPos, ArgAttrs, /*SkipHasAttrCheck=*/true);
3548
3549 // Every argument with pointer type might be marked
3550 // "readnone/readonly/writeonly/..."
3552
3553 // Every argument with pointer type might be marked nofree.
3554 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);
3555
3556 // Every argument with pointer type might be privatizable (or
3557 // promotable)
3559 } else if (AttributeFuncs::isNoFPClassCompatibleType(Arg.getType())) {
3561 }
3562 }
3563
3564 auto CallSitePred = [&](Instruction &I) -> bool {
3565 auto &CB = cast<CallBase>(I);
3566 IRPosition CBInstPos = IRPosition::inst(CB);
3568
3569 // Call sites might be dead if they do not have side effects and no live
3570 // users. The return value might be dead if there are no live users.
3571 getOrCreateAAFor<AAIsDead>(CBInstPos);
3572
3573 Function *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
3574 // TODO: Even if the callee is not known now we might be able to simplify
3575 // the call/callee.
3576 if (!Callee) {
3578 return true;
3579 }
3580
3581 // Every call site can track active assumptions.
3583
3584 // Skip declarations except if annotations on their call sites were
3585 // explicitly requested.
3586 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
3587 !Callee->hasMetadata(LLVMContext::MD_callback))
3588 return true;
3589
3590 if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
3592 bool UsedAssumedInformation = false;
3593 getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation,
3595
3596 if (AttributeFuncs::isNoFPClassCompatibleType(Callee->getReturnType()))
3598 }
3599
3600 const AttributeList &CBAttrs = CBFnPos.getAttrList();
3601 for (int I = 0, E = CB.arg_size(); I < E; ++I) {
3602
3604 AttributeSet CBArgAttrs = CBAttrs.getParamAttrs(I);
3605
3606 // Every call site argument might be dead.
3608
3609 // Call site argument might be simplified. We have to go through the
3610 // Attributor interface though as outside AAs can register custom
3611 // simplification callbacks.
3612 bool UsedAssumedInformation = false;
3613 getAssumedSimplified(CBArgPos, /* AA */ nullptr, UsedAssumedInformation,
3615
3616 // Every call site argument might be marked "noundef".
3617 checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(CBArgPos, CBArgAttrs);
3618
3619 Type *ArgTy = CB.getArgOperand(I)->getType();
3620
3621 if (!ArgTy->isPointerTy()) {
3622 if (AttributeFuncs::isNoFPClassCompatibleType(ArgTy))
3624
3625 continue;
3626 }
3627
3628 // Call site argument attribute "non-null".
3629 checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(CBArgPos, CBArgAttrs);
3630
3631 // Call site argument attribute "captures(none)".
3632 checkAndQueryIRAttr<Attribute::Captures, AANoCapture>(
3633 CBArgPos, CBArgAttrs, /*SkipHasAttrCheck=*/true);
3634
3635 // Call site argument attribute "no-alias".
3636 checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(CBArgPos, CBArgAttrs);
3637
3638 // Call site argument attribute "dereferenceable".
3640
3641 // Call site argument attribute "align".
3642 getOrCreateAAFor<AAAlign>(CBArgPos);
3643
3644 // Call site argument attribute
3645 // "readnone/readonly/writeonly/..."
3646 if (!CBAttrs.hasParamAttr(I, Attribute::ReadNone))
3648
3649 // Call site argument attribute "nofree".
3650 checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(CBArgPos, CBArgAttrs);
3651 }
3652 return true;
3653 };
3654
3655 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
3656 [[maybe_unused]] bool Success;
3657 bool UsedAssumedInformation = false;
3659 nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
3660 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
3661 (unsigned)Instruction::Call},
3662 UsedAssumedInformation);
3663 assert(Success && "Expected the check call to be successful!");
3664
3665 auto LoadStorePred = [&](Instruction &I) -> bool {
3666 if (auto *LI = dyn_cast<LoadInst>(&I)) {
3667 getOrCreateAAFor<AAAlign>(IRPosition::value(*LI->getPointerOperand()));
3668 if (SimplifyAllLoads)
3670 UsedAssumedInformation, AA::Intraprocedural);
3672 IRPosition::value(*LI->getPointerOperand()));
3674 IRPosition::value(*LI->getPointerOperand()));
3675 } else {
3676 auto &SI = cast<StoreInst>(I);
3678 getAssumedSimplified(IRPosition::value(*SI.getValueOperand()), nullptr,
3679 UsedAssumedInformation, AA::Intraprocedural);
3680 getOrCreateAAFor<AAAlign>(IRPosition::value(*SI.getPointerOperand()));
3682 IRPosition::value(*SI.getPointerOperand()));
3683 }
3684 return true;
3685 };
3687 nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
3688 {(unsigned)Instruction::Load, (unsigned)Instruction::Store},
3689 UsedAssumedInformation);
3690 assert(Success && "Expected the check call to be successful!");
3691
3692 // AllocaInstPredicate
3693 auto AAAllocationInfoPred = [&](Instruction &I) -> bool {
3695 return true;
3696 };
3697
3699 nullptr, OpcodeInstMap, AAAllocationInfoPred, nullptr, nullptr,
3700 {(unsigned)Instruction::Alloca}, UsedAssumedInformation);
3701 assert(Success && "Expected the check call to be successful!");
3702}
3703
3705 if (CloseWorldAssumption.getNumOccurrences())
3706 return CloseWorldAssumption;
3707 return isModulePass() && Configuration.IsClosedWorldModule;
3708}
3709
3710/// Helpers to ease debugging through output streams and print calls.
3711///
3712///{
3714 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
3715}
3716
3718 switch (AP) {
3720 return OS << "inv";
3722 return OS << "flt";
3724 return OS << "fn_ret";
3726 return OS << "cs_ret";
3728 return OS << "fn";
3730 return OS << "cs";
3732 return OS << "arg";
3734 return OS << "cs_arg";
3735 }
3736 llvm_unreachable("Unknown attribute position!");
3737}
3738
3740 const Value &AV = Pos.getAssociatedValue();
3741 OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
3742 << Pos.getAnchorValue().getName() << "@" << Pos.getCallSiteArgNo() << "]";
3743
3744 if (Pos.hasCallBaseContext())
3745 OS << "[cb_context:" << *Pos.getCallBaseContext() << "]";
3746 return OS << "}";
3747}
3748
3750 OS << "range-state(" << S.getBitWidth() << ")<";
3751 S.getKnown().print(OS);
3752 OS << " / ";
3753 S.getAssumed().print(OS);
3754 OS << ">";
3755
3756 return OS << static_cast<const AbstractState &>(S);
3757}
3758
3760 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
3761}
3762
3764 AA.print(OS);
3765 return OS;
3766}
3767
3770 OS << "set-state(< {";
3771 if (!S.isValidState())
3772 OS << "full-set";
3773 else {
3774 for (const auto &It : S.getAssumedSet())
3775 OS << It << ", ";
3776 if (S.undefIsContained())
3777 OS << "undef ";
3778 }
3779 OS << "} >)";
3780
3781 return OS;
3782}
3783
3785 const PotentialLLVMValuesState &S) {
3786 OS << "set-state(< {";
3787 if (!S.isValidState())
3788 OS << "full-set";
3789 else {
3790 for (const auto &It : S.getAssumedSet()) {
3791 if (auto *F = dyn_cast<Function>(It.first.getValue()))
3792 OS << "@" << F->getName() << "[" << int(It.second) << "], ";
3793 else
3794 OS << *It.first.getValue() << "[" << int(It.second) << "], ";
3795 }
3796 if (S.undefIsContained())
3797 OS << "undef ";
3798 }
3799 OS << "} >)";
3800
3801 return OS;
3802}
3803
3805 OS << "[";
3806 OS << getName();
3807 OS << "] for CtxI ";
3808
3809 if (auto *I = getCtxI()) {
3810 OS << "'";
3811 I->print(OS);
3812 OS << "'";
3813 } else
3814 OS << "<<null inst>>";
3815
3816 OS << " at position " << getIRPosition() << " with state " << getAsStr(A)
3817 << '\n';
3818}
3819
3821 print(OS);
3822
3823 for (const auto &DepAA : Deps) {
3824 auto *AA = DepAA.getPointer();
3825 OS << " updates ";
3826 AA->print(OS);
3827 }
3828
3829 OS << '\n';
3830}
3831
3833 const AAPointerInfo::Access &Acc) {
3834 OS << " [" << Acc.getKind() << "] " << *Acc.getRemoteInst();
3835 if (Acc.getLocalInst() != Acc.getRemoteInst())
3836 OS << " via " << *Acc.getLocalInst();
3837 if (Acc.getContent()) {
3838 if (*Acc.getContent())
3839 OS << " [" << **Acc.getContent() << "]";
3840 else
3841 OS << " [ <unknown> ]";
3842 }
3843 return OS;
3844}
3845///}
3846
3847/// ----------------------------------------------------------------------------
3848/// Pass (Manager) Boilerplate
3849/// ----------------------------------------------------------------------------
3850
3852 SetVector<Function *> &Functions,
3853 CallGraphUpdater &CGUpdater,
3855 bool DeleteFns, bool IsModulePass) {
3856 if (Functions.empty())
3857 return false;
3858
3859 LLVM_DEBUG({
3860 dbgs() << "[Attributor] Run on module with " << Functions.size()
3861 << " functions:\n";
3862 for (Function *Fn : Functions)
3863 dbgs() << " - " << Fn->getName() << "\n";
3864 });
3865
3866 // Create an Attributor and initially empty information cache that is filled
3867 // while we identify default attribute opportunities.
3868 AttributorConfig AC(CGUpdater);
3869 AC.IsModulePass = IsModulePass;
3870 AC.DeleteFns = DeleteFns;
3871 auto OREGetter = [&FAM](Function *F) -> OptimizationRemarkEmitter & {
3872 return FAM.getResult<OptimizationRemarkEmitterAnalysis>(*F);
3873 };
3874 AC.OREGetter = OREGetter;
3875 AC.PassName = DEBUG_TYPE;
3876
3877 /// Tracking callback for specialization of indirect calls.
3879 IndirectCalleeTrackingMap;
3880 if (MaxSpecializationPerCB.getNumOccurrences()) {
3881 AC.IndirectCalleeSpecializationCallback =
3882 [&](Attributor &, const AbstractAttribute &AA, CallBase &CB,
3883 Function &Callee, unsigned) {
3884 if (MaxSpecializationPerCB == 0)
3885 return false;
3886 auto &Set = IndirectCalleeTrackingMap[&CB];
3887 if (!Set)
3888 Set = std::make_unique<SmallPtrSet<Function *, 8>>();
3889 if (Set->size() >= MaxSpecializationPerCB)
3890 return Set->contains(&Callee);
3891 Set->insert(&Callee);
3892 return true;
3893 };
3894 }
3895
3896 Attributor A(Functions, InfoCache, AC);
3897
3898 // Create shallow wrappers for all functions that are not IPO amendable
3900 for (Function *F : Functions)
3901 if (!A.isFunctionIPOAmendable(*F))
3903
3904 // Internalize non-exact functions
3905 // TODO: for now we eagerly internalize functions without calculating the
3906 // cost, we need a cost interface to determine whether internalizing
3907 // a function is "beneficial"
3908 if (AllowDeepWrapper) {
3909 unsigned FunSize = Functions.size();
3910 for (unsigned u = 0; u < FunSize; u++) {
3911 Function *F = Functions[u];
3912 if (!F->isDeclaration() && !F->isDefinitionExact() && !F->use_empty() &&
3913 !GlobalValue::isInterposableLinkage(F->getLinkage())) {
3915 assert(NewF && "Could not internalize function.");
3916 Functions.insert(NewF);
3917
3918 // Update call graph
3919 CGUpdater.replaceFunctionWith(*F, *NewF);
3920 for (const Use &U : NewF->uses())
3921 if (CallBase *CB = dyn_cast<CallBase>(U.getUser())) {
3922 auto *CallerF = CB->getCaller();
3923 CGUpdater.reanalyzeFunction(*CallerF);
3924 }
3925 }
3926 }
3927 }
3928
3929 for (Function *F : Functions) {
3930 if (F->isDeclaration())
3931 continue;
3932
3933 if (F->hasExactDefinition())
3934 NumFnWithExactDefinition++;
3935 else
3936 NumFnWithoutExactDefinition++;
3937
3938 // We look at internal functions only on-demand but if any use is not a
3939 // direct call or outside the current set of analyzed functions, we have
3940 // to do it eagerly.
3941 if (F->hasLocalLinkage()) {
3942 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
3943 const auto *CB = dyn_cast<CallBase>(U.getUser());
3944 return CB && CB->isCallee(&U) &&
3945 Functions.count(const_cast<Function *>(CB->getCaller()));
3946 }))
3947 continue;
3948 }
3949
3950 // Populate the Attributor with abstract attribute opportunities in the
3951 // function and the information cache with IR information.
3952 A.identifyDefaultAbstractAttributes(*F);
3953 }
3954
3955 ChangeStatus Changed = A.run();
3956
3957 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
3958 << " functions, result: " << Changed << ".\n");
3960}
3961
3963 SetVector<Function *> &Functions,
3964 CallGraphUpdater &CGUpdater,
3966 bool IsModulePass) {
3967 if (Functions.empty())
3968 return false;
3969
3970 LLVM_DEBUG({
3971 dbgs() << "[AttributorLight] Run on module with " << Functions.size()
3972 << " functions:\n";
3973 for (Function *Fn : Functions)
3974 dbgs() << " - " << Fn->getName() << "\n";
3975 });
3976
3977 // Create an Attributor and initially empty information cache that is filled
3978 // while we identify default attribute opportunities.
3979 AttributorConfig AC(CGUpdater);
3980 AC.IsModulePass = IsModulePass;
3981 AC.DeleteFns = false;
3982 DenseSet<const char *> Allowed(
3989 AC.Allowed = &Allowed;
3990 AC.UseLiveness = false;
3991
3992 Attributor A(Functions, InfoCache, AC);
3993
3994 for (Function *F : Functions) {
3995 if (F->isDeclaration())
3996 continue;
3997
3998 if (F->hasExactDefinition())
3999 NumFnWithExactDefinition++;
4000 else
4001 NumFnWithoutExactDefinition++;
4002
4003 // We look at internal functions only on-demand but if any use is not a
4004 // direct call or outside the current set of analyzed functions, we have
4005 // to do it eagerly.
4006 if (AC.UseLiveness && F->hasLocalLinkage()) {
4007 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
4008 const auto *CB = dyn_cast<CallBase>(U.getUser());
4009 return CB && CB->isCallee(&U) &&
4010 Functions.count(const_cast<Function *>(CB->getCaller()));
4011 }))
4012 continue;
4013 }
4014
4015 // Populate the Attributor with abstract attribute opportunities in the
4016 // function and the information cache with IR information.
4017 A.identifyDefaultAbstractAttributes(*F);
4018 }
4019
4020 ChangeStatus Changed = A.run();
4021
4023 // Invalidate analyses for modified functions so that we don't have to
4024 // invalidate all analyses for all functions in this SCC.
4025 PreservedAnalyses FuncPA;
4026 // We haven't changed the CFG for modified functions.
4027 FuncPA.preserveSet<CFGAnalyses>();
4028 for (Function *Changed : A.getModifiedFunctions()) {
4029 FAM.invalidate(*Changed, FuncPA);
4030 // Also invalidate any direct callers of changed functions since analyses
4031 // may care about attributes of direct callees. For example, MemorySSA
4032 // cares about whether or not a call's callee modifies memory and queries
4033 // that through function attributes.
4034 for (auto *U : Changed->users()) {
4035 if (auto *Call = dyn_cast<CallBase>(U)) {
4036 if (Call->getCalledFunction() == Changed)
4037 FAM.invalidate(*Call->getFunction(), FuncPA);
4038 }
4039 }
4040 }
4041 }
4042 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
4043 << " functions, result: " << Changed << ".\n");
4045}
4046
4047void AADepGraph::viewGraph() { llvm::ViewGraph(this, "Dependency Graph"); }
4048
4050 static std::atomic<int> CallTimes;
4051 std::string Prefix;
4052
4053 if (!DepGraphDotFileNamePrefix.empty())
4055 else
4056 Prefix = "dep_graph";
4057 std::string Filename =
4058 Prefix + "_" + std::to_string(CallTimes.load()) + ".dot";
4059
4060 outs() << "Dependency graph dump to " << Filename << ".\n";
4061
4062 std::error_code EC;
4063
4065 if (!EC)
4066 llvm::WriteGraph(File, this);
4067
4068 CallTimes++;
4069}
4070
4072 for (auto DepAA : SyntheticRoot.Deps)
4073 cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(outs());
4074}
4075
4079 AnalysisGetter AG(FAM);
4080
4081 SetVector<Function *> Functions;
4082 Functions.reserve(M.size());
4083 for (Function &F : M)
4084 Functions.insert(&F);
4085
4086 CallGraphUpdater CGUpdater;
4087 BumpPtrAllocator Allocator;
4088 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);
4089 if (runAttributorOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4090 /* DeleteFns */ true, /* IsModulePass */ true)) {
4091 // FIXME: Think about passes we will preserve and add them here.
4092 return PreservedAnalyses::none();
4093 }
4094 return PreservedAnalyses::all();
4095}
4096
4099 LazyCallGraph &CG,
4100 CGSCCUpdateResult &UR) {
4102 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
4103 AnalysisGetter AG(FAM);
4104
4105 SetVector<Function *> Functions;
4106 Functions.reserve(C.size());
4107 for (LazyCallGraph::Node &N : C)
4108 Functions.insert(&N.getFunction());
4109
4110 if (Functions.empty())
4111 return PreservedAnalyses::all();
4112
4113 Module &M = *Functions.back()->getParent();
4114 CallGraphUpdater CGUpdater;
4115 CGUpdater.initialize(CG, C, AM, UR);
4116 BumpPtrAllocator Allocator;
4117 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
4118 if (runAttributorOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4119 /* DeleteFns */ false,
4120 /* IsModulePass */ false)) {
4121 // FIXME: Think about passes we will preserve and add them here.
4124 return PA;
4125 }
4126 return PreservedAnalyses::all();
4127}
4128
4133 AnalysisGetter AG(FAM, /* CachedOnly */ true);
4134
4135 SetVector<Function *> Functions;
4136 Functions.reserve(M.size());
4137 for (Function &F : M)
4138 Functions.insert(&F);
4139
4140 CallGraphUpdater CGUpdater;
4141 BumpPtrAllocator Allocator;
4142 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);
4143 if (runAttributorLightOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4144 /* IsModulePass */ true)) {
4146 // We have not added or removed functions.
4148 // We already invalidated all relevant function analyses above.
4150 return PA;
4151 }
4152 return PreservedAnalyses::all();
4153}
4154
4157 LazyCallGraph &CG,
4158 CGSCCUpdateResult &UR) {
4160 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
4161 AnalysisGetter AG(FAM);
4162
4163 SetVector<Function *> Functions;
4164 for (LazyCallGraph::Node &N : C)
4165 Functions.insert(&N.getFunction());
4166
4167 if (Functions.empty())
4168 return PreservedAnalyses::all();
4169
4170 Module &M = *Functions.back()->getParent();
4171 CallGraphUpdater CGUpdater;
4172 CGUpdater.initialize(CG, C, AM, UR);
4173 BumpPtrAllocator Allocator;
4174 InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
4175 if (runAttributorLightOnFunctions(InfoCache, Functions, CGUpdater, FAM,
4176 /* IsModulePass */ false)) {
4178 // We have not added or removed functions.
4180 // We already invalidated all relevant function analyses above.
4182 return PA;
4183 }
4184 return PreservedAnalyses::all();
4185}
4186namespace llvm {
4187
4204
4205template <>
4207 static NodeRef getEntryNode(AADepGraph *DG) { return DG->GetEntryNode(); }
4208
4211
4212 static nodes_iterator nodes_begin(AADepGraph *DG) { return DG->begin(); }
4213
4214 static nodes_iterator nodes_end(AADepGraph *DG) { return DG->end(); }
4215};
4216
4217template <> struct DOTGraphTraits<AADepGraph *> : public DefaultDOTGraphTraits {
4219
4220 static std::string getNodeLabel(const AADepGraphNode *Node,
4221 const AADepGraph *DG) {
4222 std::string AAString;
4223 raw_string_ostream O(AAString);
4224 Node->print(O);
4225 return AAString;
4226 }
4227};
4228
4229} // 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
uint64_t uint64_t
Rewrite undef for PHI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static cl::opt< bool > AllowShallowWrappers("attributor-allow-shallow-wrappers", cl::Hidden, cl::desc("Allow the Attributor to create shallow " "wrappers for non-exact definitions."), cl::init(false))
bool canMarkAsVisited(const User *Usr)
#define VERBOSE_DEBUG_TYPE
static cl::opt< bool > EnableHeapToStack("enable-heap-to-stack-conversion", cl::init(true), cl::Hidden)
static cl::list< std::string > SeedAllowList("attributor-seed-allow-list", cl::Hidden, cl::desc("Comma separated list of attribute names that are " "allowed to be seeded."), cl::CommaSeparated)
static bool getPotentialCopiesOfMemoryValue(Attributor &A, Ty &I, SmallSetVector< Value *, 4 > &PotentialCopies, SmallSetVector< Instruction *, 4 > *PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact)
static cl::opt< unsigned, true > MaxInitializationChainLengthX("attributor-max-initialization-chain-length", cl::Hidden, cl::desc("Maximal number of chained initializations (to avoid stack overflows)"), cl::location(MaxInitializationChainLength), cl::init(1024))
static cl::opt< unsigned > MaxSpecializationPerCB("attributor-max-specializations-per-call-base", cl::Hidden, cl::desc("Maximal number of callees specialized for " "a call base"), cl::init(UINT32_MAX))
static cl::opt< bool > SimplifyAllLoads("attributor-simplify-all-loads", cl::Hidden, cl::desc("Try to simplify all loads."), cl::init(true))
static bool runAttributorOnFunctions(InformationCache &InfoCache, SetVector< Function * > &Functions, CallGraphUpdater &CGUpdater, FunctionAnalysisManager &FAM, bool DeleteFns, bool IsModulePass)
}
static bool 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...
bool empty() const
Return true if the mask contains no attributes.
This class holds the attributes for a particular argument, parameter, function, or return value.
Definition Attributes.h:406
LLVM_ABI 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.
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
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:262
LLVM Basic Block Representation.
Definition BasicBlock.h:62
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:463
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void setCallingConv(CallingConv::ID CC)
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
LLVM_ABI void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
CallingConv::ID getCallingConv() const
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
void setAttributes(AttributeList A)
Set the attributes for this call.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
Wrapper to unify "old style" CallGraph and "new style" LazyCallGraph.
LLVM_ABI void replaceFunctionWith(Function &OldFn, Function &NewFn)
Replace OldFn in the call graph (and SCC) with NewFn.
LLVM_ABI void reanalyzeFunction(Function &Fn)
After an CGSCC pass changes a function in ways that affect the call graph, this method can be called ...
void initialize(LazyCallGraph &LCG, LazyCallGraph::SCC &SCC, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR)
Initializers for usage outside of a CGSCC pass, inside a CGSCC pass in the old and new pass manager (...
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
void setTailCall(bool IsTc=true)
A constant value that is initialized with an expression using other constant values.
Definition Constants.h:1316
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static LLVM_ABI Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
LLVM_ABI void print(raw_ostream &OS) const
Print out the bounds to a stream.
This is an important base class in LLVM.
Definition Constant.h: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:716
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:793
Implements a dense probed hash-table based set.
Definition DenseSet.h: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:862
bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const
check if an attributes is in the list of attributes.
Definition Function.cpp:743
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
iterator begin()
Definition Function.h:838
arg_iterator arg_begin()
Definition Function.h:853
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition Function.h:332
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:352
size_t arg_size() const
Definition Function.h:886
Type * getReturnType() const
Returns the type of the ret val.
Definition Function.h:217
void setMemoryEffects(MemoryEffects ME)
Definition Function.cpp:865
Argument * getArg(unsigned i) const
Definition Function.h:871
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition Function.cpp:846
bool hasMetadata() const
Return true if this GlobalObject has any metadata attached to it.
LLVM_ABI void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
LinkageTypes getLinkage() const
bool hasLocalLinkage() const
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
void setDSOLocal(bool Local)
PointerType * getType() const
Global values are always pointers.
@ DefaultVisibility
The GV is visible.
Definition GlobalValue.h:68
void setVisibility(VisibilityTypes V)
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
LLVM_ABI void copyProfileAndDebugMetadata(const Instruction &SrcInst)
Copy debug, profile, and memprof metadata from SrcInst to this instruction without copying alias-anal...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr, InsertPosition InsertBefore=nullptr)
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
A node in the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
An instruction for reading from memory.
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memcpy/memmove intrinsics.
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
bool doesAccessArgPointees() const
Whether this function may access argument memory.
Definition ModRef.h:260
static 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:549
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:708
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:315
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:396
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:802
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp: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:2605
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:2540
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.