75#define DEBUG_TYPE "globalopt"
77STATISTIC(NumMarked ,
"Number of globals marked constant");
78STATISTIC(NumUnnamed ,
"Number of globals marked unnamed_addr");
79STATISTIC(NumSRA ,
"Number of aggregate globals broken into scalars");
80STATISTIC(NumSubstitute,
"Number of globals with initializers stored into them");
82STATISTIC(NumGlobUses ,
"Number of global uses devirtualized");
83STATISTIC(NumLocalized ,
"Number of globals localized");
84STATISTIC(NumShrunkToBool ,
"Number of global vars shrunk to booleans");
85STATISTIC(NumFastCallFns ,
"Number of functions converted to fastcc");
86STATISTIC(NumCtorsEvaluated,
"Number of static ctors evaluated");
87STATISTIC(NumNestRemoved ,
"Number of nest attributes removed");
88STATISTIC(NumAliasesResolved,
"Number of global aliases resolved");
89STATISTIC(NumAliasesRemoved,
"Number of global aliases eliminated");
90STATISTIC(NumCXXDtorsRemoved,
"Number of global C++ destructors removed");
91STATISTIC(NumAtExitRemoved,
"Number of atexit handlers removed");
92STATISTIC(NumInternalFunc,
"Number of internal functions");
93STATISTIC(NumColdCC,
"Number of functions marked coldcc");
94STATISTIC(NumIFuncsResolved,
"Number of statically resolved IFuncs");
95STATISTIC(NumIFuncsDeleted,
"Number of IFuncs removed");
99 cl::desc(
"Statically resolve calls to versioned "
100 "functions from non-versioned callers."),
105 cl::desc(
"Maximum number of caller/callee versions that is allowed for "
106 "using the expensive (cubic) static resolution algorithm."));
110 cl::desc(
"Enable stress test of coldcc by adding "
111 "calling conv to all internal functions."),
117 "Maximum block frequency, expressed as a percentage of caller's "
118 "entry frequency, for a call site to be considered cold for enabling "
140 Type *Ty = Types.pop_back_val();
141 switch (Ty->getTypeID()) {
160 Types.push_back(InnerTy);
165 if (--Limit == 0)
return true;
166 }
while (!Types.empty());
187 if (
I->mayHaveSideEffects())
190 if (!
GEP->hasAllConstantIndices())
192 }
else if (
I->getNumOperands() != 1) {
196 V =
I->getOperand(0);
223 while (!Worklist.
empty()) {
226 Value *V =
SI->getValueOperand();
229 SI->eraseFromParent();
232 Dead.push_back(std::make_pair(
I,
SI));
237 MSI->eraseFromParent();
240 Dead.push_back(std::make_pair(
I, MSI));
246 MTI->eraseFromParent();
249 Dead.push_back(std::make_pair(
I, MTI));
257 for (
const auto &[Inst, Store] :
Dead) {
259 Store->eraseFromParent();
267 I->eraseFromParent();
270 I->eraseFromParent();
294 I->eraseFromParent();
297 while (!WorkList.
empty()) {
299 if (!Visited.
insert(U).second)
311 Type *Ty = LI->getType();
313 LI->replaceAllUsesWith(Res);
318 Value *PtrOp = LI->getPointerOperand();
323 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address)
324 PtrOp =
II->getArgOperand(0);
328 LI->replaceAllUsesWith(
Value);
339 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address)
365 auto AppendUses = [&](
Value *V) {
367 if (Visited.
insert(&U).second)
371 while (!Worklist.
empty()) {
373 User *V = U->getUser();
377 (
GEP &&
GEP->hasAllConstantIndices())) {
389 Ptr = Ptr->stripAndAccumulateConstantOffsets(
DL,
Offset,
391 if (Ptr != GV ||
Offset.getActiveBits() >= 64)
397 const auto &[It, Inserted] =
399 if (Ty != It->second.Ty)
403 It->second.Initializer =
405 if (!It->second.Initializer) {
406 LLVM_DEBUG(
dbgs() <<
"Global SRA: Failed to evaluate initializer of "
407 << *GV <<
" with type " << *Ty <<
" at offset "
408 <<
Offset.getZExtValue());
414 if (Ty->isScalableTy())
427 return Initializer != StoredConst;
431 It->second.IsStored |= IsStored(V, It->second.Initializer);
456 for (
auto *GVE : GVs) {
459 int64_t CurVarOffsetInBytes = 0;
461 uint64_t FragmentEndInBits = FragmentOffsetInBits + FragmentSizeInBits;
468 if (CurVarOffsetInBytes < 0)
472 CurVarOffsetInBits = CHAR_BIT * (
uint64_t)CurVarOffsetInBytes;
475 if (CurVarOffsetInBits >= FragmentEndInBits)
479 uint64_t CurVarEndInBits = CurVarOffsetInBits + CurVarSize;
481 if (CurVarSize != 0 &&
482 CurVarEndInBits <= FragmentOffsetInBits)
487 if (CurVarSize != 0 &&
488 CurVarOffsetInBits >= FragmentOffsetInBits &&
489 CurVarEndInBits <= FragmentEndInBits) {
491 (CurVarOffsetInBits - FragmentOffsetInBits) / 8;
492 if (CurVarOffsetInFragment != 0)
494 CurVarOffsetInFragment});
504 if (FragmentSizeInBits < VarSize) {
505 if (CurVarOffsetInBits > FragmentOffsetInBits)
507 uint64_t CurVarFragmentOffsetInBits =
508 FragmentOffsetInBits - CurVarOffsetInBits;
509 uint64_t CurVarFragmentSizeInBits = FragmentSizeInBits;
510 if (CurVarSize != 0 && CurVarEndInBits < FragmentEndInBits)
511 CurVarFragmentSizeInBits -= (FragmentEndInBits - CurVarEndInBits);
512 if (CurVarOffsetInBits)
515 Expr, CurVarFragmentOffsetInBits, CurVarFragmentSizeInBits))
545 unsigned NumParts =
count_if(Parts, [](
const auto &Pair) {
546 return Pair.second.IsLoaded && Pair.second.IsStored;
553 for (
const auto &Pair : Parts) {
555 {Pair.first, Pair.second.Ty, Pair.second.Initializer});
561 for (
const auto &[OffsetForTy, Ty,
_] : TypesVector) {
566 Offset = OffsetForTy +
DL.getTypeAllocSize(Ty);
573 LLVM_DEBUG(
dbgs() <<
"PERFORMING GLOBAL SRA ON: " << *GV <<
"\n");
576 Align StartAlignment =
582 unsigned NameSuffix = 0;
583 for (
auto &[OffsetForTy, Ty, Initializer] : TypesVector) {
586 Initializer, GV->
getName() +
"." +
Twine(NameSuffix++), GV,
590 NewGlobals.
insert({OffsetForTy, NGV});
601 DL.getTypeAllocSizeInBits(Ty), VarSize);
608 auto AppendUsers = [&](
Value *V) {
610 if (Visited.
insert(U).second)
614 while (!Worklist.
empty()) {
626 Ptr = Ptr->stripAndAccumulateConstantOffsets(
DL,
Offset,
628 assert(Ptr == GV &&
"Load/store must be from/to global");
630 assert(NGV &&
"Must have replacement global for this offset");
638 LI->setOperand(0, NGV);
639 LI->setAlignment(NewAlign);
642 SI->setOperand(1, NGV);
643 SI->setAlignment(NewAlign);
649 "Other users can only be dead constants");
659 return NewGlobals.
begin()->second;
677 if (
SI->getOperand(0) == V) {
681 if (CI->getCalledOperand() != V) {
685 if (
II->getCalledOperand() != V) {
703 ->getPointerOperand()
704 ->stripPointerCasts()) &&
705 "Should be GlobalVariable");
722 while (!Worklist.
empty()) {
724 for (
const auto *U :
P->users()) {
735 if (
SI->getPointerOperand() !=
P)
738 if (CE->stripPointerCasts() != GV)
757 while (!Worklist.
empty()) {
759 for (
auto *U :
P->users()) {
766 "Expect only load or store instructions");
774 for (
auto UI = V->user_begin(),
E = V->user_end(); UI !=
E; ) {
781 LI->setOperand(0, NewV);
784 if (
SI->getOperand(1) == V) {
785 SI->setOperand(1, NewV);
795 bool PassedAsArg =
false;
796 for (
unsigned i = 0, e = CB->
arg_size(); i != e; ++i)
804 UI = V->user_begin();
810 if (CI->use_empty()) {
812 CI->eraseFromParent();
817 Idxs.
reserve(GEPI->getNumOperands()-1);
824 if (Idxs.
size() == GEPI->getNumOperands()-1)
828 if (GEPI->use_empty()) {
830 GEPI->eraseFromParent();
849 bool AllNonStoreUsesGone =
true;
856 if (LI->use_empty()) {
857 LI->eraseFromParent();
860 AllNonStoreUsesGone =
false;
864 assert(GlobalUser->getOperand(1) == GV &&
865 "Must be storing *to* the global");
867 AllNonStoreUsesGone =
false;
876 "Only expect load and stores!");
881 LLVM_DEBUG(
dbgs() <<
"OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV
888 if (AllNonStoreUsesGone) {
912 I->replaceAllUsesWith(NewC);
916 while (UI !=
E && *UI ==
I)
919 I->eraseFromParent();
933 LLVM_DEBUG(
errs() <<
"PROMOTING GLOBAL: " << *GV <<
" CALL = " << *CI
955 Builder.CreateMemSet(NewGV, InitVal, AllocSize, std::nullopt);
967 bool InitBoolUsed =
false;
972 for (
auto *U : Guses) {
978 SI->getValueOperand())),
979 InitBool,
false,
Align(1),
SI->getOrdering(),
SI->getSyncScopeID(),
981 NewSI->setDebugLoc(
SI->getDebugLoc());
982 SI->eraseFromParent();
1005 InitBoolUsed =
true;
1030 if (!InitBoolUsed) {
1059 while (!Worklist.
empty()) {
1061 if (!Visited.
insert(V).second)
1064 for (
const Use &VUse : V->
uses()) {
1065 const User *U = VUse.getUser();
1070 if (
SI->getValueOperand() == V &&
1071 SI->getPointerOperand()->stripPointerCasts() != GV)
1113 if (AllocSize >= 2048)
1158 auto *TLI = &GetTLI(*CI->getFunction());
1209 "No reason to shrink to bool!");
1216 bool IsOneZero =
false;
1217 bool EmitOneOrZero =
true;
1219 if (CI && CI->getValue().getActiveBits() <= 64) {
1220 IsOneZero = InitVal->
isNullValue() && CI->isOne();
1223 if (CIInit && CIInit->getValue().getActiveBits() <= 64) {
1224 uint64_t ValInit = CIInit->getZExtValue();
1225 uint64_t ValOther = CI->getZExtValue();
1226 uint64_t ValMinus = ValOther - ValInit;
1228 for(
auto *GVe : GVs){
1243 dwarf::DW_OP_deref_size, SizeInOctets,
1244 dwarf::DW_OP_constu, ValMinus,
1245 dwarf::DW_OP_mul, dwarf::DW_OP_constu, ValInit,
1247 bool WithStackValue =
true;
1253 EmitOneOrZero =
false;
1257 if (EmitOneOrZero) {
1268 bool StoringOther =
SI->getOperand(0) == OtherVal;
1271 if (StoringOther ||
SI->getOperand(0) == InitVal) {
1284 assert(LI->getOperand(0) == GV &&
"Not a copy!");
1288 false,
Align(1), LI->getOrdering(),
1289 LI->getSyncScopeID(), LI->getIterator());
1293 "This is not a form that we understand!");
1300 SI->getSyncScopeID(),
SI->getIterator());
1347 Dead = (
F->isDeclaration() &&
F->use_empty()) ||
F->isDefTriviallyDead();
1355 if (DeleteFnCallback)
1356 DeleteFnCallback(*
F);
1380 for (
auto *U : GV->
users()) {
1384 assert(
I->getParent()->getParent() ==
F);
1398 auto &DT = LookupDomTree(*
const_cast<Function *
>(
F));
1409 const unsigned Threshold = 100;
1410 if (Loads.
size() * Stores.
size() > Threshold)
1413 for (
auto *L : Loads) {
1414 auto *LTy = L->getType();
1420 return DT.dominates(S, L) &&
1421 DL.getTypeStoreSize(LTy).getFixedValue() <=
1422 DL.getTypeStoreSize(STy).getFixedValue();
1446 if (LI->getFunction() ==
F &&
1447 LI->getType() == StoredOnceValue->
getType() && LI->isSimple())
1452 bool MadeChange =
false;
1453 if (!Loads.
empty()) {
1454 auto &DT = LookupDomTree(*
const_cast<Function *
>(
F));
1455 for (
auto *LI : Loads) {
1456 if (DT.dominates(StoredOnceStore, LI)) {
1457 LI->replaceAllUsesWith(
const_cast<Value *
>(StoredOnceValue));
1458 LI->eraseFromParent();
1482 if (!GS.HasMultipleAccessingFunctions &&
1483 GS.AccessingFunction &&
1487 GS.AccessingFunction->doesNotRecurse() &&
1494 GS.AccessingFunction->getEntryBlock().begin().getNonConst();
1498 nullptr, GV->
getName(), FirstI);
1556 LLVM_DEBUG(
dbgs() <<
" *** Marking constant allowed us to simplify "
1557 <<
"all users and delete global!\n");
1571 Value *StoredOnceValue = GS.getStoredOnceValue();
1574 const_cast<Function &
>(*GS.StoredOnceStore->getFunction());
1575 bool CanHaveNonUndefGlobalInitializer =
1576 GetTTI(StoreFn).canHaveNonUndefGlobalInitializerInAddressSpace(
1587 DL.getTypeAllocSize(SOVConstant->getType()).getFixedValue() ==
1589 CanHaveNonUndefGlobalInitializer) {
1600 NGV->copyAttributesFrom(GV);
1610 LLVM_DEBUG(
dbgs() <<
" *** Substituting initializer allowed us to "
1611 <<
"simplify all users and delete global!\n");
1626 if (GS.NumStores == 1)
1634 CanHaveNonUndefGlobalInitializer)) {
1679 if (GVar->isConstant() || !GVar->hasInitializer())
1689 for (
User *U :
F->users())
1691 if (
Call->getCalledOperand() ==
F)
1698 if (Attrs.hasAttrSomewhere(
A, &AttrIndex))
1699 return Attrs.removeAttributeAtIndex(
C, AttrIndex,
A);
1704 F->setAttributes(
StripAttr(
F->getContext(),
F->getAttributes(),
A));
1705 for (
User *U :
F->users()) {
1729 for (
User *U :
F->users()) {
1739 if (BB.getTerminatingMustTailCall())
1742 return !
F->hasAddressTaken();
1751 return Res.first->second;
1759 auto CallSiteFreq = CallerBFI.
getBlockFreq(CallSiteBB);
1760 auto CallerEntryFreq =
1762 return CallSiteFreq < CallerEntryFreq * ColdProb;
1772 const std::vector<Function *> &AllCallsCold) {
1777 for (
User *U :
F.users()) {
1792 for (
User *U :
F->users())
1794 if (
Call->getCalledOperand() ==
F)
1809 if (CI->isInlineAsm())
1811 Function *CalledFn = CI->getCalledFunction();
1835 for (
User *U :
F->users()) {
1844 for (
User *U :
F->users())
1853 auto *M =
F->getParent();
1859 for (
User *U : PreallocatedCalls) {
1866 "Shouldn't call RemotePreallocated() on a musttail preallocated call");
1870 CallBase *PreallocatedSetup =
nullptr;
1871 for (
auto *It = OpBundles.
begin(); It != OpBundles.
end(); ++It) {
1872 if (It->getTag() ==
"preallocated") {
1874 OpBundles.
erase(It);
1878 assert(PreallocatedSetup &&
"Did not find preallocated bundle");
1883 "Unknown indirect call type");
1889 Builder.SetInsertPoint(PreallocatedSetup);
1890 auto *StackSave = Builder.CreateStackSave();
1892 Builder.CreateStackRestore(StackSave);
1903 for (
auto *
User : PreallocatedArgs) {
1905 assert(UseCall->getCalledFunction()->getIntrinsicID() ==
1906 Intrinsic::call_preallocated_arg &&
1907 "preallocated token use was not a llvm.call.preallocated.arg");
1910 Value *AllocaReplacement = ArgAllocas[AllocArgIndex];
1911 if (!AllocaReplacement) {
1912 auto AddressSpace = UseCall->getType()->getPointerAddressSpace();
1914 UseCall->getFnAttr(Attribute::Preallocated).getValueAsType();
1915 auto *InsertBefore = PreallocatedSetup->
getNextNode();
1916 Builder.SetInsertPoint(InsertBefore);
1918 Builder.CreateAlloca(ArgType,
AddressSpace,
nullptr,
"paarg");
1919 ArgAllocas[AllocArgIndex] = Alloca;
1920 AllocaReplacement = Alloca;
1923 UseCall->replaceAllUsesWith(AllocaReplacement);
1924 UseCall->eraseFromParent();
1944 std::vector<Function *> AllCallsCold;
1947 AllCallsCold.push_back(&
F);
1953 if (
F.hasFnAttribute(Attribute::Naked))
1957 if (!
F.hasName() && !
F.isDeclaration() && !
F.hasLocalLinkage())
1960 if (
deleteIfDead(
F, NotDiscardableComdats, DeleteFnCallback)) {
1974 if (!
F.isDeclaration()) {
1977 ChangedCFGCallback(
F);
1983 if (!
F.hasLocalLinkage())
1991 if (
F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) &&
1999 if (
F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
2016 (
TTI.useColdCCForColdCall(
F) &&
2018 ChangeableCCCache.
erase(&
F);
2031 if (
TTI.useFastCCForInternalCall(
F)) {
2039 if (
F.getAttributes().hasAttrSomewhere(Attribute::Nest) &&
2040 !
F.hasAddressTaken()) {
2064 if (GV.hasInitializer())
2066 auto &
DL = M.getDataLayout();
2072 GV.setInitializer(New);
2090 if (
F->isDeclaration())
2099 ++NumCtorsEvaluated;
2104 <<
F->getName() <<
"' to " << NewInitializers.size()
2106 for (
const auto &Pair : NewInitializers)
2107 Pair.first->setInitializer(Pair.second);
2109 GV->setConstant(
true);
2124 V.eraseFromParent();
2129 const Type *UsedArrayType = V.getValueType();
2147 Module *M = V.getParent();
2148 V.removeFromParent();
2154 NV->setSection(
"llvm.metadata");
2162 SmallPtrSet<GlobalValue *, 4> Used;
2163 SmallPtrSet<GlobalValue *, 4> CompilerUsed;
2164 GlobalVariable *UsedV;
2165 GlobalVariable *CompilerUsedV;
2177 using iterator = SmallPtrSet<GlobalValue *, 4>::iterator;
2178 using used_iterator_range = iterator_range<iterator>;
2180 iterator usedBegin() {
return Used.begin(); }
2181 iterator usedEnd() {
return Used.end(); }
2183 used_iterator_range used() {
2184 return used_iterator_range(usedBegin(), usedEnd());
2187 iterator compilerUsedBegin() {
return CompilerUsed.begin(); }
2188 iterator compilerUsedEnd() {
return CompilerUsed.end(); }
2190 used_iterator_range compilerUsed() {
2191 return used_iterator_range(compilerUsedBegin(), compilerUsedEnd());
2194 bool usedCount(GlobalValue *GV)
const {
return Used.count(GV); }
2196 bool compilerUsedCount(GlobalValue *GV)
const {
2197 return CompilerUsed.count(GV);
2200 bool usedErase(GlobalValue *GV) {
return Used.erase(GV); }
2201 bool compilerUsedErase(GlobalValue *GV) {
return CompilerUsed.erase(GV); }
2202 bool usedInsert(GlobalValue *GV) {
return Used.insert(GV).second; }
2204 bool compilerUsedInsert(GlobalValue *GV) {
2205 return CompilerUsed.insert(GV).second;
2208 void syncVariablesAndSets() {
2222 assert((!U.usedCount(&GA) || !U.compilerUsedCount(&GA)) &&
2223 "We should have removed the duplicated "
2224 "element from llvm.compiler.used");
2231 return !U.usedCount(&GA) && !U.compilerUsedCount(&GA);
2238 return U.usedCount(&GV) || U.compilerUsedCount(&GV);
2242 bool &RenameTarget) {
2246 RenameTarget =
false;
2267 RenameTarget =
true;
2278 Used.compilerUsedErase(GV);
2289 if (!J.hasName() && !J.isDeclaration() && !J.hasLocalLinkage())
2298 if (!IsModuleLocal(J))
2301 Constant *Aliasee = J.getAliasee();
2312 Target->removeDeadConstantUsers();
2319 J.replaceAllUsesWith(Aliasee);
2320 ++NumAliasesResolved;
2326 Target->setLinkage(J.getLinkage());
2327 Target->setDSOLocal(J.isDSOLocal());
2328 Target->setVisibility(J.getVisibility());
2329 Target->setDLLStorageClass(J.getDLLStorageClass());
2331 if (Used.usedErase(&J))
2334 if (Used.compilerUsedErase(&J))
2335 Used.compilerUsedInsert(
Target);
2341 ++NumAliasesRemoved;
2345 Used.syncVariablesAndSets();
2355 auto FuncIter = M.
begin();
2356 if (FuncIter == M.end())
2358 auto *TLI = &GetTLI(*FuncIter);
2360 if (!TLI->has(Func))
2372 if (!TLI->getLibFunc(*Fn,
F) ||
F != Func)
2389 if (
I.isDebugOrPseudoInst())
2433 ++NumCXXDtorsRemoved;
2477 if (!IF.use_empty() &&
2478 (!Callee->isDeclaration() ||
2479 none_of(IF.users(), [](
User *U) { return isa<GlobalAlias>(U); }))) {
2480 IF.replaceAllUsesWith(Callee);
2481 NumIFuncsResolved++;
2506 if (!GetTTI(*F).isMultiversionedFunction(*
F))
2515 for (
unsigned I = 0,
E = Phi->getNumIncomingValues();
I !=
E; ++
I)
2562 LLVM_DEBUG(
dbgs() <<
"Examining IFUNC " << IF.getName() <<
"\n");
2564 if (IF.isInterposable())
2584 if (Versions.
empty())
2588 VersionOf.
insert({V, &IF});
2589 auto [FeatIt, FeatInserted] = FeatureMask.
try_emplace(V);
2591 FeatIt->second = GetTTI(*V).getFeatureMask(*V);
2592 auto [PriorIt, PriorInserted] = PriorityMask.
try_emplace(V);
2594 PriorIt->second = GetTTI(*V).getPriorityMask(*V);
2599 return PriorityMask[
LHS].ugt(PriorityMask[
RHS]);
2603 VersionedFuncs.
try_emplace(&IF, std::move(Versions));
2614 if (CB->getCalledOperand() == CalleeIF) {
2615 Function *Caller = CB->getFunction();
2618 bool CallerIsFMV =
TTI.isMultiversionedFunction(*Caller);
2620 if (
auto It = VersionOf.
find(Caller); It != VersionOf.
end())
2621 CallerIF = It->second;
2624 auto [It, Inserted] = FeatureMask.
try_emplace(Caller);
2626 It->second =
TTI.getFeatureMask(*Caller);
2630 auto [It, Inserted] = CallSites.
try_emplace(Caller);
2633 CallerIFuncs.
insert(CallerIF);
2637 It->second.push_back(CB);
2642 if (CallSites.
empty())
2646 << CalleeIF->getResolverFunction()->getName() <<
"\n");
2654 bool AllowExpensiveChecks = CallerIsFMV &&
2660 for (
unsigned I = 0,
E = Callers.
size();
I <
E; ++
I) {
2662 if (J == Callees.
size())
2666 APInt CallerBits = FeatureMask[Caller];
2673 auto eliminateAvailableFeatures = [&](
unsigned BestCandidate) {
2675 while (K <
I && BestCandidate < Callees.
size()) {
2676 APInt MissingBits = FeatureMask[Callers[K]] & ~CallerBits;
2677 if (MissingBits.
isSubsetOf(FeatureMask[Callees[BestCandidate]])) {
2684 return BestCandidate;
2687 unsigned BestCandidate =
2688 AllowExpensiveChecks ? eliminateAvailableFeatures(J) : J;
2690 if (BestCandidate == Callees.
size())
2694 << (CallerIsFMV ?
"FMV" :
"regular") <<
" caller "
2695 << Caller->getName() <<
"\n");
2697 Function *Callee = Callees[BestCandidate];
2698 APInt CalleeBits = FeatureMask[Callee];
2705 if (
auto It = CallSites.
find(Caller); It != CallSites.
end()) {
2708 <<
" -> " << Callee->getName() <<
"\n");
2723 while (CallerBits.
isSubsetOf(FeatureMask[Callees[J]]) &&
2724 ++J < Callees.
size())
2729 auto &Callees = VersionedFuncs[CalleeIF];
2733 staticallyResolveCalls(NonFMVCallers, Callees,
false);
2737 auto &Callers = VersionedFuncs[CallerIF];
2738 staticallyResolveCalls(Callers, Callees,
true);
2741 if (CalleeIF->use_empty() ||
2742 all_of(CalleeIF->users(), [](
User *U) { return isa<GlobalAlias>(U); }))
2743 NumIFuncsResolved++;
2758 bool LocalChange =
true;
2759 std::optional<uint32_t> FirstNotFullyEvaluatedPriority;
2761 while (LocalChange) {
2762 LocalChange =
false;
2764 NotDiscardableComdats.
clear();
2768 NotDiscardableComdats.
insert(
C);
2770 if (
const Comdat *
C =
F.getComdat())
2771 if (!
F.isDefTriviallyDead())
2772 NotDiscardableComdats.
insert(
C);
2774 if (
const Comdat *
C = GA.getComdat())
2775 if (!GA.isDiscardableIfUnused() || !GA.use_empty())
2776 NotDiscardableComdats.
insert(
C);
2780 NotDiscardableComdats, ChangedCFGCallback,
2786 if (FirstNotFullyEvaluatedPriority &&
2787 *FirstNotFullyEvaluatedPriority != Priority)
2791 FirstNotFullyEvaluatedPriority = Priority;
2797 NotDiscardableComdats);
2830 auto &
DL = M.getDataLayout();
2852 ChangedCFGCallback, DeleteFnCallback))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
static bool IsSafeComputationToRemove(Value *V, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
Given a value that is stored to a global but never read, determine whether it's safe to remove the st...
static Function * FindAtExitLibFunc(Module &M, function_ref< TargetLibraryInfo &(Function &)> GetTLI, LibFunc Func)
static bool optimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal, const DataLayout &DL, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
static Function * hasSideeffectFreeStaticResolution(GlobalIFunc &IF)
static bool tryToOptimizeStoreOfAllocationToGlobal(GlobalVariable *GV, CallInst *CI, const DataLayout &DL, TargetLibraryInfo *TLI)
If we have a global that is only initialized with a fixed size allocation try to transform the progra...
static void ConstantPropUsersOf(Value *V, const DataLayout &DL, TargetLibraryInfo *TLI)
Walk the use list of V, constant folding all of the instructions that are foldable.
static bool OptimizeStaticIFuncs(Module &M)
Find IFuncs that have resolvers that always point at the same statically known callee,...
static bool hasOnlyColdCalls(Function &F, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, ChangeableCCCacheTy &ChangeableCCCache)
static bool allUsesOfLoadedValueWillTrapIfNull(const GlobalVariable *GV)
Return true if all uses of any loads from GV will trap if the loaded value is null.
static bool hasChangeableCCImpl(Function *F)
Return true if this is a calling convention that we'd like to change.
static bool AllUsesOfValueWillTrapIfNull(const Value *V, SmallPtrSetImpl< const PHINode * > &PHIs)
Return true if all users of the specified value will trap if the value is dynamically null.
static GlobalVariable * OptimizeGlobalAddressOfAllocation(GlobalVariable *GV, CallInst *CI, uint64_t AllocSize, Constant *InitVal, const DataLayout &DL, TargetLibraryInfo *TLI)
This function takes the specified global variable, and transforms the program as if it always contain...
static bool collectVersions(Value *V, SmallVectorImpl< Function * > &Versions, function_ref< TargetTransformInfo &(Function &)> GetTTI)
static bool IsEmptyAtExitFunction(const Function &Fn)
Returns whether the given function is an empty C++ destructor or atexit handler and can therefore be ...
static bool collectSRATypes(DenseMap< uint64_t, GlobalPart > &Parts, GlobalVariable *GV, const DataLayout &DL)
Look at all uses of the global and determine which (offset, type) pairs it can be split into.
static bool valueIsOnlyUsedLocallyOrStoredToOneGlobal(const CallInst *CI, const GlobalVariable *GV)
Scan the use-list of GV checking to make sure that there are no complex uses of GV.
static bool OptimizeFunctions(Module &M, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, function_ref< DominatorTree &(Function &)> LookupDomTree, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats, function_ref< void(Function &F)> ChangedCFGCallback, function_ref< void(Function &F)> DeleteFnCallback)
static bool DeleteDeadIFuncs(Module &M, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats)
static void RemoveAttribute(Function *F, Attribute::AttrKind A)
static bool hasChangeableCC(Function *F, ChangeableCCCacheTy &ChangeableCCCache)
static bool deleteIfDead(GlobalValue &GV, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats, function_ref< void(Function &)> DeleteFnCallback=nullptr)
static void RemovePreallocated(Function *F)
static cl::opt< bool > OptimizeNonFMVCallers("optimize-non-fmv-callers", cl::desc("Statically resolve calls to versioned " "functions from non-versioned callers."), cl::init(true), cl::Hidden)
static bool processGlobal(GlobalValue &GV, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< DominatorTree &(Function &)> LookupDomTree)
Analyze the specified global variable and optimize it if possible.
static bool isColdCallSite(CallBase &CB, BlockFrequencyInfo &CallerBFI)
Return true if the block containing the call site has a BlockFrequency of less than ColdCCRelFreq% of...
static void transferSRADebugInfo(GlobalVariable *GV, GlobalVariable *NGV, uint64_t FragmentOffsetInBits, uint64_t FragmentSizeInBits, uint64_t VarSize)
Copy over the debug info for a variable to its SRA replacements.
static cl::opt< bool > EnableColdCCStressTest("enable-coldcc-stress-test", cl::desc("Enable stress test of coldcc by adding " "calling conv to all internal functions."), cl::init(false), cl::Hidden)
static bool OptimizeGlobalAliases(Module &M, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats)
static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal)
At this point, we have learned that the only two values ever stored into GV are its initializer and O...
static void ChangeCalleesToFastCall(Function *F)
Walk all of the direct calls of the specified function, changing them to FastCC.
static bool hasMustTailCallers(Function *F)
static bool OptimizeNonTrivialIFuncs(Module &M, function_ref< TargetTransformInfo &(Function &)> GetTTI)
static bool OptimizeGlobalVars(Module &M, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< DominatorTree &(Function &)> LookupDomTree, SmallPtrSetImpl< const Comdat * > &NotDiscardableComdats)
static void allUsesOfLoadAndStores(GlobalVariable *GV, SmallVector< Value *, 4 > &Uses)
Get all the loads/store uses for global variable GV.
static bool OptimizeEmptyGlobalAtExitDtors(Function *CXAAtExitFn, bool isCXX)
static bool mayHaveOtherReferences(GlobalValue &GV, const LLVMUsed &U)
static void changeCallSitesToColdCC(Function *F)
static AttributeList StripAttr(LLVMContext &C, AttributeList Attrs, Attribute::AttrKind A)
static bool hasInvokeCallers(Function *F)
static void setUsedInitializer(GlobalVariable &V, const SmallPtrSetImpl< GlobalValue * > &Init)
static cl::opt< unsigned > MaxIFuncVersions("max-ifunc-versions", cl::Hidden, cl::init(5), cl::desc("Maximum number of caller/callee versions that is allowed for " "using the expensive (cubic) static resolution algorithm."))
static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV, const DataLayout &DL, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
The specified global has only one non-null value stored into it.
static bool isValidCandidateForColdCC(Function &F, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, const std::vector< Function * > &AllCallsCold)
static cl::opt< int > ColdCCRelFreq("coldcc-rel-freq", cl::Hidden, cl::init(2), cl::desc("Maximum block frequency, expressed as a percentage of caller's " "entry frequency, for a call site to be considered cold for enabling " "coldcc"))
static bool optimizeGlobalsInModule(Module &M, const DataLayout &DL, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI, function_ref< DominatorTree &(Function &)> LookupDomTree, function_ref< void(Function &F)> ChangedCFGCallback, function_ref< void(Function &F)> DeleteFnCallback)
static bool EvaluateStaticConstructor(Function *F, const DataLayout &DL, TargetLibraryInfo *TLI)
Evaluate static constructors in the function, if we can.
static bool CleanupConstantGlobalUsers(GlobalVariable *GV, const DataLayout &DL)
We just marked GV constant.
SmallDenseMap< Function *, bool, 8 > ChangeableCCCacheTy
static bool isLeakCheckerRoot(GlobalVariable *GV)
Is this global variable possibly used by a leak checker as a root?
static bool forwardStoredOnceStore(GlobalVariable *GV, const StoreInst *StoredOnceStore, function_ref< DominatorTree &(Function &)> LookupDomTree)
static int compareNames(Constant *const *A, Constant *const *B)
static bool CleanupPointerRootUsers(GlobalVariable *GV, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
This GV is a pointer root.
static bool isPointerValueDeadOnEntryToFunction(const Function *F, GlobalValue *GV, function_ref< DominatorTree &(Function &)> LookupDomTree)
static bool processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS, function_ref< TargetTransformInfo &(Function &)> GetTTI, function_ref< TargetLibraryInfo &(Function &)> GetTLI, function_ref< DominatorTree &(Function &)> LookupDomTree)
Analyze the specified global variable and optimize it if possible.
static bool hasUsesToReplace(GlobalAlias &GA, const LLVMUsed &U, bool &RenameTarget)
static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV)
static GlobalVariable * SRAGlobal(GlobalVariable *GV, const DataLayout &DL)
Perform scalar replacement of aggregates on the specified global variable.
static bool hasUseOtherThanLLVMUsed(GlobalAlias &GA, const LLVMUsed &U)
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Machine Check Debug Module
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
This file contains the declarations for profiling metadata utility functions.
Remove Loads Into Fake Uses
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
This class represents a conversion between pointers from one address space to another.
an instruction to allocate memory on the stack
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
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 LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Represents analyses that only rely on functions' control flow.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
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.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
static LLVM_ABI CallBase * Create(CallBase *CB, ArrayRef< OperandBundleDef > Bundles, InsertPosition InsertPt=nullptr)
Create a clone of CB with a different set of operand bundles and insert it before InsertPt.
void setCalledOperand(Value *V)
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).
This class represents a function call, abstracting a target machine's calling convention.
bool isMustTailCall() const
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getPredicate() const
Return the predicate for this instruction.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
A constant value that is initialized with an expression using other constant values.
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static LLVM_ABI Constant * getAddrSpaceCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This is an important base class in LLVM.
const Constant * stripPointerCasts() const
LLVM_ABI void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
LLVM_ABI bool extractIfOffset(int64_t &Offset) const
If this is a constant offset, extract it.
static LLVM_ABI std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)
Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...
static LLVM_ABI DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)
Prepend DIExpr with the given opcodes and optionally turn it into a stack value.
A pair of DIGlobalVariable and DIExpression.
uint64_t getSizeInBits() const
Base class for variables.
A parsed version of the target data layout string in and methods for querying it.
static DebugLoc getCompilerGenerated()
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
This class evaluates LLVM IR, producing the Constant representing each SSA instruction.
DenseMap< GlobalVariable *, Constant * > getMutatedInitializers() const
bool EvaluateFunction(Function *F, Constant *&RetVal, const SmallVectorImpl< Constant * > &ActualArgs)
Evaluate a call to function F, returning true if successful, false if we can't evaluate it.
const SmallPtrSetImpl< GlobalVariable * > & getInvariants() const
const BasicBlock & getEntryBlock() const
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
const Function & getFunction() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
const Constant * getAliasee() const
LLVM_ABI const Function * getResolverFunction() const
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
bool isImplicitDSOLocal() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
LLVM_ABI const Comdat * getComdat() const
ThreadLocalMode getThreadLocalMode() const
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing module and deletes it.
PointerType * getType() const
Global values are always pointers.
LLVM_ABI bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time ...
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
bool hasGlobalUnnamedAddr() const
UnnamedAddr getUnnamedAddr() const
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
static bool isDiscardableIfUnused(LinkageTypes Linkage)
Whether the definition of this global may be discarded if it is not used in its compilation unit.
@ InternalLinkage
Rename collisions when linking (static functions).
@ AppendingLinkage
Special purpose, only applies to global arrays.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
bool isExternallyInitialized() const
MaybeAlign getAlign() const
Returns the alignment of the given variable.
void setConstant(bool Val)
LLVM_ABI void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
LLVM_ABI void getDebugInfo(SmallVectorImpl< DIGlobalVariableExpression * > &GVs) const
Fill the vector with all debug info attachements.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
LLVM_ABI void addDebugInfo(DIGlobalVariableExpression *GV)
Attach a DIGlobalVariableExpression.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
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.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this load instruction.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
LLVMContext & getContext() const
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
This class wraps the llvm.memcpy/memmove intrinsics.
A Module instance is used to store all the information related to an LLVM module.
void insertGlobalVariable(GlobalVariable *GV)
Insert global variable GV at the end of the global variable list and take ownership.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
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.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
iterator erase(const_iterator CI)
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.
Value * getValueOperand()
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
int compare(StringRef RHS) const
compare - Compare two strings; the result is negative, zero, or positive if this string is lexicograp...
Class to represent struct types.
ArrayRef< Type * > elements() const
bool isOpaque() const
Return true if this is a type with an identity that has no body specified yet.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
@ ScalableVectorTyID
Scalable SIMD vector type.
@ FixedVectorTyID
Fixed width SIMD vector type.
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
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.
LLVM_ABI void set(Value *Val)
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
user_iterator_impl< User > user_iterator
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
This class represents zero extension of integer types.
std::pair< iterator, bool > insert(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ X86_ThisCall
Similar to X86_StdCall.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
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.
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,...
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.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI Constant * ConstantFoldInstruction(const Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstruction - Try to constant fold the specified instruction.
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
constexpr from_range_t from_range
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
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.
LLVM_ABI bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
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...
bool isSafeToDestroyConstant(const Constant *C)
It is safe to destroy a constant iff it is only used by constants itself.
LLVM_ABI Align getOrEnforceKnownAlignment(Value *V, MaybeAlign PrefAlign, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to ensure that the alignment of V is at least PrefAlign bytes.
bool optimizeGlobalCtorsList(Module &M, function_ref< bool(uint32_t, Function *)> ShouldRemove)
Call "ShouldRemove" for every entry in M's global_ctor list and remove the entries for which it retur...
void sort(IteratorTy Start, IteratorTy End)
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.
bool isPointerTy(const Type *T)
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
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...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(SmallVectorImpl< WeakTrackingVH > &DeadInsts, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow instructions that are not...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI GlobalVariable * collectUsedGlobalVariables(const Module &M, SmallVectorImpl< GlobalValue * > &Vec, bool CompilerUsed)
Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...
Part of the global at a specific offset, which is only accessed through loads and stores with the giv...
This struct is a compact representation of a valid (non-zero power of two) alignment.
As we analyze each global or thread-local variable, keep track of some information about it.
@ InitializerStored
This global is stored to, but the only thing stored is the constant it was initialized with.
@ StoredOnce
This global is stored to, but only its initializer and one other value is ever stored to it.
static bool analyzeGlobal(const Value *V, GlobalStatus &GS)
Look at all uses of the global and fill in the GlobalStatus structure.
Various options to control the behavior of getObjectSize.
Function object to check whether the first component of a container supported by std::get (like std::...