50#ifdef EXPENSIVE_CHECKS
60#define DEBUG_TYPE "attributor"
61#define VERBOSE_DEBUG_TYPE DEBUG_TYPE "-verbose"
64 "Determine what attributes are manifested in the IR");
66STATISTIC(NumFnDeleted,
"Number of function deleted");
68 "Number of functions with exact definitions");
70 "Number of functions without exact definitions");
71STATISTIC(NumFnShallowWrappersCreated,
"Number of shallow wrappers created");
73 "Number of abstract attributes timed out before fixpoint");
75 "Number of abstract attributes in a valid fixpoint state");
77 "Number of abstract attributes manifested in IR");
89 cl::desc(
"Maximal number of fixpoint iterations."),
93 "attributor-max-initialization-chain-length",
cl::Hidden,
95 "Maximal number of chained initializations (to avoid stack overflows)"),
100 "attributor-max-iterations-verify",
cl::Hidden,
101 cl::desc(
"Verify that max-iterations is a tight bound for a fixpoint"),
106 cl::desc(
"Annotate call sites of function declarations."),
cl::init(
false));
113 cl::desc(
"Allow the Attributor to create shallow "
114 "wrappers for non-exact definitions."),
119 cl::desc(
"Allow the Attributor to use IP information "
120 "derived from non-exact functions via cloning"),
127 cl::desc(
"Comma seperated list of attribute names that are "
128 "allowed to be seeded."),
132 "attributor-function-seed-allow-list",
cl::Hidden,
133 cl::desc(
"Comma seperated list of function names that are "
134 "allowed to be seeded."),
140 cl::desc(
"Dump the dependency graph to dot files."),
144 "attributor-depgraph-dot-filename-prefix",
cl::Hidden,
145 cl::desc(
"The prefix used for the CallGraph dot file names."));
148 cl::desc(
"View the dependency graph."),
152 cl::desc(
"Print attribute dependencies"),
156 "attributor-enable-call-site-specific-deduction",
cl::Hidden,
157 cl::desc(
"Allow the Attributor to do call site specific analysis"),
162 cl::desc(
"Print Attributor's internal call graph"),
167 cl::desc(
"Try to simplify all loads."),
174 return L == ChangeStatus::CHANGED ? L : R;
181 return L == ChangeStatus::UNCHANGED ? L : R;
191 return T.isAMDGPU() ||
T.isNVPTX();
197 if (
const auto *CB = dyn_cast<CallBase>(&
I)) {
198 if (CB->hasFnAttr(Attribute::NoSync))
202 if (!CB->isConvergent() && !CB->mayReadOrWriteMemory())
208 const auto &NoSyncAA =
A.getAAFor<
AANoSync>(
213 if (!
I.mayReadOrWriteMemory())
220 const Value &V,
bool ForAnalysisOnly) {
222 if (!ForAnalysisOnly)
233 if (isa<AllocaInst>(Obj))
237 auto *GV = dyn_cast<GlobalVariable>(&Obj);
241 bool UsedAssumedInformation =
false;
243 if (
A.hasGlobalVariableSimplificationCallback(*GV)) {
244 auto AssumedGV =
A.getAssumedInitializerFromCallBack(
245 *GV,
nullptr, UsedAssumedInformation);
246 Initializer = *AssumedGV;
250 if (!GV->hasLocalLinkage() && !(GV->isConstant() && GV->hasInitializer()))
252 if (!GV->hasInitializer())
256 Initializer = GV->getInitializer();
268 if (isa<Constant>(V))
270 if (
auto *
I = dyn_cast<Instruction>(&V))
271 return I->getFunction() == Scope;
272 if (
auto *
A = dyn_cast<Argument>(&V))
273 return A->getParent() == Scope;
285 if (
auto *
A = dyn_cast<Argument>(VAC.
getValue()))
286 return A->getParent() == Scope;
287 if (
auto *
I = dyn_cast<Instruction>(VAC.
getValue())) {
288 if (
I->getFunction() == Scope) {
292 return DT->dominates(
I, CtxI);
294 if (CtxI &&
I->getParent() == CtxI->
getParent())
297 [&](
const Instruction &AfterI) { return &AfterI == CtxI; });
304 if (V.getType() == &Ty)
306 if (isa<PoisonValue>(V))
308 if (isa<UndefValue>(V))
310 if (
auto *
C = dyn_cast<Constant>(&V)) {
311 if (
C->isNullValue())
325std::optional<Value *>
327 const std::optional<Value *> &
B,
340 Ty = (*A)->getType();
341 if (isa_and_nonnull<UndefValue>(*
A))
343 if (isa<UndefValue>(*
B))
350template <
bool IsLoad,
typename Ty>
356 LLVM_DEBUG(
dbgs() <<
"Trying to determine the potential copies of " <<
I
357 <<
" (only exact: " << OnlyExact <<
")\n";);
368 A.getInfoCache().getTargetLibraryInfoForFunction(*
I.getFunction());
370 auto Pred = [&](
Value &Obj) {
372 if (isa<UndefValue>(&Obj))
374 if (isa<ConstantPointerNull>(&Obj)) {
378 Ptr.getType()->getPointerAddressSpace()) &&
379 A.getAssumedSimplified(
Ptr, QueryingAA, UsedAssumedInformation,
383 dbgs() <<
"Underlying object is a valid nullptr, giving up.\n";);
387 if (!isa<AllocaInst>(&Obj) && !isa<GlobalVariable>(&Obj) &&
389 LLVM_DEBUG(
dbgs() <<
"Underlying object is not supported yet: " << Obj
393 if (
auto *GV = dyn_cast<GlobalVariable>(&Obj))
394 if (!GV->hasLocalLinkage() &&
395 !(GV->isConstant() && GV->hasInitializer())) {
397 "linkage, not supported yet: "
402 bool NullOnly =
true;
403 bool NullRequired =
false;
404 auto CheckForNullOnlyAndUndef = [&](std::optional<Value *> V,
406 if (!V || *V ==
nullptr)
408 else if (isa<UndefValue>(*V))
410 else if (isa<Constant>(*V) && cast<Constant>(*V)->isNullValue())
411 NullRequired = !IsExact;
420 LLVM_DEBUG(
dbgs() <<
"Underlying object written but stored value "
421 "cannot be converted to read type: "
433 CheckForNullOnlyAndUndef(Acc.
getContent(), IsExact);
434 if (OnlyExact && !IsExact && !NullOnly &&
440 if (NullRequired && !NullOnly) {
441 LLVM_DEBUG(
dbgs() <<
"Required all `null` accesses due to non exact "
442 "one, however found non-null one: "
447 assert(isa<LoadInst>(
I) &&
"Expected load or store instruction only!");
458 LLVM_DEBUG(
dbgs() <<
"Underlying object written through a non-store "
459 "instruction not supported yet: "
463 Value *V = AdjustWrittenValueType(Acc, *
SI->getValueOperand());
469 assert(isa<StoreInst>(
I) &&
"Expected load or store instruction only!");
471 if (!LI && OnlyExact) {
473 "instruction not supported yet: "
484 bool HasBeenWrittenTo =
false;
489 if (!PI.forallInterferingAccesses(
A, QueryingAA,
I,
492 CheckAccess, HasBeenWrittenTo, Range)) {
495 <<
"Failed to verify all interfering accesses for underlying object: "
500 if (IsLoad && !HasBeenWrittenTo && !Range.isUnassigned()) {
502 Value *InitialValue =
505 LLVM_DEBUG(
dbgs() <<
"Could not determine required initial value of "
506 "underlying object, abort!\n");
509 CheckForNullOnlyAndUndef(InitialValue,
true);
510 if (NullRequired && !NullOnly) {
511 LLVM_DEBUG(
dbgs() <<
"Non exact access but initial value that is not "
512 "null or undef, abort!\n");
527 if (!AAUO.forallUnderlyingObjects(Pred)) {
529 dbgs() <<
"Underlying objects stored into could not be determined\n";);
536 for (
const auto *PI : PIs) {
537 if (!PI->getState().isAtFixpoint())
538 UsedAssumedInformation =
true;
539 A.recordDependence(*PI, QueryingAA, DepClassTy::OPTIONAL);
542 PotentialValueOrigins.
insert(NewCopyOrigins.
begin(), NewCopyOrigins.
end());
553 A, LI, PotentialValues, PotentialValueOrigins, QueryingAA,
554 UsedAssumedInformation, OnlyExact);
563 A,
SI, PotentialCopies, PotentialValueOrigins, QueryingAA,
564 UsedAssumedInformation, OnlyExact);
569 bool RequireReadNone,
bool &IsKnown) {
573 const auto &MemLocAA =
575 if (MemLocAA.isAssumedReadNone()) {
576 IsKnown = MemLocAA.isKnownReadNone();
578 A.recordDependence(MemLocAA, QueryingAA, DepClassTy::OPTIONAL);
583 const auto &MemBehaviorAA =
585 if (MemBehaviorAA.isAssumedReadNone() ||
586 (!RequireReadNone && MemBehaviorAA.isAssumedReadOnly())) {
587 IsKnown = RequireReadNone ? MemBehaviorAA.isKnownReadNone()
588 : MemBehaviorAA.isKnownReadOnly();
590 A.recordDependence(MemBehaviorAA, QueryingAA, DepClassTy::OPTIONAL);
613 std::function<
bool(
const Function &
F)> GoBackwardsCB) {
615 dbgs() <<
"[AA] isPotentiallyReachable @" << ToFn.
getName() <<
" from "
616 << FromI <<
" [GBCB: " <<
bool(GoBackwardsCB) <<
"][#ExS: "
617 << (ExclusionSet ? std::to_string(ExclusionSet->
size()) :
"none")
620 for (
auto *ES : *ExclusionSet)
621 dbgs() << *ES <<
"\n";
629 if (GoBackwardsCB && &ToFn != FromI.
getFunction() &&
632 LLVM_DEBUG(
dbgs() <<
"[AA] assume kernel cannot be reached from within the "
633 "module; success\n";);
642 if (!GoBackwardsCB && !ExclusionSet) {
644 <<
" is not checked backwards and does not have an "
645 "exclusion set, abort\n");
653 while (!Worklist.
empty()) {
655 if (!Visited.
insert(CurFromI).second)
659 if (FromFn == &ToFn) {
662 LLVM_DEBUG(
dbgs() <<
"[AA] check " << *ToI <<
" from " << *CurFromI
663 <<
" intraprocedurally\n");
667 ReachabilityAA.isAssumedReachable(
A, *CurFromI, *ToI, ExclusionSet);
669 << (Result ?
"can potentially " :
"cannot ") <<
"reach "
670 << *ToI <<
" [Intra]\n");
681 ToReachabilityAA.isAssumedReachable(
A, EntryI, *ToI, ExclusionSet);
683 <<
" " << (Result ?
"can potentially " :
"cannot ")
684 <<
"reach @" << *ToI <<
" [ToFn]\n");
692 Result = FnReachabilityAA.instructionCanReach(
A, *CurFromI, ToFn,
695 <<
" " << (Result ?
"can potentially " :
"cannot ")
696 <<
"reach @" << ToFn.
getName() <<
" [FromFn]\n");
706 ReachabilityAA.isAssumedReachable(
A, *CurFromI, Ret, ExclusionSet);
708 << (Result ?
"can potentially " :
"cannot ") <<
"reach "
709 << Ret <<
" [Intra]\n");
714 bool UsedAssumedInformation =
false;
715 if (
A.checkForAllInstructions(ReturnInstCB, FromFn, QueryingAA,
716 {Instruction::Ret}, UsedAssumedInformation)) {
721 if (!GoBackwardsCB) {
723 <<
" is not checked backwards, abort\n");
729 if (!GoBackwardsCB(*FromFn))
736 CallBase *CB = ACS.getInstruction();
740 if (isa<InvokeInst>(CB))
748 Result = !
A.checkForAllCallSites(CheckCallSite, *FromFn,
750 &QueryingAA, UsedAssumedInformation);
752 LLVM_DEBUG(
dbgs() <<
"[AA] stepping back to call sites from " << *CurFromI
753 <<
" in @" << FromFn->
getName()
754 <<
" failed, give up\n");
758 LLVM_DEBUG(
dbgs() <<
"[AA] stepped back to call sites from " << *CurFromI
759 <<
" in @" << FromFn->
getName()
760 <<
" worklist size is: " << Worklist.
size() <<
"\n");
769 std::function<
bool(
const Function &
F)> GoBackwardsCB) {
771 return ::isPotentiallyReachable(
A, FromI, &ToI, *ToFn, QueryingAA,
772 ExclusionSet, GoBackwardsCB);
779 std::function<
bool(
const Function &
F)> GoBackwardsCB) {
780 return ::isPotentiallyReachable(
A, FromI,
nullptr, ToFn, QueryingAA,
781 ExclusionSet, GoBackwardsCB);
786 if (isa<UndefValue>(Obj))
788 if (isa<AllocaInst>(Obj)) {
792 dbgs() <<
"[AA] Object '" << Obj
793 <<
"' is thread local; stack objects are thread local.\n");
799 << (NoCaptureAA.isAssumedNoCapture() ?
"" :
"not")
801 << (NoCaptureAA.isAssumedNoCapture() ?
"non-" :
"")
802 <<
"captured stack object.\n");
803 return NoCaptureAA.isAssumedNoCapture();
805 if (
auto *GV = dyn_cast<GlobalVariable>(&Obj)) {
806 if (GV->isConstant()) {
808 <<
"' is thread local; constant global\n");
811 if (GV->isThreadLocal()) {
813 <<
"' is thread local; thread local global\n");
818 if (
A.getInfoCache().targetIsGPU()) {
820 (
int)AA::GPUAddressSpace::Local) {
822 <<
"' is thread local; GPU local memory\n");
826 (
int)AA::GPUAddressSpace::Constant) {
828 <<
"' is thread local; GPU constant memory\n");
833 LLVM_DEBUG(
dbgs() <<
"[AA] Object '" << Obj <<
"' is not thread local\n");
839 if (!
I.mayHaveSideEffects() && !
I.mayReadFromMemory())
844 auto AddLocationPtr = [&](std::optional<MemoryLocation> Loc) {
845 if (!Loc || !Loc->Ptr) {
847 dbgs() <<
"[AA] Access to unknown location; -> requires barriers\n");
876 auto Pred = [&](
Value &Obj) {
880 <<
"'; -> requires barrier\n");
886 if (!UnderlyingObjsAA.forallUnderlyingObjects(Pred))
905 bool ForceReplace =
false) {
909 if (Attrs.hasAttributeAtIndex(AttrIdx, Kind))
913 Attrs = Attrs.addAttributeAtIndex(Ctx, AttrIdx, Attr);
918 if (Attrs.hasAttributeAtIndex(AttrIdx, Kind))
922 Attrs = Attrs.addAttributeAtIndex(Ctx, AttrIdx, Attr);
927 if (Attrs.hasAttributeAtIndex(AttrIdx, Kind))
931 Attrs = Attrs.removeAttributeAtIndex(Ctx, AttrIdx, Kind);
932 Attrs = Attrs.addAttributeAtIndex(Ctx, AttrIdx, Attr);
953 std::optional<Argument *> CBCandidateArg;
957 for (
const Use *U : CallbackUses) {
971 "ACS mapped into var-args arguments!");
972 if (CBCandidateArg) {
973 CBCandidateArg =
nullptr;
981 if (CBCandidateArg && *CBCandidateArg)
982 return *CBCandidateArg;
988 return Callee->getArg(ArgNo);
1002 LLVM_DEBUG(
dbgs() <<
"[Attributor] Update " << HasChanged <<
" " << *
this
1011 bool ForceReplace) {
1038 for (
const Attribute &Attr : DeducedAttrs) {
1072 IRPositions.emplace_back(IRP);
1076 auto CanIgnoreOperandBundles = [](
const CallBase &CB) {
1077 return (isa<IntrinsicInst>(CB) &&
1078 cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);
1092 assert(CB &&
"Expected call site!");
1095 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))
1100 assert(CB &&
"Expected call site!");
1103 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
1108 if (
Arg.hasReturnedAttr()) {
1109 IRPositions.emplace_back(
1111 IRPositions.emplace_back(
1120 assert(CB &&
"Expected call site!");
1123 if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
1138 bool IgnoreSubsumingPositions,
Attributor *
A)
const {
1142 if (EquivIRP.getAttrsFromIRAttr(AK, Attrs))
1147 if (IgnoreSubsumingPositions)
1152 if (getAttrsFromAssumes(AK, Attrs, *
A))
1159 bool IgnoreSubsumingPositions,
Attributor *
A)
const {
1162 EquivIRP.getAttrsFromIRAttr(AK, Attrs);
1166 if (IgnoreSubsumingPositions)
1171 getAttrsFromAssumes(AK, Attrs, *
A);
1198 A.getInfoCache().getKnowledgeMap().lookup({&AssociatedValue, AK});
1206 unsigned AttrsSize =
Attrs.size();
1208 A.getInfoCache().getMustBeExecutedContextExplorer();
1210 for (
const auto &It : A2K)
1213 return AttrsSize !=
Attrs.size();
1216void IRPosition::verify() {
1217#ifdef EXPENSIVE_CHECKS
1220 assert((CBContext ==
nullptr) &&
1221 "Invalid position must not have CallBaseContext!");
1223 "Expected a nullptr for an invalid position!");
1227 "Expected specialized kind for argument values!");
1230 assert(isa<Function>(getAsValuePtr()) &&
1231 "Expected function for a 'returned' position!");
1233 "Associated value mismatch!");
1236 assert((CBContext ==
nullptr) &&
1237 "'call site returned' position must not have CallBaseContext!");
1238 assert((isa<CallBase>(getAsValuePtr())) &&
1239 "Expected call base for 'call site returned' position!");
1241 "Associated value mismatch!");
1244 assert((CBContext ==
nullptr) &&
1245 "'call site function' position must not have CallBaseContext!");
1246 assert((isa<CallBase>(getAsValuePtr())) &&
1247 "Expected call base for 'call site function' position!");
1249 "Associated value mismatch!");
1252 assert(isa<Function>(getAsValuePtr()) &&
1253 "Expected function for a 'function' position!");
1255 "Associated value mismatch!");
1258 assert(isa<Argument>(getAsValuePtr()) &&
1259 "Expected argument for a 'argument' position!");
1261 "Associated value mismatch!");
1264 assert((CBContext ==
nullptr) &&
1265 "'call site argument' position must not have CallBaseContext!");
1266 Use *
U = getAsUsePtr();
1268 assert(U &&
"Expected use for a 'call site argument' position!");
1269 assert(isa<CallBase>(
U->getUser()) &&
1270 "Expected call base user for a 'call site argument' position!");
1271 assert(cast<CallBase>(
U->getUser())->isArgOperand(U) &&
1272 "Expected call base argument operand for a 'call site argument' "
1274 assert(cast<CallBase>(
U->getUser())->getArgOperandNo(U) ==
1276 "Argument number mismatch!");
1284std::optional<Constant *>
1287 bool &UsedAssumedInformation) {
1291 for (
auto &CB : SimplificationCallbacks.lookup(IRP)) {
1292 std::optional<Value *> SimplifiedV = CB(IRP, &AA, UsedAssumedInformation);
1294 return std::nullopt;
1295 if (isa_and_nonnull<Constant>(*SimplifiedV))
1296 return cast<Constant>(*SimplifiedV);
1304 UsedAssumedInformation)) {
1306 return std::nullopt;
1307 if (
auto *
C = dyn_cast_or_null<Constant>(
1320 for (
auto &CB : SimplificationCallbacks.lookup(IRP))
1321 return CB(IRP, AA, UsedAssumedInformation);
1327 return std::nullopt;
1340 bool &UsedAssumedInformation) {
1344 const auto &SimplificationCBs = SimplificationCallbacks.lookup(IRP);
1345 for (
const auto &CB : SimplificationCBs) {
1346 std::optional<Value *> CBResult = CB(IRP, AA, UsedAssumedInformation);
1347 if (!CBResult.has_value())
1349 Value *V = *CBResult;
1358 if (!SimplificationCBs.empty())
1362 const auto &PotentialValuesAA =
1364 if (!PotentialValuesAA.getAssumedSimplifiedValues(*
this, Values, S))
1366 UsedAssumedInformation |= !PotentialValuesAA.isAtFixpoint();
1372 bool &UsedAssumedInformation) {
1375 if (*V ==
nullptr || isa<Constant>(*V))
1377 if (
auto *
Arg = dyn_cast<Argument>(*V))
1379 if (!
Arg->hasPointeeInMemoryValueAttr())
1389 for (
auto &It : AAMap) {
1397 bool &UsedAssumedInformation,
1398 bool CheckBBLivenessOnly,
DepClassTy DepClass) {
1402 return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,
1403 CheckBBLivenessOnly, DepClass);
1409 bool &UsedAssumedInformation,
1410 bool CheckBBLivenessOnly,
DepClassTy DepClass) {
1411 Instruction *UserI = dyn_cast<Instruction>(U.getUser());
1414 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1416 if (
auto *CB = dyn_cast<CallBase>(UserI)) {
1419 if (CB->isArgOperand(&U)) {
1423 UsedAssumedInformation, CheckBBLivenessOnly,
1426 }
else if (
ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
1429 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1430 }
else if (
PHINode *
PHI = dyn_cast<PHINode>(UserI)) {
1433 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1434 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(UserI)) {
1435 if (!CheckBBLivenessOnly &&
SI->getPointerOperand() != U.get()) {
1443 UsedAssumedInformation =
true;
1450 UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1456 bool &UsedAssumedInformation,
1457 bool CheckBBLivenessOnly,
DepClassTy DepClass,
1458 bool CheckForDeadStore) {
1462 if (ManifestAddedBlocks.contains(
I.getParent()))
1471 if (QueryingAA == FnLivenessAA)
1475 if (CheckBBLivenessOnly ? FnLivenessAA->
isAssumedDead(
I.getParent())
1480 UsedAssumedInformation =
true;
1484 if (CheckBBLivenessOnly)
1492 if (QueryingAA == &IsDeadAA)
1499 UsedAssumedInformation =
true;
1507 UsedAssumedInformation =
true;
1517 bool &UsedAssumedInformation,
1518 bool CheckBBLivenessOnly,
DepClassTy DepClass) {
1528 isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,
1533 if (CheckBBLivenessOnly)
1539 IsDeadAA = &getOrCreateAAFor<AAIsDead>(
1546 if (QueryingAA == IsDeadAA)
1553 UsedAssumedInformation =
true;
1570 if (QueryingAA == FnLivenessAA)
1585 bool CheckBBLivenessOnly,
DepClassTy LivenessDepClass,
1586 bool IgnoreDroppableUses,
1591 if (!CB(*
this, &QueryingAA))
1602 auto AddUsers = [&](
const Value &V,
const Use *OldUse) {
1603 for (
const Use &UU : V.uses()) {
1604 if (OldUse && EquivalentUseCB && !EquivalentUseCB(*OldUse, UU)) {
1606 "rejected by the equivalence call back: "
1616 AddUsers(V,
nullptr);
1619 <<
" initial uses to check\n");
1622 const auto *LivenessAA =
1627 while (!Worklist.
empty()) {
1629 if (isa<PHINode>(U->getUser()) && !Visited.
insert(U).second)
1632 if (
auto *Fn = dyn_cast<Function>(U->getUser()))
1633 dbgs() <<
"[Attributor] Check use: " << **U <<
" in " << Fn->getName()
1636 dbgs() <<
"[Attributor] Check use: " << **U <<
" in " << *U->getUser()
1639 bool UsedAssumedInformation =
false;
1640 if (
isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,
1641 CheckBBLivenessOnly, LivenessDepClass)) {
1643 dbgs() <<
"[Attributor] Dead use, skip!\n");
1646 if (IgnoreDroppableUses && U->getUser()->isDroppable()) {
1648 dbgs() <<
"[Attributor] Droppable user, skip!\n");
1652 if (
auto *
SI = dyn_cast<StoreInst>(U->getUser())) {
1653 if (&
SI->getOperandUse(0) == U) {
1654 if (!Visited.
insert(U).second)
1658 *
this, *
SI, PotentialCopies, QueryingAA, UsedAssumedInformation,
1662 <<
"[Attributor] Value is stored, continue with "
1663 << PotentialCopies.
size()
1664 <<
" potential copies instead!\n");
1665 for (
Value *PotentialCopy : PotentialCopies)
1666 if (!AddUsers(*PotentialCopy, U))
1673 bool Follow =
false;
1674 if (!Pred(*U, Follow))
1679 User &Usr = *U->getUser();
1680 AddUsers(Usr,
nullptr);
1682 auto *RI = dyn_cast<ReturnInst>(&Usr);
1688 return AddUsers(*ACS.getInstruction(), U);
1691 &QueryingAA, UsedAssumedInformation)) {
1692 LLVM_DEBUG(
dbgs() <<
"[Attributor] Could not follow return instruction "
1693 "to all call sites: "
1704 bool RequireAllCallSites,
1705 bool &UsedAssumedInformation) {
1711 if (!AssociatedFunction) {
1712 LLVM_DEBUG(
dbgs() <<
"[Attributor] No function associated with " << IRP
1718 &QueryingAA, UsedAssumedInformation);
1723 bool RequireAllCallSites,
1725 bool &UsedAssumedInformation,
1726 bool CheckPotentiallyDead) {
1730 <<
"[Attributor] Function " << Fn.
getName()
1731 <<
" has no internal linkage, hence not all call sites are known\n");
1736 if (!CB(*
this, QueryingAA))
1740 for (
unsigned u = 0; u <
Uses.size(); ++u) {
1743 if (
auto *Fn = dyn_cast<Function>(U))
1744 dbgs() <<
"[Attributor] Check use: " << Fn->
getName() <<
" in "
1745 << *U.getUser() <<
"\n";
1747 dbgs() <<
"[Attributor] Check use: " << *U <<
" in " << *U.getUser()
1750 if (!CheckPotentiallyDead &&
1751 isAssumedDead(U, QueryingAA,
nullptr, UsedAssumedInformation,
1754 dbgs() <<
"[Attributor] Dead use, skip!\n");
1757 if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
1758 if (CE->isCast() && CE->getType()->isPointerTy()) {
1760 dbgs() <<
"[Attributor] Use, is constant cast expression, add "
1761 << CE->getNumUses() <<
" uses of that expression instead!\n";
1763 for (
const Use &CEU : CE->uses())
1764 Uses.push_back(&CEU);
1772 <<
" has non call site use " << *U.get() <<
" in "
1773 << *U.getUser() <<
"\n");
1775 if (isa<BlockAddress>(U.getUser()))
1780 const Use *EffectiveUse =
1783 if (!RequireAllCallSites) {
1784 LLVM_DEBUG(
dbgs() <<
"[Attributor] User " << *EffectiveUse->getUser()
1785 <<
" is not a call of " << Fn.
getName()
1789 LLVM_DEBUG(
dbgs() <<
"[Attributor] User " << *EffectiveUse->getUser()
1790 <<
" is an invalid use of " << Fn.
getName() <<
"\n");
1798 unsigned MinArgsParams =
1800 for (
unsigned u = 0; u < MinArgsParams; ++u) {
1804 dbgs() <<
"[Attributor] Call site / callee argument type mismatch ["
1805 << u <<
"@" << Fn.
getName() <<
": "
1815 LLVM_DEBUG(
dbgs() <<
"[Attributor] Call site callback failed for "
1823bool Attributor::shouldPropagateCallBaseContext(
const IRPosition &IRP) {
1838 if (!AssociatedFunction)
1845 const auto &AARetVal =
1847 if (!AARetVal.getState().isValidState())
1850 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
1858 if (!AssociatedFunction)
1864 const auto &AARetVal =
1866 if (!AARetVal.getState().isValidState())
1869 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
1879 bool &UsedAssumedInformation,
bool CheckBBLivenessOnly =
false,
1880 bool CheckPotentiallyDead =
false) {
1881 for (
unsigned Opcode : Opcodes) {
1883 auto *Insts = OpcodeInstMap.
lookup(Opcode);
1889 if (
A && !CheckPotentiallyDead &&
1891 UsedAssumedInformation, CheckBBLivenessOnly)) {
1893 dbgs() <<
"[Attributor] Instruction " << *
I
1894 <<
" is potentially dead, skip!\n";);
1909 bool &UsedAssumedInformation,
1910 bool CheckBBLivenessOnly,
1911 bool CheckPotentiallyDead) {
1918 const auto *LivenessAA =
1919 CheckPotentiallyDead
1925 LivenessAA, Opcodes, UsedAssumedInformation,
1926 CheckBBLivenessOnly, CheckPotentiallyDead))
1935 bool &UsedAssumedInformation,
1936 bool CheckBBLivenessOnly,
1937 bool CheckPotentiallyDead) {
1941 UsedAssumedInformation, CheckBBLivenessOnly,
1942 CheckPotentiallyDead);
1947 bool &UsedAssumedInformation) {
1949 const Function *AssociatedFunction =
1951 if (!AssociatedFunction)
1956 const auto &LivenessAA =
1963 UsedAssumedInformation))
1973void Attributor::runTillFixpoint() {
1977 <<
" abstract attributes.\n");
1982 unsigned IterationCounter = 1;
1983 unsigned MaxIterations =
1993 LLVM_DEBUG(
dbgs() <<
"\n\n[Attributor] #Iteration: " << IterationCounter
1994 <<
", Worklist size: " << Worklist.
size() <<
"\n");
1999 for (
unsigned u = 0; u < InvalidAAs.
size(); ++u) {
2004 dbgs() <<
"[Attributor] InvalidAA: " << *InvalidAA
2005 <<
" has " << InvalidAA->
Deps.
size()
2006 <<
" required & optional dependences\n");
2007 for (
auto &DepIt : InvalidAA->
Deps) {
2011 dbgs() <<
" - recompute: " << *DepAA);
2016 <<
" - invalidate: " << *DepAA);
2020 InvalidAAs.
insert(DepAA);
2030 for (
auto &DepIt : ChangedAA->Deps)
2031 Worklist.
insert(cast<AbstractAttribute>(DepIt.getPointer()));
2032 ChangedAA->Deps.clear();
2035 LLVM_DEBUG(
dbgs() <<
"[Attributor] #Iteration: " << IterationCounter
2036 <<
", Worklist+Dependent size: " << Worklist.
size()
2046 const auto &AAState = AA->getState();
2047 if (!AAState.isAtFixpoint())
2049 ChangedAAs.push_back(AA);
2053 if (!AAState.isValidState())
2065 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
2066 Worklist.insert(QueryAAsAwaitingUpdate.begin(),
2067 QueryAAsAwaitingUpdate.end());
2068 QueryAAsAwaitingUpdate.clear();
2070 }
while (!Worklist.empty() &&
2073 if (IterationCounter > MaxIterations && !Functions.
empty()) {
2075 return ORM <<
"Attributor did not reach a fixpoint after "
2076 <<
ore::NV(
"Iterations", MaxIterations) <<
" iterations.";
2079 emitRemark<OptimizationRemarkMissed>(
F,
"FixedPoint",
Remark);
2082 LLVM_DEBUG(
dbgs() <<
"\n[Attributor] Fixpoint iteration done after: "
2083 << IterationCounter <<
"/" << MaxIterations
2084 <<
" iterations\n");
2092 for (
unsigned u = 0;
u < ChangedAAs.size();
u++) {
2094 if (!Visited.
insert(ChangedAA).second)
2101 NumAttributesTimedOut++;
2104 for (
auto &DepIt : ChangedAA->
Deps)
2105 ChangedAAs.push_back(cast<AbstractAttribute>(DepIt.getPointer()));
2110 if (!Visited.
empty())
2111 dbgs() <<
"\n[Attributor] Finalized " << Visited.
size()
2112 <<
" abstract attributes.\n";
2116 errs() <<
"\n[Attributor] Fixpoint iteration done after: "
2117 << IterationCounter <<
"/" << MaxIterations <<
" iterations\n";
2118 llvm_unreachable(
"The fixpoint was not reached with exactly the number of "
2119 "specified iterations!");
2125 "Non-query AAs should not be required to register for updates!");
2126 QueryAAsAwaitingUpdate.insert(&AA);
2133 unsigned NumManifested = 0;
2134 unsigned NumAtFixpoint = 0;
2158 bool UsedAssumedInformation =
false;
2170 LLVM_DEBUG(
dbgs() <<
"[Attributor] Manifest " << LocalChange <<
" : " << *AA
2173 ManifestChange = ManifestChange | LocalChange;
2179 (void)NumManifested;
2180 (void)NumAtFixpoint;
2181 LLVM_DEBUG(
dbgs() <<
"\n[Attributor] Manifested " << NumManifested
2182 <<
" arguments while " << NumAtFixpoint
2183 <<
" were in a valid fixpoint state\n");
2185 NumAttributesManifested += NumManifested;
2186 NumAttributesValidFixpoint += NumAtFixpoint;
2191 for (
unsigned u = 0; u < NumFinalAAs; ++u)
2195 errs() <<
"Unexpected abstract attribute: "
2196 << cast<AbstractAttribute>(DepIt->getPointer()) <<
" :: "
2197 << cast<AbstractAttribute>(DepIt->getPointer())
2199 .getAssociatedValue()
2203 "remain unchanged!");
2205 return ManifestChange;
2208void Attributor::identifyDeadInternalFunctions() {
2229 if (
F->hasLocalLinkage() && (
isModulePass() || !TLI->getLibFunc(*
F, LF)))
2233 bool FoundLiveInternal =
true;
2234 while (FoundLiveInternal) {
2235 FoundLiveInternal =
false;
2236 for (
unsigned u = 0, e = InternalFns.
size(); u < e; ++u) {
2241 bool UsedAssumedInformation =
false;
2245 return ToBeDeletedFunctions.count(
Callee) ||
2246 (Functions.count(
Callee) &&
Callee->hasLocalLinkage() &&
2249 *
F,
true,
nullptr, UsedAssumedInformation)) {
2254 InternalFns[
u] =
nullptr;
2255 FoundLiveInternal =
true;
2259 for (
unsigned u = 0, e = InternalFns.
size(); u < e; ++u)
2261 ToBeDeletedFunctions.insert(
F);
2268 << ToBeDeletedFunctions.size() <<
" functions and "
2269 << ToBeDeletedBlocks.size() <<
" blocks and "
2270 << ToBeDeletedInsts.size() <<
" instructions and "
2271 << ToBeChangedValues.size() <<
" values and "
2272 << ToBeChangedUses.size() <<
" uses. To insert "
2273 << ToBeChangedToUnreachableInsts.size()
2274 <<
" unreachables.\n"
2275 <<
"Preserve manifest added " << ManifestAddedBlocks.size()
2281 auto ReplaceUse = [&](
Use *
U,
Value *NewV) {
2286 const auto &Entry = ToBeChangedValues.lookup(NewV);
2289 NewV = get<0>(Entry);
2294 "Cannot replace an instruction outside the current SCC!");
2298 if (
auto *RI = dyn_cast_or_null<ReturnInst>(
I)) {
2300 if (CI->isMustTailCall() && !ToBeDeletedInsts.count(CI))
2304 if (!isa<Argument>(NewV))
2305 for (
auto &
Arg : RI->getFunction()->args())
2306 Arg.removeAttr(Attribute::Returned);
2310 <<
" instead of " << *OldV <<
"\n");
2314 CGModifiedFunctions.insert(
I->getFunction());
2315 if (!isa<PHINode>(
I) && !ToBeDeletedInsts.count(
I) &&
2319 if (isa<UndefValue>(NewV) && isa<CallBase>(
U->getUser())) {
2320 auto *CB = cast<CallBase>(
U->getUser());
2321 if (CB->isArgOperand(U)) {
2322 unsigned Idx = CB->getArgOperandNo(U);
2323 CB->removeParamAttr(
Idx, Attribute::NoUndef);
2324 Function *Fn = CB->getCalledFunction();
2329 if (isa<Constant>(NewV) && isa<BranchInst>(
U->getUser())) {
2331 if (isa<UndefValue>(NewV)) {
2332 ToBeChangedToUnreachableInsts.insert(UserI);
2339 for (
auto &It : ToBeChangedUses) {
2341 Value *NewV = It.second;
2342 ReplaceUse(U, NewV);
2346 for (
auto &It : ToBeChangedValues) {
2347 Value *OldV = It.first;
2348 auto [NewV,
Done] = It.second;
2350 for (
auto &U : OldV->
uses())
2351 if (
Done || !
U.getUser()->isDroppable())
2354 if (
auto *
I = dyn_cast<Instruction>(
U->getUser()))
2357 ReplaceUse(U, NewV);
2361 for (
const auto &V : InvokeWithDeadSuccessor)
2362 if (
InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
2364 "Cannot replace an invoke outside the current SCC!");
2365 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
2366 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
2367 bool Invoke2CallAllowed =
2369 assert((UnwindBBIsDead || NormalBBIsDead) &&
2370 "Invoke does not have dead successors!");
2372 BasicBlock *NormalDestBB = II->getNormalDest();
2373 if (UnwindBBIsDead) {
2375 if (Invoke2CallAllowed) {
2380 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
2382 assert(NormalBBIsDead &&
"Broken invariant!");
2385 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->
front());
2390 "Cannot replace a terminator outside the current SCC!");
2391 CGModifiedFunctions.insert(
I->getFunction());
2394 for (
const auto &V : ToBeChangedToUnreachableInsts)
2395 if (
Instruction *
I = dyn_cast_or_null<Instruction>(V)) {
2399 "Cannot replace an instruction outside the current SCC!");
2400 CGModifiedFunctions.insert(
I->getFunction());
2404 for (
const auto &V : ToBeDeletedInsts) {
2405 if (
Instruction *
I = dyn_cast_or_null<Instruction>(V)) {
2406 if (
auto *CB = dyn_cast<CallBase>(
I)) {
2408 "Cannot delete an instruction outside the current SCC!");
2409 if (!isa<IntrinsicInst>(CB))
2412 I->dropDroppableUses();
2413 CGModifiedFunctions.insert(
I->getFunction());
2414 if (!
I->getType()->isVoidTy())
2419 I->eraseFromParent();
2426 dbgs() <<
"[Attributor] DeadInsts size: " << DeadInsts.
size() <<
"\n";
2427 for (
auto &
I : DeadInsts)
2429 dbgs() <<
" - " << *
I <<
"\n";
2434 if (
unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
2436 ToBeDeletedBBs.
reserve(NumDeadBlocks);
2439 "Cannot delete a block outside the current SCC!");
2440 CGModifiedFunctions.insert(BB->
getParent());
2442 if (ManifestAddedBlocks.contains(BB))
2452 identifyDeadInternalFunctions();
2455 ChangeStatus ManifestChange = rewriteFunctionSignatures(CGModifiedFunctions);
2457 for (
Function *Fn : CGModifiedFunctions)
2458 if (!ToBeDeletedFunctions.count(Fn) && Functions.count(Fn))
2461 for (
Function *Fn : ToBeDeletedFunctions) {
2462 if (!Functions.count(Fn))
2467 if (!ToBeChangedUses.empty())
2470 if (!ToBeChangedToUnreachableInsts.empty())
2473 if (!ToBeDeletedFunctions.empty())
2476 if (!ToBeDeletedBlocks.empty())
2479 if (!ToBeDeletedInsts.empty())
2482 if (!InvokeWithDeadSuccessor.empty())
2485 if (!DeadInsts.empty())
2488 NumFnDeleted += ToBeDeletedFunctions.size();
2490 LLVM_DEBUG(
dbgs() <<
"[Attributor] Deleted " << ToBeDeletedFunctions.size()
2491 <<
" functions after manifest.\n");
2493#ifdef EXPENSIVE_CHECKS
2495 if (ToBeDeletedFunctions.count(
F))
2501 return ManifestChange;
2511 Phase = AttributorPhase::UPDATE;
2524 Phase = AttributorPhase::MANIFEST;
2527 Phase = AttributorPhase::CLEANUP;
2533 return ManifestChange | CleanupChange;
2540 assert(Phase == AttributorPhase::UPDATE &&
2541 "We can update AA only in the update stage!");
2544 DependenceVector DV;
2545 DependenceStack.push_back(&DV);
2549 bool UsedAssumedInformation =
false;
2561 RerunCS = AA.
update(*
this);
2567 AAState.indicateOptimisticFixpoint();
2570 if (!AAState.isAtFixpoint())
2571 rememberDependences();
2575 DependenceVector *PoppedDV = DependenceStack.pop_back_val();
2577 assert(PoppedDV == &DV &&
"Inconsistent usage of the dependence stack!");
2583 assert(!
F.isDeclaration() &&
"Cannot create a wrapper around a declaration!");
2592 M.getFunctionList().insert(
F.getIterator(),
Wrapper);
2597 assert(
F.use_empty() &&
"Uses remained after wrapper was created!");
2602 F.setComdat(
nullptr);
2606 F.getAllMetadata(MDs);
2607 for (
auto MDIt : MDs)
2608 Wrapper->addMetadata(MDIt.first, *MDIt.second);
2609 Wrapper->setAttributes(
F.getAttributes());
2617 Args.push_back(&
Arg);
2626 NumFnShallowWrappersCreated++;
2630 if (
F.isDeclaration() ||
F.hasLocalLinkage() ||
2646 return InternalizedFns[&
F];
2664 F->getName() +
".internalized");
2667 for (
auto &
Arg :
F->args()) {
2668 auto ArgName =
Arg.getName();
2669 NewFArgIt->setName(ArgName);
2670 VMap[&
Arg] = &(*NewFArgIt++);
2685 F->getAllMetadata(MDs);
2686 for (
auto MDIt : MDs)
2690 M.getFunctionList().insert(
F->getIterator(), Copied);
2698 auto &InternalizedFn = FnMap[
F];
2699 auto IsNotInternalized = [&](
Use &U) ->
bool {
2700 if (
auto *CB = dyn_cast<CallBase>(U.getUser()))
2701 return !FnMap.
lookup(CB->getCaller());
2704 F->replaceUsesWithIf(InternalizedFn, IsNotInternalized);
2733 LLVM_DEBUG(
dbgs() <<
"[Attributor] Cannot rewrite var-args functions\n");
2744 dbgs() <<
"[Attributor] Cannot rewrite due to complex attribute\n");
2749 bool UsedAssumedInformation =
false;
2751 UsedAssumedInformation)) {
2752 LLVM_DEBUG(
dbgs() <<
"[Attributor] Cannot rewrite all call sites\n");
2757 if (
auto *CI = dyn_cast<CallInst>(&
I))
2758 return !CI->isMustTailCall();
2766 nullptr, {Instruction::Call},
2767 UsedAssumedInformation)) {
2768 LLVM_DEBUG(
dbgs() <<
"[Attributor] Cannot rewrite due to instructions\n");
2780 <<
Arg.getParent()->getName() <<
" with "
2781 << ReplacementTypes.
size() <<
" replacements\n");
2783 "Cannot register an invalid rewrite");
2787 ArgumentReplacementMap[Fn];
2793 std::unique_ptr<ArgumentReplacementInfo> &ARI = ARIs[
Arg.getArgNo()];
2794 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.
size()) {
2795 LLVM_DEBUG(
dbgs() <<
"[Attributor] Existing rewrite is preferred\n");
2804 <<
Arg.getParent()->getName() <<
" with "
2805 << ReplacementTypes.
size() <<
" replacements\n");
2809 std::move(CalleeRepairCB),
2810 std::move(ACSRepairCB)));
2831 for (
auto &It : ArgumentReplacementMap) {
2835 if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))
2848 if (
const std::unique_ptr<ArgumentReplacementInfo> &ARI =
2849 ARIs[
Arg.getArgNo()]) {
2850 NewArgumentTypes.
append(ARI->ReplacementTypes.begin(),
2851 ARI->ReplacementTypes.end());
2852 NewArgumentAttributes.
append(ARI->getNumReplacementArgs(),
2862 for (
auto *
I : NewArgumentTypes)
2863 if (
auto *VT = dyn_cast<llvm::VectorType>(
I))
2864 LargestVectorWidth =
2865 std::max(LargestVectorWidth,
2866 VT->getPrimitiveSizeInBits().getKnownMinValue());
2877 << *NewFnTy <<
"\n");
2882 Functions.insert(NewFn);
2896 NewArgumentAttributes));
2907 if (
auto *BA = dyn_cast<BlockAddress>(U))
2909 for (
auto *BA : BlockAddresses)
2924 for (
unsigned OldArgNum = 0; OldArgNum < ARIs.
size(); ++OldArgNum) {
2925 unsigned NewFirstArgNum = NewArgOperands.
size();
2926 (void)NewFirstArgNum;
2927 if (
const std::unique_ptr<ArgumentReplacementInfo> &ARI =
2929 if (ARI->ACSRepairCB)
2930 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
2931 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
2932 NewArgOperands.
size() &&
2933 "ACS repair callback did not provide as many operand as new "
2934 "types were registered!");
2936 NewArgOperandAttributes.
append(ARI->ReplacementTypes.size(),
2945 assert(NewArgOperands.
size() == NewArgOperandAttributes.
size() &&
2946 "Mismatch # argument operands vs. # argument operand attributes!");
2948 "Mismatch # argument operands vs. # function arguments!");
2955 if (
InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
2958 NewArgOperands, OperandBundleDefs,
"", OldCB);
2962 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
2967 NewCB->
copyMetadata(*OldCB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
2972 OldCallAttributeList.
getRetAttrs(), NewArgOperandAttributes));
2975 LargestVectorWidth);
2977 CallSitePairs.
push_back({OldCB, NewCB});
2982 bool UsedAssumedInformation =
false;
2984 true,
nullptr, UsedAssumedInformation,
2987 assert(
Success &&
"Assumed call site replacement to succeed!");
2992 for (
unsigned OldArgNum = 0; OldArgNum < ARIs.
size();
2993 ++OldArgNum, ++OldFnArgIt) {
2994 if (
const std::unique_ptr<ArgumentReplacementInfo> &ARI =
2996 if (ARI->CalleeRepairCB)
2997 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
2998 if (ARI->ReplacementTypes.empty())
3001 NewFnArgIt += ARI->ReplacementTypes.size();
3003 NewFnArgIt->
takeName(&*OldFnArgIt);
3010 for (
auto &CallSitePair : CallSitePairs) {
3011 CallBase &OldCB = *CallSitePair.first;
3012 CallBase &NewCB = *CallSitePair.second;
3014 "Cannot handle call sites with different types!");
3026 if (ModifiedFns.
remove(OldFn))
3027 ModifiedFns.
insert(NewFn);
3035void InformationCache::initializeInformationCache(
const Function &CF,
3051 auto AddToAssumeUsesMap = [&](
const Value &
V) ->
void {
3053 if (
auto *
I = dyn_cast<Instruction>(&V))
3055 while (!Worklist.
empty()) {
3057 std::optional<short> &NumUses = AssumeUsesMap[
I];
3059 NumUses =
I->getNumUses();
3060 NumUses = *NumUses - 1;
3063 AssumeOnlyValues.insert(
I);
3064 for (
const Value *Op :
I->operands())
3065 if (
auto *OpI = dyn_cast<Instruction>(Op))
3071 bool IsInterestingOpcode =
false;
3078 switch (
I.getOpcode()) {
3081 "New call base instruction type needs to be known in the "
3084 case Instruction::Call:
3088 if (
auto *Assume = dyn_cast<AssumeInst>(&
I)) {
3089 AssumeOnlyValues.insert(Assume);
3091 AddToAssumeUsesMap(*Assume->getArgOperand(0));
3092 }
else if (cast<CallInst>(
I).isMustTailCall()) {
3093 FI.ContainsMustTailCall =
true;
3095 getFunctionInfo(*Callee).CalledViaMustTail =
true;
3098 case Instruction::CallBr:
3099 case Instruction::Invoke:
3100 case Instruction::CleanupRet:
3101 case Instruction::CatchSwitch:
3102 case Instruction::AtomicRMW:
3103 case Instruction::AtomicCmpXchg:
3104 case Instruction::Br:
3105 case Instruction::Resume:
3106 case Instruction::Ret:
3107 case Instruction::Load:
3109 case Instruction::Store:
3111 case Instruction::Alloca:
3112 case Instruction::AddrSpaceCast:
3113 IsInterestingOpcode =
true;
3115 if (IsInterestingOpcode) {
3116 auto *&Insts = FI.OpcodeInstMap[
I.getOpcode()];
3121 if (
I.mayReadOrWriteMemory())
3122 FI.RWInsts.push_back(&
I);
3125 if (
F.hasFnAttribute(Attribute::AlwaysInline) &&
3127 InlineableFunctions.insert(&
F);
3134InformationCache::FunctionInfo::~FunctionInfo() {
3137 for (
auto &It : OpcodeInstMap)
3138 It.getSecond()->~InstructionVectorTy();
3149 if (DependenceStack.empty())
3153 DependenceStack.back()->push_back({&FromAA, &ToAA, DepClass});
3156void Attributor::rememberDependences() {
3157 assert(!DependenceStack.empty() &&
"No dependences to remember!");
3159 for (DepInfo &DI : *DependenceStack.back()) {
3162 "Expected required or optional dependence (1 bit)!");
3170 if (!VisitedFunctions.insert(&
F).second)
3172 if (
F.isDeclaration())
3178 InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(
F);
3180 for (
const Use &U :
F.uses())
3181 if (
const auto *CB = dyn_cast<CallBase>(U.getUser()))
3182 if (CB->isCallee(&U) && CB->isMustTailCall())
3183 FI.CalledViaMustTail =
true;
3191 getOrCreateAAFor<AAIsDead>(FPos);
3194 getOrCreateAAFor<AAWillReturn>(FPos);
3197 getOrCreateAAFor<AAMustProgress>(FPos);
3200 getOrCreateAAFor<AAUndefinedBehavior>(FPos);
3203 getOrCreateAAFor<AANoUnwind>(FPos);
3206 getOrCreateAAFor<AANoSync>(FPos);
3209 getOrCreateAAFor<AANoFree>(FPos);
3212 getOrCreateAAFor<AANoReturn>(FPos);
3215 getOrCreateAAFor<AANoRecurse>(FPos);
3218 if (
F.hasFnAttribute(Attribute::Convergent))
3219 getOrCreateAAFor<AANonConvergent>(FPos);
3222 getOrCreateAAFor<AAMemoryBehavior>(FPos);
3225 getOrCreateAAFor<AAMemoryLocation>(FPos);
3228 getOrCreateAAFor<AAAssumptionInfo>(FPos);
3232 getOrCreateAAFor<AAHeapToStack>(FPos);
3235 Type *ReturnType =
F.getReturnType();
3236 if (!ReturnType->isVoidTy()) {
3239 getOrCreateAAFor<AAReturnedValues>(FPos);
3244 getOrCreateAAFor<AAIsDead>(RetPos);
3247 bool UsedAssumedInformation =
false;
3252 getOrCreateAAFor<AANoUndef>(RetPos);
3254 if (ReturnType->isPointerTy()) {
3257 getOrCreateAAFor<AAAlign>(RetPos);
3260 getOrCreateAAFor<AANonNull>(RetPos);
3263 getOrCreateAAFor<AANoAlias>(RetPos);
3267 getOrCreateAAFor<AADereferenceable>(RetPos);
3269 getOrCreateAAFor<AANoFPClass>(RetPos);
3279 bool UsedAssumedInformation =
false;
3284 getOrCreateAAFor<AAIsDead>(ArgPos);
3287 getOrCreateAAFor<AANoUndef>(ArgPos);
3289 if (
Arg.getType()->isPointerTy()) {
3291 getOrCreateAAFor<AANonNull>(ArgPos);
3294 getOrCreateAAFor<AANoAlias>(ArgPos);
3297 getOrCreateAAFor<AADereferenceable>(ArgPos);
3300 getOrCreateAAFor<AAAlign>(ArgPos);
3303 getOrCreateAAFor<AANoCapture>(ArgPos);
3307 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
3310 getOrCreateAAFor<AANoFree>(ArgPos);
3313 getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);
3315 getOrCreateAAFor<AANoFPClass>(ArgPos);
3320 auto &CB = cast<CallBase>(
I);
3326 getOrCreateAAFor<AAIsDead>(CBInstPos);
3335 getOrCreateAAFor<AAAssumptionInfo>(CBFnPos);
3340 !
Callee->hasMetadata(LLVMContext::MD_callback))
3343 if (!
Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
3345 bool UsedAssumedInformation =
false;
3350 getOrCreateAAFor<AANoFPClass>(CBInstPos);
3353 for (
int I = 0,
E = CB.arg_size();
I <
E; ++
I) {
3358 getOrCreateAAFor<AAIsDead>(CBArgPos);
3363 bool UsedAssumedInformation =
false;
3368 getOrCreateAAFor<AANoUndef>(CBArgPos);
3370 Type *ArgTy = CB.getArgOperand(
I)->getType();
3374 getOrCreateAAFor<AANoFPClass>(CBArgPos);
3380 getOrCreateAAFor<AANonNull>(CBArgPos);
3383 getOrCreateAAFor<AANoCapture>(CBArgPos);
3386 getOrCreateAAFor<AANoAlias>(CBArgPos);
3389 getOrCreateAAFor<AADereferenceable>(CBArgPos);
3392 getOrCreateAAFor<AAAlign>(CBArgPos);
3396 getOrCreateAAFor<AAMemoryBehavior>(CBArgPos);
3399 getOrCreateAAFor<AANoFree>(CBArgPos);
3406 bool UsedAssumedInformation =
false;
3408 nullptr, OpcodeInstMap, CallSitePred,
nullptr,
nullptr,
3409 {(
unsigned)Instruction::Invoke, (
unsigned)Instruction::CallBr,
3411 UsedAssumedInformation);
3413 assert(
Success &&
"Expected the check call to be successful!");
3416 if (isa<LoadInst>(
I)) {
3417 getOrCreateAAFor<AAAlign>(
3423 auto &
SI = cast<StoreInst>(
I);
3432 nullptr, OpcodeInstMap, LoadStorePred,
nullptr,
nullptr,
3433 {(
unsigned)Instruction::Load, (
unsigned)Instruction::Store},
3434 UsedAssumedInformation);
3436 assert(
Success &&
"Expected the check call to be successful!");
3453 return OS <<
"fn_ret";
3455 return OS <<
"cs_ret";
3463 return OS <<
"cs_arg";
3485 return OS << static_cast<const AbstractState &>(S);
3499 OS <<
"set-state(< {";
3515 OS <<
"set-state(< {";
3520 if (
auto *
F = dyn_cast<Function>(It.first.getValue()))
3521 OS <<
"@" <<
F->getName() <<
"[" << int(It.second) <<
"], ";
3523 OS << *It.first.getValue() <<
"[" << int(It.second) <<
"], ";
3536 OS <<
"] for CtxI ";
3543 OS <<
"<<null inst>>";
3552 for (
const auto &DepAA :
Deps) {
3553 auto *AA = DepAA.getPointer();
3570 OS <<
" [ <unknown> ]";
3584 bool DeleteFns,
bool IsModulePass) {
3585 if (Functions.
empty())
3589 dbgs() <<
"[Attributor] Run on module with " << Functions.
size()
3598 AC.IsModulePass = IsModulePass;
3599 AC.DeleteFns = DeleteFns;
3605 if (!
A.isFunctionIPOAmendable(*
F))
3613 unsigned FunSize = Functions.
size();
3614 for (
unsigned u = 0; u < FunSize; u++) {
3616 if (!
F->isDeclaration() && !
F->isDefinitionExact() &&
F->getNumUses() &&
3619 assert(NewF &&
"Could not internalize function.");
3624 for (
const Use &U : NewF->
uses())
3625 if (
CallBase *CB = dyn_cast<CallBase>(U.getUser())) {
3626 auto *CallerF = CB->getCaller();
3634 if (
F->hasExactDefinition())
3635 NumFnWithExactDefinition++;
3637 NumFnWithoutExactDefinition++;
3642 if (
F->hasLocalLinkage()) {
3644 const auto *CB = dyn_cast<CallBase>(U.getUser());
3645 return CB && CB->isCallee(&U) &&
3646 Functions.count(const_cast<Function *>(CB->getCaller()));
3653 A.identifyDefaultAbstractAttributes(*
F);
3659 <<
" functions, result: " << Changed <<
".\n");
3666 static std::atomic<int> CallTimes;
3672 Prefix =
"dep_graph";
3673 std::string Filename =
3674 Prefix +
"_" + std::to_string(CallTimes.load()) +
".dot";
3676 outs() <<
"Dependency graph dump to " << Filename <<
".\n";
3689 cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(
outs());
3722 Functions.
insert(&
N.getFunction());
3724 if (Functions.
empty())
3779 std::string AAString;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
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))
static cl::opt< bool > VerifyMaxFixpointIterations("attributor-max-iterations-verify", cl::Hidden, cl::desc("Verify that max-iterations is a tight bound for a fixpoint"), cl::init(false))
static bool checkForAllInstructionsImpl(Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap, function_ref< bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA, const AAIsDead *LivenessAA, const ArrayRef< unsigned > &Opcodes, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, bool CheckPotentiallyDead=false)
#define VERBOSE_DEBUG_TYPE
static cl::opt< bool > EnableHeapToStack("enable-heap-to-stack-conversion", cl::init(true), cl::Hidden)
static bool runAttributorOnFunctions(InformationCache &InfoCache, SetVector< Function * > &Functions, AnalysisGetter &AG, CallGraphUpdater &CGUpdater, bool DeleteFns, bool IsModulePass)
}
static bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction *ToI, const Function &ToFn, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet, std::function< bool(const Function &F)> GoBackwardsCB)
static bool getPotentialCopiesOfMemoryValue(Attributor &A, Ty &I, SmallSetVector< Value *, 4 > &PotentialCopies, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact)
static cl::list< std::string > FunctionSeedAllowList("attributor-function-seed-allow-list", cl::Hidden, cl::desc("Comma seperated list of function names that are " "allowed to be seeded."), cl::CommaSeparated)
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< bool > SimplifyAllLoads("attributor-simplify-all-loads", cl::Hidden, cl::desc("Try to simplify all loads."), cl::init(true))
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 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 bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr, AttributeList &Attrs, int AttrIdx, bool ForceReplace=false)
Return true if the information provided by Attr was added to the attribute list Attrs.
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 > SeedAllowList("attributor-seed-allow-list", cl::Hidden, cl::desc("Comma seperated list of attribute 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 GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-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...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static Function * getFunction(Constant *C)
Rewrite Partial Register Uses
static const Function * getCalledFunction(const Value *V, bool &IsNoBuiltin)
print must be executed print the must be executed context for all instructions
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
FunctionAnalysisManager FAM
This file defines the PointerIntPair class.
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSimple(Instruction *I)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A manager for alias analyses.
Class for arbitrary precision integers.
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 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.
Value * getCalledOperand() const
Return the pointer to function that is being called.
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...
A container for analyses that lazily runs them and caches their results.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool hasAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
AttributeSet getFnAttrs() const
The function attributes are returned.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
AttributeSet getRetAttrs() const
The attributes for the ret value are returned.
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value.
Attribute getAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
bool isIntAttribute() const
Return true if the attribute is an integer attribute.
uint64_t getValueAsInt() const
Return the attribute's value as an integer.
StringRef getKindAsString() const
Return the attribute's kind as a string.
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
LLVM Basic Block Representation.
const Instruction & front() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
Allocate memory in an ever growing pool, as if by bump-pointer.
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.
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
AttributeList getAttributes() const
Return the parameter attributes for this call.
Function * getCaller()
Helper to get the caller (the parent function).
Wrapper to unify "old style" CallGraph and "new style" LazyCallGraph.
void removeFunction(Function &Fn)
Remove Fn from the call graph.
void removeCallSite(CallBase &CS)
Remove the call site CS from the call graph.
void replaceFunctionWith(Function &OldFn, Function &NewFn)
Replace OldFn in the call graph (and SCC) with NewFn.
void reanalyzeFunction(Function &Fn)
After an CGSCC pass changes a function in ways that affect the call graph, this method can be called ...
bool replaceCallSite(CallBase &OldCS, CallBase &NewCS)
Replace OldCS with the new call site NewCS.
void initialize(CallGraph &CG, CallGraphSCC &SCC)
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.
void setTailCall(bool IsTc=true)
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
A constant value that is initialized with an expression using other constant values.
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static Constant * getFPTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
void print(raw_ostream &OS) const
Print out the bounds to a stream.
This is an important base class in LLVM.
static 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.
static bool shouldExecute(unsigned CounterName)
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
A proxy from a FunctionAnalysisManager to an SCC.
Class to represent function types.
static 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)
void splice(Function::iterator ToIt, Function *FromF)
Transfer all blocks from FromF to this function at ToIt.
const BasicBlock & getEntryBlock() const
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
removes the attribute from the list of attributes.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
iterator_range< arg_iterator > args()
DISubprogram * getSubprogram() const
Get the attached subprogram.
AttributeList getAttributes() const
Return the attribute list for this Function.
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
Argument * getArg(unsigned i) const
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
bool hasMetadata() const
Return true if this value has any metadata attached to it.
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
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.
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.
@ InternalLinkage
Rename collisions when linking (static functions).
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
const BasicBlock * getParent() const
const Function * getFunction() const
Return the function this instruction belongs to.
const Instruction * getNextNonDebugInstruction(bool SkipPseudoOp=false) const
Return a pointer to the next non-debug instruction in the same basic block as 'this',...
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr, Instruction *InsertBefore=nullptr)
This is an important class for using LLVM in a threaded context.
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 MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
A Module instance is used to store all the information related to an LLVM module.
const FunctionListType & getFunctionList() const
Get the Module's list of functions (constant).
PointerIntPair - This class implements a pair of a pointer and small integer.
void * getOpaqueValue() const
PointerTy getPointer() const
static 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.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserve()
Mark an analysis as preserved.
Return a value (possibly void), from a function.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool remove(const value_type &X)
Remove an item from the set vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
const value_type & front() const
Return the first element of the SetVector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
typename vector_type::const_iterator iterator
const value_type & back() const
Return the last element of the SetVector.
iterator begin()
Get an iterator to the beginning of the SetVector.
ArrayRef< value_type > getArrayRef() 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.
A SetVector that performs no allocations if smaller than a certain size.
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 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.
StringRef - Represent a constant reference to a string, i.e.
A visitor class for IR positions.
SubsumingPositionIterator(const IRPosition &IRP)
Provides information about what library functions are available for the current target.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isVoidTy() const
Return true if this is 'void'.
static 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.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
Value handle that is nullable, but tries to track the Value.
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
iterator insert(iterator where, pointer New)
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.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
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.
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,...
bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
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...
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.
Constant * getInitialValueForObj(Attributor &A, 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.
bool isPotentiallyAffectedByBarrier(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is potentially affected by a barrier.
bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
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.
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...
bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
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.
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.
bool isNoFPClassCompatibleType(Type *Ty)
Returns true if this is a type legal for the 'nofpclass' attribute.
void updateMinLegalVectorWidthAttr(Function &Fn, uint64_t Width)
Update min-legal-vector-width if it is in Attribute and less than Width.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
DiagnosticInfoOptimizationBase::Argument NV
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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,...
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.
unsigned MaxInitializationChainLength
The value passed to the line option that defines the maximal initialization chain length.
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...
APInt operator&(APInt a, const APInt &b)
void detachDeadBlocks(ArrayRef< BasicBlock * > BBs, SmallVectorImpl< DominatorTree::UpdateType > *Updates, bool KeepOneInputPHIs=false)
Replace contents of every block in BBs with single unreachable instruction.
bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
CallInst * changeToCall(InvokeInst *II, DomTreeUpdater *DTU=nullptr)
This function converts the specified invoke into a normal call.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
InlineResult isInlineViable(Function &Callee)
Minimal filter to detect invalid constructs for inlining.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
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.
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool AreStatisticsEnabled()
Check if statistics are enabled.
Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
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...
Constant * ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty)
If C is a uniform value where all bits are the same (either all zero, all ones, all undef or all pois...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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...
bool operator&=(SparseBitVector< ElementSize > *LHS, const SparseBitVector< ElementSize > &RHS)
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)
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.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
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.
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)
@ OPTIONAL
The target may be valid if the source is not.
@ NONE
Do not track a dependence between source and target.
@ REQUIRED
The target cannot be valid if the source is not.
APInt operator|(APInt a, const APInt &b)
DepSetTy Deps
Set of dependency graph nodes which should be updated if this one is updated.
The data structure for the dependency graph.
AADepGraphNode SyntheticRoot
There is no root node for the dependency graph.
void print()
Print dependency graph.
void dumpGraph()
Dump graph to file.
AADepGraphNode * GetEntryNode()
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.
An abstract interface to determine reachability of point A to B.
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).
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
An abstract interface for all nocapture attributes.
bool isAssumedNoSync() const
Returns true if "nosync" is assumed.
static bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
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 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.
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
bool offsetOrSizeAreUnknown() const
Return true if offset or size are unknown.
const Instruction * getCtxI() const
Base struct for all "concrete attribute" deductions.
ChangeStatus update(Attributor &A)
Hook for the Attributor to trigger an update of the internal state.
virtual ChangeStatus manifest(Attributor &A)
Hook for the Attributor to trigger the manifestation of the information represented by the abstract a...
virtual void printWithDeps(raw_ostream &OS) const
virtual StateType & getState()=0
Return the internal abstract state for inspection.
virtual const std::string getName() const =0
This function should return the name of the AbstractAttribute.
virtual ~AbstractAttribute()=default
Virtual destructor.
virtual const std::string getAsStr() const =0
This function should return the "summarized" assumed state as string.
void print(raw_ostream &OS) const override
Helper functions, for debug purposes only.
virtual bool isQueryAA() const
A query AA is always scheduled as long as we do updates because it does lazy computation that cannot ...
virtual ChangeStatus updateImpl(Attributor &A)=0
The actual update/transfer function which has to be implemented by the derived classes.
virtual void trackStatistics() const =0
Hook to enable custom statistic tracking, called after manifest that resulted in a change if statisti...
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.
virtual ChangeStatus indicateOptimisticFixpoint()=0
Indicate that the abstract state should converge to the optimistic state.
Wrapper for FunctionAnalysisManager.
Analysis::Result * getAnalysis(const Function &F)
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.
bool RewriteSignatures
Flag to determine if we rewrite function signatures.
bool DeleteFns
Flag to determine if we can delete functions or keep dead ones around.
CallGraphUpdater & CGUpdater
Helper to update an underlying call graph and to delete functions.
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 &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
std::function< void(const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
bool registerFunctionSignatureRewrite(Argument &Arg, ArrayRef< Type * > ReplacementTypes, ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB, ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB)
Register a rewrite for a function signature.
bool isModulePass() const
Return true if this is a module pass, false otherwise.
bool isValidFunctionSignatureRewrite(Argument &Arg, ArrayRef< Type * > ReplacementTypes)
Check if we can rewrite a function signature.
bool checkForAllInstructions(function_ref< bool(Instruction &)> Pred, const Function *Fn, const AbstractAttribute &QueryingAA, const ArrayRef< unsigned > &Opcodes, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, bool CheckPotentiallyDead=false)
Check Pred on all instructions in Fn with an opcode present in Opcodes.
static bool isInternalizable(Function &F)
Returns true if the function F can be internalized.
bool isRunOn(Function &Fn) const
Return true if we derive attributes for Fn.
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.
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 void createShallowWrapper(Function &F)
Create a shallow wrapper for F such that F has internal linkage afterwards.
bool checkForAllReturnedValuesAndReturnInsts(function_ref< bool(Value &, const SmallSetVector< ReturnInst *, 4 > &)> Pred, const AbstractAttribute &QueryingAA)
Check Pred on all values potentially returned by F.
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 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 checkForAllReadWriteInstructions(function_ref< bool(Instruction &)> Pred, AbstractAttribute &QueryingAA, bool &UsedAssumedInformation)
Check Pred on all Read/Write instructions.
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,...
InformationCache & getInfoCache()
Return the internal information cache.
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.
bool checkForAllReturnedValues(function_ref< bool(Value &)> Pred, const AbstractAttribute &QueryingAA)
Check Pred on all values potentially returned by the function associated with QueryingAA.
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.
void registerForUpdate(AbstractAttribute &AA)
Allows a query AA to request an update if a new query was received.
bool getAssumedSimplifiedValues(const IRPosition &IRP, const AbstractAttribute *AA, SmallVectorImpl< AA::ValueAndContext > &Values, AA::ValueScope S, bool &UsedAssumedInformation)
Try to simplify IRP and in the scope S.
void identifyDefaultAbstractAttributes(Function &F)
Determine opportunities to derive 'default' attributes in F and create abstract attribute objects for...
std::function< bool(Attributor &, const AbstractAttribute *)> VirtualUseCallbackTy
ChangeStatus run()
Run the analyses until a fixpoint is reached or enforced (timeout).
static 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...
bool checkForAllCallSites(function_ref< bool(AbstractCallSite)> Pred, const AbstractAttribute &QueryingAA, bool RequireAllCallSites, bool &UsedAssumedInformation)
Check Pred on all function call sites.
bool isKnown(base_t BitsEncoding) 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)
DOTGraphTraits(bool isSimple=false)
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
An information struct used to provide DenseMap with the various necessary components for a given valu...
static NodeRef DepGetVal(const DepTy &DT)
static ChildIteratorType child_end(NodeRef N)
static NodeRef getEntryNode(AADepGraphNode *DGN)
static ChildIteratorType child_begin(NodeRef N)
Def