74#define DEBUG_TYPE "globalopt"
76STATISTIC(NumMarked ,
"Number of globals marked constant");
77STATISTIC(NumUnnamed ,
"Number of globals marked unnamed_addr");
78STATISTIC(NumSRA ,
"Number of aggregate globals broken into scalars");
79STATISTIC(NumSubstitute,
"Number of globals with initializers stored into them");
81STATISTIC(NumGlobUses ,
"Number of global uses devirtualized");
82STATISTIC(NumLocalized ,
"Number of globals localized");
83STATISTIC(NumShrunkToBool ,
"Number of global vars shrunk to booleans");
84STATISTIC(NumFastCallFns ,
"Number of functions converted to fastcc");
85STATISTIC(NumCtorsEvaluated,
"Number of static ctors evaluated");
86STATISTIC(NumNestRemoved ,
"Number of nest attributes removed");
87STATISTIC(NumAliasesResolved,
"Number of global aliases resolved");
88STATISTIC(NumAliasesRemoved,
"Number of global aliases eliminated");
89STATISTIC(NumCXXDtorsRemoved,
"Number of global C++ destructors removed");
90STATISTIC(NumAtExitRemoved,
"Number of atexit handlers removed");
91STATISTIC(NumInternalFunc,
"Number of internal functions");
92STATISTIC(NumColdCC,
"Number of functions marked coldcc");
93STATISTIC(NumIFuncsResolved,
"Number of statically resolved IFuncs");
94STATISTIC(NumIFuncsDeleted,
"Number of IFuncs removed");
96 "Number of global arrays padded to alignment boundary");
100 cl::desc(
"Statically resolve calls to versioned "
101 "functions from non-versioned callers."),
106 cl::desc(
"Enable stress test of coldcc by adding "
107 "calling conv to all internal functions."),
113 "Maximum block frequency, expressed as a percentage of caller's "
114 "entry frequency, for a call site to be considered cold for enabling "
136 Type *Ty = Types.pop_back_val();
143 if (cast<VectorType>(Ty)->getElementType()->
isPointerTy())
147 Types.push_back(cast<ArrayType>(Ty)->getElementType());
153 if (isa<PointerType>(InnerTy))
return true;
154 if (isa<StructType>(InnerTy) || isa<ArrayType>(InnerTy) ||
155 isa<VectorType>(InnerTy))
156 Types.push_back(InnerTy);
161 if (--Limit == 0)
return true;
162 }
while (!Types.empty());
172 if (isa<Constant>(V))
176 if (isa<LoadInst>(V) || isa<InvokeInst>(V) || isa<Argument>(V) ||
183 if (
I->mayHaveSideEffects())
186 if (!
GEP->hasAllConstantIndices())
188 }
else if (
I->getNumOperands() != 1) {
192 V =
I->getOperand(0);
211 bool Changed =
false;
219 while (!Worklist.
empty()) {
221 if (
StoreInst *SI = dyn_cast<StoreInst>(U)) {
222 Value *V = SI->getValueOperand();
223 if (isa<Constant>(V)) {
225 SI->eraseFromParent();
228 Dead.push_back(std::make_pair(
I, SI));
230 }
else if (
MemSetInst *MSI = dyn_cast<MemSetInst>(U)) {
231 if (isa<Constant>(MSI->getValue())) {
233 MSI->eraseFromParent();
234 }
else if (
Instruction *
I = dyn_cast<Instruction>(MSI->getValue())) {
236 Dead.push_back(std::make_pair(
I, MSI));
239 GlobalVariable *MemSrc = dyn_cast<GlobalVariable>(MTI->getSource());
242 MTI->eraseFromParent();
243 }
else if (
Instruction *
I = dyn_cast<Instruction>(MTI->getSource())) {
245 Dead.push_back(std::make_pair(
I, MTI));
247 }
else if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
248 if (isa<GEPOperator>(CE))
253 for (
int i = 0, e = Dead.size(); i != e; ++i) {
255 Dead[i].second->eraseFromParent();
260 Instruction *J = dyn_cast<Instruction>(
I->getOperand(0));
263 I->eraseFromParent();
266 I->eraseFromParent();
283 bool Changed =
false;
288 if (
auto *OpI = dyn_cast<Instruction>(
Op))
290 I->eraseFromParent();
293 while (!WorkList.
empty()) {
295 if (!Visited.
insert(U).second)
298 if (
auto *BO = dyn_cast<BitCastOperator>(U))
300 if (
auto *ASC = dyn_cast<AddrSpaceCastOperator>(U))
302 else if (
auto *
GEP = dyn_cast<GEPOperator>(U))
304 else if (
auto *LI = dyn_cast<LoadInst>(U)) {
307 Type *Ty = LI->getType();
309 LI->replaceAllUsesWith(Res);
314 Value *PtrOp = LI->getPointerOperand();
319 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address)
320 PtrOp =
II->getArgOperand(0);
324 LI->replaceAllUsesWith(
Value);
328 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(U)) {
335 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address)
361 auto AppendUses = [&](
Value *V) {
362 for (
Use &U : V->uses())
363 if (Visited.
insert(&U).second)
367 while (!Worklist.
empty()) {
369 User *V = U->getUser();
371 auto *
GEP = dyn_cast<GEPOperator>(V);
372 if (isa<BitCastOperator>(V) || isa<AddrSpaceCastOperator>(V) ||
373 (
GEP &&
GEP->hasAllConstantIndices())) {
381 if (isa<StoreInst>(V) && U->getOperandNo() == 0)
387 if (
Ptr != GV ||
Offset.getActiveBits() >= 64)
393 const auto &[It, Inserted] =
395 if (Ty != It->second.Ty)
399 It->second.Initializer =
401 if (!It->second.Initializer) {
402 LLVM_DEBUG(
dbgs() <<
"Global SRA: Failed to evaluate initializer of "
403 << *GV <<
" with type " << *Ty <<
" at offset "
404 <<
Offset.getZExtValue());
414 auto *SI = dyn_cast<StoreInst>(V);
418 Constant *StoredConst = dyn_cast<Constant>(SI->getOperand(0));
423 return Initializer != StoredConst;
426 It->second.IsLoaded |= isa<LoadInst>(V);
427 It->second.IsStored |= IsStored(V, It->second.Initializer);
432 if (
auto *
C = dyn_cast<Constant>(V)) {
452 for (
auto *GVE : GVs) {
455 int64_t CurVarOffsetInBytes = 0;
457 uint64_t FragmentEndInBits = FragmentOffsetInBits + FragmentSizeInBits;
464 if (CurVarOffsetInBytes < 0)
468 CurVarOffsetInBits = CHAR_BIT * (
uint64_t)CurVarOffsetInBytes;
471 if (CurVarOffsetInBits >= FragmentEndInBits)
475 uint64_t CurVarEndInBits = CurVarOffsetInBits + CurVarSize;
477 if (CurVarSize != 0 &&
478 CurVarEndInBits <= FragmentOffsetInBits)
483 if (CurVarSize != 0 &&
484 CurVarOffsetInBits >= FragmentOffsetInBits &&
485 CurVarEndInBits <= FragmentEndInBits) {
487 (CurVarOffsetInBits - FragmentOffsetInBits) / 8;
488 if (CurVarOffsetInFragment != 0)
489 Expr = DIExpression::get(Expr->
getContext(), {dwarf::DW_OP_plus_uconst,
490 CurVarOffsetInFragment});
492 Expr = DIExpression::get(Expr->
getContext(), {});
494 DIGlobalVariableExpression::get(GVE->getContext(), Var, Expr);
500 if (FragmentSizeInBits < VarSize) {
501 if (CurVarOffsetInBits > FragmentOffsetInBits)
503 uint64_t CurVarFragmentOffsetInBits =
504 FragmentOffsetInBits - CurVarOffsetInBits;
505 uint64_t CurVarFragmentSizeInBits = FragmentSizeInBits;
506 if (CurVarSize != 0 && CurVarEndInBits < FragmentEndInBits)
507 CurVarFragmentSizeInBits -= (FragmentEndInBits - CurVarEndInBits);
508 if (CurVarOffsetInBits)
509 Expr = DIExpression::get(Expr->
getContext(), {});
511 Expr, CurVarFragmentOffsetInBits, CurVarFragmentSizeInBits))
516 auto *NGVE = DIGlobalVariableExpression::get(GVE->getContext(), Var, Expr);
541 unsigned NumParts =
count_if(Parts, [](
const auto &Pair) {
542 return Pair.second.IsLoaded && Pair.second.IsStored;
549 for (
const auto &Pair : Parts) {
551 {Pair.first, Pair.second.Ty, Pair.second.Initializer});
557 for (
const auto &[OffsetForTy, Ty,
_] : TypesVector) {
562 Offset = OffsetForTy +
DL.getTypeAllocSize(Ty);
569 LLVM_DEBUG(
dbgs() <<
"PERFORMING GLOBAL SRA ON: " << *GV <<
"\n");
572 Align StartAlignment =
578 unsigned NameSuffix = 0;
579 for (
auto &[OffsetForTy, Ty, Initializer] : TypesVector) {
581 *GV->
getParent(), Ty,
false, GlobalVariable::InternalLinkage,
582 Initializer, GV->
getName() +
"." +
Twine(NameSuffix++), GV,
586 NewGlobals.
insert({OffsetForTy, NGV});
597 DL.getTypeAllocSizeInBits(Ty), VarSize);
604 auto AppendUsers = [&](
Value *V) {
605 for (
User *U : V->users())
606 if (Visited.
insert(U).second)
610 while (!Worklist.
empty()) {
612 if (isa<BitCastOperator>(V) || isa<AddrSpaceCastOperator>(V) ||
613 isa<GEPOperator>(V)) {
615 if (isa<Instruction>(V))
624 assert(
Ptr == GV &&
"Load/store must be from/to global");
626 assert(NGV &&
"Must have replacement global for this offset");
633 if (
auto *LI = dyn_cast<LoadInst>(V)) {
634 LI->setOperand(0, NGV);
635 LI->setAlignment(NewAlign);
637 auto *SI = cast<StoreInst>(V);
638 SI->setOperand(1, NGV);
639 SI->setAlignment(NewAlign);
645 "Other users can only be dead constants");
655 return NewGlobals.
begin()->second;
663 for (
const User *U : V->users()) {
670 if (isa<LoadInst>(U)) {
672 }
else if (
const StoreInst *SI = dyn_cast<StoreInst>(U)) {
673 if (SI->getOperand(0) == V) {
676 }
else if (
const CallInst *CI = dyn_cast<CallInst>(U)) {
677 if (CI->getCalledOperand() != V) {
680 }
else if (
const InvokeInst *
II = dyn_cast<InvokeInst>(U)) {
681 if (
II->getCalledOperand() != V) {
689 }
else if (
const PHINode *PN = dyn_cast<PHINode>(U)) {
694 }
else if (isa<ICmpInst>(U) &&
695 !ICmpInst::isSigned(cast<ICmpInst>(U)->getPredicate()) &&
696 isa<LoadInst>(U->getOperand(0)) &&
697 isa<ConstantPointerNull>(U->getOperand(1))) {
698 assert(isa<GlobalValue>(cast<LoadInst>(U->getOperand(0))
699 ->getPointerOperand()
700 ->stripPointerCasts()) &&
701 "Should be GlobalVariable");
718 while (!Worklist.
empty()) {
720 for (
const auto *U :
P->users()) {
721 if (
auto *LI = dyn_cast<LoadInst>(U)) {
725 }
else if (
auto *SI = dyn_cast<StoreInst>(U)) {
727 if (SI->getPointerOperand() !=
P)
729 }
else if (
auto *CE = dyn_cast<ConstantExpr>(U)) {
730 if (CE->stripPointerCasts() != GV)
749 while (!Worklist.
empty()) {
751 for (
auto *U :
P->users()) {
752 if (
auto *CE = dyn_cast<ConstantExpr>(U)) {
757 assert((isa<LoadInst>(U) || isa<StoreInst>(U)) &&
758 "Expect only load or store instructions");
765 bool Changed =
false;
766 for (
auto UI = V->user_begin(), E = V->user_end(); UI != E; ) {
772 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
773 LI->setOperand(0, NewV);
775 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(
I)) {
776 if (SI->getOperand(1) == V) {
777 SI->setOperand(1, NewV);
780 }
else if (isa<CallInst>(
I) || isa<InvokeInst>(
I)) {
787 bool PassedAsArg =
false;
788 for (
unsigned i = 0, e = CB->
arg_size(); i != e; ++i)
796 UI = V->user_begin();
802 if (CI->use_empty()) {
804 CI->eraseFromParent();
809 Idxs.
reserve(GEPI->getNumOperands()-1);
812 if (
Constant *
C = dyn_cast<Constant>(*i))
816 if (Idxs.
size() == GEPI->getNumOperands()-1)
820 if (GEPI->use_empty()) {
822 GEPI->eraseFromParent();
837 bool Changed =
false;
841 bool AllNonStoreUsesGone =
true;
845 if (
LoadInst *LI = dyn_cast<LoadInst>(GlobalUser)) {
848 if (LI->use_empty()) {
849 LI->eraseFromParent();
852 AllNonStoreUsesGone =
false;
854 }
else if (isa<StoreInst>(GlobalUser)) {
856 assert(GlobalUser->getOperand(1) == GV &&
857 "Must be storing *to* the global");
859 AllNonStoreUsesGone =
false;
863 assert((isa<PHINode>(GlobalUser) || isa<SelectInst>(GlobalUser) ||
864 isa<ConstantExpr>(GlobalUser) || isa<CmpInst>(GlobalUser) ||
865 isa<BitCastInst>(GlobalUser) ||
866 isa<GetElementPtrInst>(GlobalUser) ||
867 isa<AddrSpaceCastInst>(GlobalUser)) &&
868 "Only expect load and stores!");
873 LLVM_DEBUG(
dbgs() <<
"OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV
880 if (AllNonStoreUsesGone) {
904 I->replaceAllUsesWith(NewC);
908 while (UI != E && *UI ==
I)
911 I->eraseFromParent();
925 LLVM_DEBUG(
errs() <<
"PROMOTING GLOBAL: " << *GV <<
" CALL = " << *CI
944 if (!isa<UndefValue>(InitVal)) {
947 Builder.
CreateMemSet(NewGV, InitVal, AllocSize, std::nullopt);
959 bool InitBoolUsed =
false;
964 for (
auto *U : Guses) {
965 if (
StoreInst *SI = dyn_cast<StoreInst>(U)) {
970 !isa<ConstantPointerNull>(SI->getValueOperand())),
971 InitBool,
false,
Align(1), SI->getOrdering(),
972 SI->getSyncScopeID(), SI->getIterator());
973 SI->eraseFromParent();
994 case ICmpInst::ICMP_ULT:
997 case ICmpInst::ICMP_UGE:
1000 case ICmpInst::ICMP_ULE:
1001 case ICmpInst::ICMP_EQ:
1004 case ICmpInst::ICMP_NE:
1005 case ICmpInst::ICMP_UGT:
1015 if (!InitBoolUsed) {
1017 cast<StoreInst>(InitBool->
user_back())->eraseFromParent();
1044 while (!Worklist.
empty()) {
1046 if (!Visited.
insert(V).second)
1049 for (
const Use &VUse : V->uses()) {
1050 const User *U = VUse.getUser();
1051 if (isa<LoadInst>(U) || isa<CmpInst>(U))
1054 if (
auto *SI = dyn_cast<StoreInst>(U)) {
1055 if (SI->getValueOperand() == V &&
1056 SI->getPointerOperand()->stripPointerCasts() != GV)
1061 if (
auto *GEPI = dyn_cast<GetElementPtrInst>(U)) {
1098 if (AllocSize >= 2048)
1140 if (
Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) {
1145 if (
auto *CI = dyn_cast<CallInst>(StoredOnceVal)) {
1146 auto *TLI = &GetTLI(*CI->getFunction());
1176 if (!isa<LoadInst>(U) && !isa<StoreInst>(U))
1197 "No reason to shrink to bool!");
1204 bool IsOneZero =
false;
1205 bool EmitOneOrZero =
true;
1206 auto *CI = dyn_cast<ConstantInt>(OtherVal);
1207 if (CI && CI->getValue().getActiveBits() <= 64) {
1208 IsOneZero = InitVal->
isNullValue() && CI->isOne();
1211 if (CIInit && CIInit->getValue().getActiveBits() <= 64) {
1212 uint64_t ValInit = CIInit->getZExtValue();
1213 uint64_t ValOther = CI->getZExtValue();
1214 uint64_t ValMinus = ValOther - ValInit;
1216 for(
auto *GVe : GVs){
1220 unsigned SizeInOctets =
1232 dwarf::DW_OP_deref_size, SizeInOctets,
1233 dwarf::DW_OP_constu, ValMinus,
1234 dwarf::DW_OP_mul, dwarf::DW_OP_constu, ValInit,
1236 bool WithStackValue =
true;
1239 DIGlobalVariableExpression::get(NewGV->
getContext(), DGV, E);
1242 EmitOneOrZero =
false;
1246 if (EmitOneOrZero) {
1255 if (
StoreInst *SI = dyn_cast<StoreInst>(UI)) {
1257 bool StoringOther = SI->getOperand(0) == OtherVal;
1260 if (StoringOther || SI->getOperand(0) == InitVal) {
1267 Instruction *StoredVal = cast<Instruction>(SI->getOperand(0));
1272 if (
LoadInst *LI = dyn_cast<LoadInst>(StoredVal)) {
1273 assert(LI->getOperand(0) == GV &&
"Not a copy!");
1277 false,
Align(1), LI->getOrdering(),
1278 LI->getSyncScopeID(), LI->getIterator());
1280 assert((isa<CastInst>(StoredVal) || isa<SelectInst>(StoredVal)) &&
1281 "This is not a form that we understand!");
1283 assert(isa<LoadInst>(StoreVal) &&
"Not a load of NewGV!");
1287 new StoreInst(StoreVal, NewGV,
false,
Align(1), SI->getOrdering(),
1288 SI->getSyncScopeID(), SI->getIterator());
1332 if (
auto *
F = dyn_cast<Function>(&GV))
1333 Dead = (
F->isDeclaration() &&
F->use_empty()) ||
F->isDefTriviallyDead();
1340 if (
auto *
F = dyn_cast<Function>(&GV)) {
1341 if (DeleteFnCallback)
1342 DeleteFnCallback(*
F);
1366 for (
auto *U : GV->
users()) {
1370 assert(
I->getParent()->getParent() ==
F);
1372 if (
auto *LI = dyn_cast<LoadInst>(
I))
1374 else if (
auto *SI = dyn_cast<StoreInst>(
I))
1384 auto &DT = LookupDomTree(*
const_cast<Function *
>(
F));
1395 const unsigned Threshold = 100;
1396 if (Loads.
size() * Stores.
size() > Threshold)
1399 for (
auto *L : Loads) {
1400 auto *LTy = L->getType();
1407 DL.getTypeStoreSize(LTy).getFixedValue() <=
1408 DL.getTypeStoreSize(STy).getFixedValue();
1426 if (!isa<Constant>(StoredOnceValue))
1431 if (
auto *LI = dyn_cast<LoadInst>(U)) {
1432 if (LI->getFunction() ==
F &&
1433 LI->getType() == StoredOnceValue->
getType() && LI->isSimple())
1438 bool MadeChange =
false;
1439 if (!Loads.
empty()) {
1440 auto &DT = LookupDomTree(*
const_cast<Function *
>(
F));
1441 for (
auto *LI : Loads) {
1442 if (DT.
dominates(StoredOnceStore, LI)) {
1443 LI->replaceAllUsesWith(
const_cast<Value *
>(StoredOnceValue));
1444 LI->eraseFromParent();
1468 if (!GS.HasMultipleAccessingFunctions &&
1469 GS.AccessingFunction &&
1473 GS.AccessingFunction->doesNotRecurse() &&
1480 GS.AccessingFunction->getEntryBlock().begin().getNonConst();
1484 nullptr, GV->
getName(), FirstI);
1494 bool Changed =
false;
1525 if (GS.Ordering == AtomicOrdering::NotAtomic) {
1536 LLVM_DEBUG(
dbgs() <<
" *** Marking constant allowed us to simplify "
1537 <<
"all users and delete global!\n");
1551 Value *StoredOnceValue = GS.getStoredOnceValue();
1554 const_cast<Function &
>(*GS.StoredOnceStore->getFunction());
1555 bool CanHaveNonUndefGlobalInitializer =
1556 GetTTI(StoreFn).canHaveNonUndefGlobalInitializerInAddressSpace(
1565 auto *SOVConstant = dyn_cast<Constant>(StoredOnceValue);
1567 DL.getTypeAllocSize(SOVConstant->getType()) ==
1569 CanHaveNonUndefGlobalInitializer) {
1580 NGV->copyAttributesFrom(GV);
1590 LLVM_DEBUG(
dbgs() <<
" *** Substituting initializer allowed us to "
1591 <<
"simplify all users and delete global!\n");
1606 if (GS.NumStores == 1)
1612 if (SOVConstant && GS.Ordering == AtomicOrdering::NotAtomic &&
1614 CanHaveNonUndefGlobalInitializer)) {
1640 bool Changed =
false;
1642 auto NewUnnamedAddr = GV.
hasLocalLinkage() ? GlobalValue::UnnamedAddr::Global
1643 : GlobalValue::UnnamedAddr::Local;
1655 auto *GVar = dyn_cast<GlobalVariable>(&GV);
1659 if (GVar->isConstant() || !GVar->hasInitializer())
1669 for (
User *U :
F->users()) {
1670 if (isa<BlockAddress>(U))
1679 if (Attrs.hasAttrSomewhere(
A, &AttrIndex))
1680 return Attrs.removeAttributeAtIndex(
C, AttrIndex,
A);
1685 F->setAttributes(
StripAttr(
F->getContext(),
F->getAttributes(),
A));
1686 for (
User *U :
F->users()) {
1687 if (isa<BlockAddress>(U))
1712 for (
User *U :
F->users()) {
1713 if (isa<BlockAddress>(U))
1715 CallInst* CI = dyn_cast<CallInst>(U);
1724 if (BB.getTerminatingMustTailCall())
1727 return !
F->hasAddressTaken();
1736 return Res.first->second;
1744 auto CallSiteFreq = CallerBFI.
getBlockFreq(CallSiteBB);
1745 auto CallerEntryFreq =
1747 return CallSiteFreq < CallerEntryFreq * ColdProb;
1757 const std::vector<Function *> &AllCallsCold) {
1762 for (
User *U :
F.users()) {
1763 if (isa<BlockAddress>(U))
1778 for (
User *U :
F->users()) {
1779 if (isa<BlockAddress>(U))
1794 if (
CallInst *CI = dyn_cast<CallInst>(&
I)) {
1796 if (CI->isInlineAsm())
1798 Function *CalledFn = CI->getCalledFunction();
1822 for (
User *U :
F->users()) {
1823 CallBase *CB = dyn_cast<CallBase>(U);
1825 assert(isa<BlockAddress>(U) &&
1826 "Expected either CallBase or BlockAddress");
1836 for (
User *U :
F->users())
1837 if (isa<InvokeInst>(U))
1845 auto *M =
F->getParent();
1851 for (
User *U : PreallocatedCalls) {
1852 CallBase *CB = dyn_cast<CallBase>(U);
1858 "Shouldn't call RemotePreallocated() on a musttail preallocated call");
1862 CallBase *PreallocatedSetup =
nullptr;
1863 for (
auto *It = OpBundles.
begin(); It != OpBundles.
end(); ++It) {
1864 if (It->getTag() ==
"preallocated") {
1865 PreallocatedSetup = cast<CallBase>(*It->input_begin());
1866 OpBundles.
erase(It);
1870 assert(PreallocatedSetup &&
"Did not find preallocated bundle");
1872 cast<ConstantInt>(PreallocatedSetup->
getArgOperand(0))->getZExtValue();
1874 assert((isa<CallInst>(CB) || isa<InvokeInst>(CB)) &&
1875 "Unknown indirect call type");
1895 for (
auto *
User : PreallocatedArgs) {
1896 auto *UseCall = cast<CallBase>(
User);
1897 assert(UseCall->getCalledFunction()->getIntrinsicID() ==
1898 Intrinsic::call_preallocated_arg &&
1899 "preallocated token use was not a llvm.call.preallocated.arg");
1901 cast<ConstantInt>(UseCall->getArgOperand(1))->getZExtValue();
1902 Value *AllocaReplacement = ArgAllocas[AllocArgIndex];
1903 if (!AllocaReplacement) {
1904 auto AddressSpace = UseCall->getType()->getPointerAddressSpace();
1906 UseCall->getFnAttr(Attribute::Preallocated).getValueAsType();
1911 ArgAllocas[AllocArgIndex] = Alloca;
1912 AllocaReplacement = Alloca;
1916 UseCall->eraseFromParent();
1919 cast<Instruction>(PreallocatedSetup)->eraseFromParent();
1933 bool Changed =
false;
1936 std::vector<Function *> AllCallsCold;
1939 AllCallsCold.push_back(&
F);
1945 if (
F.hasFnAttribute(Attribute::Naked))
1949 if (!
F.hasName() && !
F.isDeclaration() && !
F.hasLocalLinkage())
1952 if (
deleteIfDead(
F, NotDiscardableComdats, DeleteFnCallback)) {
1966 if (!
F.isDeclaration()) {
1969 ChangedCFGCallback(
F);
1975 if (!
F.hasLocalLinkage())
1983 if (
F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) &&
1991 if (
F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
2010 ChangeableCCCache.
erase(&
F);
2028 if (
F.getAttributes().hasAttrSomewhere(Attribute::Nest) &&
2029 !
F.hasAddressTaken()) {
2045 if (!
F || !
F->isIntrinsic() ||
F->getIntrinsicID() != Intrinsic::memcpy)
2052 auto *IsVolatile = dyn_cast<ConstantInt>(CI->
getArgOperand(3));
2055 if (!Alloca || !IsVolatile || IsVolatile->isOne())
2058 if (!Alloca->isStaticAlloca())
2061 if (!Alloca->getAllocatedType()->isArrayTy())
2068 unsigned NumBytesToPad,
2069 unsigned NumBytesToCopy) {
2081 std::vector<uint8_t> StrData(Data.begin(), Data.end());
2082 for (
unsigned int p = 0; p < NumBytesToPad; p++)
2083 StrData.push_back(
'\0');
2084 auto Arr =
ArrayRef(StrData.data(), NumBytesToCopy + NumBytesToPad);
2089 SourceReplace, SourceReplace->
getName());
2098 const unsigned NumBytesToCopy,
2104 unsigned int TotalBytes = NumBytesToCopy + NumBytesToPad;
2105 unsigned NumElementsToCopy =
divideCeil(TotalBytes, ElementByteWidth);
2109 Alloca->getAllocatedType()->getArrayElementType(), NumElementsToCopy));
2112 Alloca->replaceAllUsesWith(NewAlloca);
2113 Alloca->eraseFromParent();
2118 const unsigned NumBytesToPad,
2119 const unsigned NumBytesToCopy,
2130 auto *CI = dyn_cast<CallInst>(
User);
2134 if (CI->getArgOperand(1) != SourceVar)
2137 widenDestArray(CI, NumBytesToPad, NumBytesToCopy, SourceDataArray);
2139 CI->setArgOperand(2, ConstantInt::get(BytesToCopyOp->
getType(),
2140 NumBytesToCopy + NumBytesToPad));
2144 NumGlobalArraysPadded++;
2163 auto *BytesToCopyOp = dyn_cast<ConstantInt>(CI->
getArgOperand(2));
2169 if (!SourceDataArray)
2172 unsigned NumBytesToCopy = BytesToCopyOp->getZExtValue();
2175 uint64_t DZSize = Alloca->getAllocatedType()->getArrayNumElements();
2181 unsigned NumElementsToCopy =
divideCeil(NumBytesToCopy, ElementByteWidth);
2186 if (NumElementsToCopy != DZSize || DZSize != SZSize)
2189 unsigned NumBytesToPad = GetTTI(*F).getNumBytesToPadGlobalArray(
2190 NumBytesToCopy, SourceDataArray->
getType());
2191 if (NumBytesToPad) {
2193 BytesToCopyOp, SourceDataArray);
2205 bool Changed =
false;
2214 auto &
DL = M.getDataLayout();
2232 Changed |=
processGlobal(GV, GetTTI, GetTLI, LookupDomTree);
2242 if (
F->isDeclaration())
2251 ++NumCtorsEvaluated;
2256 <<
F->getName() <<
"' to " << NewInitializers.size()
2258 for (
const auto &Pair : NewInitializers)
2259 Pair.first->setInitializer(Pair.second);
2276 V.eraseFromParent();
2281 const Type *UsedArrayType = V.getValueType();
2282 const auto *VAT = cast<ArrayType>(UsedArrayType);
2283 const auto *VEPT = cast<PointerType>(VAT->getArrayElementType());
2287 PointerType::get(V.getContext(), VEPT->getAddressSpace());
2299 Module *M = V.getParent();
2300 V.removeFromParent();
2305 NV->setSection(
"llvm.metadata");
2325 CompilerUsed = {Vec.
begin(), Vec.
end()};
2331 iterator usedBegin() {
return Used.begin(); }
2332 iterator usedEnd() {
return Used.end(); }
2334 used_iterator_range used() {
2335 return used_iterator_range(usedBegin(), usedEnd());
2338 iterator compilerUsedBegin() {
return CompilerUsed.
begin(); }
2339 iterator compilerUsedEnd() {
return CompilerUsed.
end(); }
2341 used_iterator_range compilerUsed() {
2342 return used_iterator_range(compilerUsedBegin(), compilerUsedEnd());
2348 return CompilerUsed.
count(GV);
2356 return CompilerUsed.
insert(GV).second;
2359 void syncVariablesAndSets() {
2373 assert((!U.usedCount(&GA) || !U.compilerUsedCount(&GA)) &&
2374 "We should have removed the duplicated "
2375 "element from llvm.compiler.used");
2382 return !U.usedCount(&GA) && !U.compilerUsedCount(&GA);
2389 return U.usedCount(&GV) || U.compilerUsedCount(&GV);
2393 bool &RenameTarget) {
2397 RenameTarget =
false;
2418 RenameTarget =
true;
2425 bool Changed =
false;
2429 Used.compilerUsedErase(GV);
2440 if (!J.hasName() && !J.isDeclaration() && !J.hasLocalLinkage())
2449 if (!IsModuleLocal(J))
2452 Constant *Aliasee = J.getAliasee();
2463 Target->removeDeadConstantUsers();
2470 J.replaceAllUsesWith(Aliasee);
2471 ++NumAliasesResolved;
2477 Target->setLinkage(J.getLinkage());
2478 Target->setDSOLocal(J.isDSOLocal());
2479 Target->setVisibility(J.getVisibility());
2480 Target->setDLLStorageClass(J.getDLLStorageClass());
2482 if (Used.usedErase(&J))
2485 if (Used.compilerUsedErase(&J))
2486 Used.compilerUsedInsert(
Target);
2492 ++NumAliasesRemoved;
2496 Used.syncVariablesAndSets();
2506 auto FuncIter = M.begin();
2507 if (FuncIter == M.end())
2509 auto *TLI = &GetTLI(*FuncIter);
2511 if (!TLI->has(Func))
2514 Function *Fn = M.getFunction(TLI->getName(Func));
2523 if (!TLI->getLibFunc(*Fn,
F) ||
F != Func)
2540 if (
I.isDebugOrPseudoInst())
2542 if (isa<ReturnInst>(
I))
2564 bool Changed =
false;
2570 CallInst *CI = dyn_cast<CallInst>(U);
2584 ++NumCXXDtorsRemoved;
2595 if (IF.isInterposable())
2619 return dyn_cast<Function>(Ret->getReturnValue());
2625 bool Changed =
false;
2628 if (!IF.use_empty() &&
2629 (!Callee->isDeclaration() ||
2630 none_of(IF.users(), [](
User *U) { return isa<GlobalAlias>(U); }))) {
2631 IF.replaceAllUsesWith(Callee);
2632 NumIFuncsResolved++;
2641 bool Changed =
false;
2655 if (
auto *
F = dyn_cast<Function>(V)) {
2659 }
else if (
auto *Sel = dyn_cast<SelectInst>(V)) {
2664 }
else if (
auto *Phi = dyn_cast<PHINode>(V)) {
2665 for (
unsigned I = 0, E = Phi->getNumIncomingValues();
I != E; ++
I)
2694 bool Changed =
false;
2700 if (IF.isInterposable())
2715 if (
auto *Ret = dyn_cast_or_null<ReturnInst>(BB.
getTerminator()))
2722 assert(!Callees.
empty() &&
"Expecting successful collection of versions");
2729 auto [It, Inserted] = FeatureMask.
try_emplace(Callee);
2736 return FeatureMask[
LHS] > FeatureMask[
RHS];
2742 for (
User *U : IF.users()) {
2743 if (
auto *CB = dyn_cast<CallBase>(U)) {
2744 if (CB->getCalledOperand() == &IF) {
2745 Function *Caller = CB->getFunction();
2746 auto [FeatIt, FeatInserted] = FeatureMask.
try_emplace(Caller);
2749 auto [CallIt, CallInserted] = CallSites.
try_emplace(Caller);
2751 Callers.push_back(Caller);
2752 CallIt->second.push_back(CB);
2759 return FeatureMask[
LHS] > FeatureMask[
RHS];
2768 assert(
I < Callees.
size() &&
"Found callers of equal priority");
2771 uint64_t CallerBits = FeatureMask[Caller];
2772 uint64_t CalleeBits = FeatureMask[Callee];
2782 if (CallerBits == CalleeBits)
2784 else if (!implies(CallerBits, CalleeBits)) {
2787 while (implies(CalleeBits, CallerBits)) {
2788 if (++
I == Callees.
size())
2790 CalleeBits = FeatureMask[Callees[
I]];
2800 auto &Calls = CallSites[Caller];
2802 LLVM_DEBUG(
dbgs() <<
"Redirecting call " << Caller->getName() <<
" -> "
2803 << Callee->getName() <<
"\n");
2804 CS->setCalledOperand(Callee);
2808 if (IF.use_empty() ||
2809 all_of(IF.users(), [](
User *U) { return isa<GlobalAlias>(U); }))
2810 NumIFuncsResolved++;
2824 bool Changed =
false;
2825 bool LocalChange =
true;
2826 std::optional<uint32_t> FirstNotFullyEvaluatedPriority;
2828 while (LocalChange) {
2829 LocalChange =
false;
2831 NotDiscardableComdats.
clear();
2835 NotDiscardableComdats.
insert(
C);
2837 if (
const Comdat *
C =
F.getComdat())
2838 if (!
F.isDefTriviallyDead())
2839 NotDiscardableComdats.
insert(
C);
2841 if (
const Comdat *
C = GA.getComdat())
2842 if (!GA.isDiscardableIfUnused() || !GA.use_empty())
2843 NotDiscardableComdats.
insert(
C);
2847 NotDiscardableComdats, ChangedCFGCallback,
2853 if (FirstNotFullyEvaluatedPriority &&
2854 *FirstNotFullyEvaluatedPriority != Priority)
2858 FirstNotFullyEvaluatedPriority = Priority;
2864 NotDiscardableComdats);
2887 Changed |= LocalChange;
2897 auto &
DL = M.getDataLayout();
2919 ChangedCFGCallback, DeleteFnCallback))
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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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 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 tryWidenGlobalArrayAndDests(Function *F, GlobalVariable *SourceVar, const unsigned NumBytesToPad, const unsigned NumBytesToCopy, ConstantInt *BytesToCopyOp, ConstantDataArray *SourceDataArray)
static GlobalVariable * widenGlobalVariable(GlobalVariable *OldVar, Function *F, unsigned NumBytesToPad, unsigned NumBytesToCopy)
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...
Returns whether the given function is an empty C destructor or atexit handler and can therefore be eliminated Note that we assume that other optimization passes have already simplified the code so we simply check for static ret bool IsEmptyAtExitFunction(const Function &Fn)
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 tryWidenGlobalArraysUsedByMemcpy(GlobalVariable *GV, function_ref< TargetTransformInfo &(Function &)> GetTTI)
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 callInstIsMemcpy(CallInst *CI)
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 void widenDestArray(CallInst *CI, const unsigned NumBytesToPad, const unsigned NumBytesToCopy, ConstantDataArray *SourceDataArray)
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 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.
Find IFuncs that have resolvers that always point at the same statically known and replace their callers with a direct static call bool OptimizeStaticIFuncs(Module &M)
static bool isLeakCheckerRoot(GlobalVariable *GV)
Is this global variable possibly used by a leak checker as a root? If so, we might not really want to...
static bool forwardStoredOnceStore(GlobalVariable *GV, const StoreInst *StoredOnceStore, function_ref< DominatorTree &(Function &)> LookupDomTree)
static int compareNames(Constant *const *A, Constant *const *B)
static bool collectVersions(TargetTransformInfo &TTI, Value *V, SmallVectorImpl< Function * > &Versions)
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 destArrayCanBeWidened(CallInst *CI)
static bool hasUseOtherThanLLVMUsed(GlobalAlias &GA, const LLVMUsed &U)
Module.h This file contains the declarations for the Module class.
This defines the Use class.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
Remove Loads Into Fake Uses
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
static SymbolRef::Type getType(const Symbol *Sym)
Class for arbitrary precision integers.
This class represents a conversion between pointers from one address space to another.
an instruction to allocate memory on the stack
void setAlignment(Align Align)
A container for analyses that lazily runs them and caches their results.
void clear(IRUnitT &IR, llvm::StringRef Name)
Clear any cached analysis results for a single unit of IR.
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
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),...
uint64_t getNumElements() const
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 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...
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...
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...
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 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.
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
Predicate getPredicate() const
Return the predicate for this instruction.
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
An array constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
ArrayType * getType() const
Specialize the getType() method to always return an ArrayType, which reduces the amount of casting ne...
uint64_t getElementByteSize() const
Return the size (in bytes) of each element in the array/vector.
StringRef getRawDataValues() const
Return the raw, underlying, bytes of this data.
A constant value that is initialized with an expression using other constant values.
static Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static 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.
This is the shared class of boolean and integer constants.
static ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getFalse(LLVMContext &Context)
static ConstantInt * getBool(LLVMContext &Context, bool V)
This is an important base class in LLVM.
const Constant * stripPointerCasts() const
void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
bool extractIfOffset(int64_t &Offset) const
If this is a constant offset, extract it.
static 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 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.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
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)
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
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...
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
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
bool isImplicitDSOLocal() const
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
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...
void eraseFromParent()
This method unlinks 'this' from the containing module and deletes it.
PointerType * getType() const
Global values are always pointers.
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.
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
bool isExternallyInitialized() const
bool hasInitializer() const
Definitions have initializers, declarations don't.
void setConstant(bool Val)
void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
void getDebugInfo(SmallVectorImpl< DIGlobalVariableExpression * > &GVs) const
Fill the vector with all debug info attachements.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
void addDebugInfo(DIGlobalVariableExpression *GV)
Attach a DIGlobalVariableExpression.
This instruction compares its operands according to the predicate given to the constructor.
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
CallInst * CreateStackSave(const Twine &Name="")
Create a call to llvm.stacksave.
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
CallInst * CreateStackRestore(Value *Ptr, const Twine &Name="")
Create a call to llvm.stackrestore.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
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',...
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.
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.
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 preserveSet()
Mark an analysis set as preserved.
void 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, Instruction *MDFrom=nullptr)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
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()
StringRef - Represent a constant reference to a string, i.e.
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.
static IntegerType * getInt1Ty(LLVMContext &C)
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.
bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
TypeID getTypeID() const
Return the type id for the type.
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.
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.
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
bool hasOneUse() const
Return true if there is exactly one use 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.
user_iterator_impl< User > user_iterator
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
This class represents zero extension of integer types.
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.
A range adaptor for a pair of iterators.
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.
@ 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.
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.
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.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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...
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
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 getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
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.
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)
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 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.
Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Constant * ConstantFoldInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstruction - Try to constant fold the specified instruction.
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...
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.
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
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::...