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(NumInternalFunc,
"Number of internal functions");
91STATISTIC(NumColdCC,
"Number of functions marked coldcc");
92STATISTIC(NumIFuncsResolved,
"Number of statically resolved IFuncs");
93STATISTIC(NumIFuncsDeleted,
"Number of IFuncs removed");
97 cl::desc(
"Enable stress test of coldcc by adding "
98 "calling conv to all internal functions."),
104 "Maximum block frequency, expressed as a percentage of caller's "
105 "entry frequency, for a call site to be considered cold for enabling"
127 Type *Ty = Types.pop_back_val();
134 if (cast<VectorType>(Ty)->getElementType()->
isPointerTy())
138 Types.push_back(cast<ArrayType>(Ty)->getElementType());
144 if (isa<PointerType>(InnerTy))
return true;
145 if (isa<StructType>(InnerTy) || isa<ArrayType>(InnerTy) ||
146 isa<VectorType>(InnerTy))
147 Types.push_back(InnerTy);
152 if (--Limit == 0)
return true;
153 }
while (!Types.empty());
163 if (isa<Constant>(V))
167 if (isa<LoadInst>(V) || isa<InvokeInst>(V) || isa<Argument>(V) ||
174 if (
I->mayHaveSideEffects())
177 if (!
GEP->hasAllConstantIndices())
179 }
else if (
I->getNumOperands() != 1) {
183 V =
I->getOperand(0);
202 bool Changed =
false;
210 while (!Worklist.
empty()) {
212 if (
StoreInst *SI = dyn_cast<StoreInst>(U)) {
213 Value *V = SI->getValueOperand();
214 if (isa<Constant>(V)) {
216 SI->eraseFromParent();
219 Dead.push_back(std::make_pair(
I, SI));
221 }
else if (
MemSetInst *MSI = dyn_cast<MemSetInst>(U)) {
222 if (isa<Constant>(MSI->getValue())) {
224 MSI->eraseFromParent();
225 }
else if (
Instruction *
I = dyn_cast<Instruction>(MSI->getValue())) {
227 Dead.push_back(std::make_pair(
I, MSI));
230 GlobalVariable *MemSrc = dyn_cast<GlobalVariable>(MTI->getSource());
233 MTI->eraseFromParent();
234 }
else if (
Instruction *
I = dyn_cast<Instruction>(MTI->getSource())) {
236 Dead.push_back(std::make_pair(
I, MTI));
238 }
else if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
239 if (isa<GEPOperator>(CE))
244 for (
int i = 0, e = Dead.size(); i != e; ++i) {
246 Dead[i].second->eraseFromParent();
251 Instruction *J = dyn_cast<Instruction>(
I->getOperand(0));
254 I->eraseFromParent();
257 I->eraseFromParent();
274 bool Changed =
false;
279 if (
auto *OpI = dyn_cast<Instruction>(
Op))
281 I->eraseFromParent();
284 while (!WorkList.
empty()) {
286 if (!Visited.
insert(U).second)
289 if (
auto *BO = dyn_cast<BitCastOperator>(U))
291 if (
auto *ASC = dyn_cast<AddrSpaceCastOperator>(U))
293 else if (
auto *
GEP = dyn_cast<GEPOperator>(U))
295 else if (
auto *LI = dyn_cast<LoadInst>(U)) {
298 Type *Ty = LI->getType();
300 LI->replaceAllUsesWith(Res);
305 Value *PtrOp = LI->getPointerOperand();
315 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(U)) {
345 auto AppendUses = [&](
Value *V) {
346 for (
Use &U : V->uses())
347 if (Visited.
insert(&U).second)
351 while (!Worklist.
empty()) {
353 User *V = U->getUser();
355 auto *
GEP = dyn_cast<GEPOperator>(V);
356 if (isa<BitCastOperator>(V) || isa<AddrSpaceCastOperator>(V) ||
357 (
GEP &&
GEP->hasAllConstantIndices())) {
365 if (isa<StoreInst>(V) && U->getOperandNo() == 0)
371 if (
Ptr != GV ||
Offset.getActiveBits() >= 64)
377 const auto &[It, Inserted] =
379 if (Ty != It->second.Ty)
383 It->second.Initializer =
385 if (!It->second.Initializer) {
386 LLVM_DEBUG(
dbgs() <<
"Global SRA: Failed to evaluate initializer of "
387 << *GV <<
" with type " << *Ty <<
" at offset "
388 <<
Offset.getZExtValue());
398 auto *SI = dyn_cast<StoreInst>(V);
402 Constant *StoredConst = dyn_cast<Constant>(SI->getOperand(0));
407 return Initializer != StoredConst;
410 It->second.IsLoaded |= isa<LoadInst>(V);
411 It->second.IsStored |= IsStored(V, It->second.Initializer);
416 if (
auto *
C = dyn_cast<Constant>(V)) {
436 for (
auto *GVE : GVs) {
439 int64_t CurVarOffsetInBytes = 0;
441 uint64_t FragmentEndInBits = FragmentOffsetInBits + FragmentSizeInBits;
448 if (CurVarOffsetInBytes < 0)
452 CurVarOffsetInBits = CHAR_BIT * (
uint64_t)CurVarOffsetInBytes;
455 if (CurVarOffsetInBits >= FragmentEndInBits)
459 uint64_t CurVarEndInBits = CurVarOffsetInBits + CurVarSize;
461 if (CurVarSize != 0 &&
462 CurVarEndInBits <= FragmentOffsetInBits)
467 if (CurVarSize != 0 &&
468 CurVarOffsetInBits >= FragmentOffsetInBits &&
469 CurVarEndInBits <= FragmentEndInBits) {
471 (CurVarOffsetInBits - FragmentOffsetInBits) / 8;
472 if (CurVarOffsetInFragment != 0)
473 Expr = DIExpression::get(Expr->
getContext(), {dwarf::DW_OP_plus_uconst,
474 CurVarOffsetInFragment});
476 Expr = DIExpression::get(Expr->
getContext(), {});
478 DIGlobalVariableExpression::get(GVE->getContext(), Var, Expr);
484 if (FragmentSizeInBits < VarSize) {
485 if (CurVarOffsetInBits > FragmentOffsetInBits)
487 uint64_t CurVarFragmentOffsetInBits =
488 FragmentOffsetInBits - CurVarOffsetInBits;
489 uint64_t CurVarFragmentSizeInBits = FragmentSizeInBits;
490 if (CurVarSize != 0 && CurVarEndInBits < FragmentEndInBits)
491 CurVarFragmentSizeInBits -= (FragmentEndInBits - CurVarEndInBits);
492 if (CurVarOffsetInBits)
493 Expr = DIExpression::get(Expr->
getContext(), {});
495 Expr, CurVarFragmentOffsetInBits, CurVarFragmentSizeInBits))
500 auto *NGVE = DIGlobalVariableExpression::get(GVE->getContext(), Var, Expr);
525 unsigned NumParts =
count_if(Parts, [](
const auto &Pair) {
526 return Pair.second.IsLoaded && Pair.second.IsStored;
533 for (
const auto &Pair : Parts) {
535 {Pair.first, Pair.second.Ty, Pair.second.Initializer});
541 for (
const auto &[OffsetForTy, Ty,
_] : TypesVector) {
546 Offset = OffsetForTy +
DL.getTypeAllocSize(Ty);
553 LLVM_DEBUG(
dbgs() <<
"PERFORMING GLOBAL SRA ON: " << *GV <<
"\n");
556 Align StartAlignment =
562 unsigned NameSuffix = 0;
563 for (
auto &[OffsetForTy, Ty, Initializer] : TypesVector) {
565 *GV->
getParent(), Ty,
false, GlobalVariable::InternalLinkage,
566 Initializer, GV->
getName() +
"." +
Twine(NameSuffix++), GV,
569 NewGlobals.
insert({OffsetForTy, NGV});
575 if (NewAlign >
DL.getABITypeAlign(Ty))
580 DL.getTypeAllocSizeInBits(Ty), VarSize);
587 auto AppendUsers = [&](
Value *V) {
588 for (
User *U : V->users())
589 if (Visited.
insert(U).second)
593 while (!Worklist.
empty()) {
595 if (isa<BitCastOperator>(V) || isa<AddrSpaceCastOperator>(V) ||
596 isa<GEPOperator>(V)) {
598 if (isa<Instruction>(V))
607 assert(
Ptr == GV &&
"Load/store must be from/to global");
609 assert(NGV &&
"Must have replacement global for this offset");
616 if (
auto *LI = dyn_cast<LoadInst>(V)) {
617 LI->setOperand(0, NGV);
618 LI->setAlignment(NewAlign);
620 auto *SI = cast<StoreInst>(V);
621 SI->setOperand(1, NGV);
622 SI->setAlignment(NewAlign);
628 "Other users can only be dead constants");
638 return NewGlobals.
begin()->second;
646 for (
const User *U : V->users()) {
653 if (isa<LoadInst>(U)) {
655 }
else if (
const StoreInst *SI = dyn_cast<StoreInst>(U)) {
656 if (SI->getOperand(0) == V) {
659 }
else if (
const CallInst *CI = dyn_cast<CallInst>(U)) {
660 if (CI->getCalledOperand() != V) {
663 }
else if (
const InvokeInst *II = dyn_cast<InvokeInst>(U)) {
664 if (II->getCalledOperand() != V) {
672 }
else if (
const PHINode *PN = dyn_cast<PHINode>(U)) {
677 }
else if (isa<ICmpInst>(U) &&
678 !ICmpInst::isSigned(cast<ICmpInst>(U)->getPredicate()) &&
679 isa<LoadInst>(U->getOperand(0)) &&
680 isa<ConstantPointerNull>(U->getOperand(1))) {
681 assert(isa<GlobalValue>(cast<LoadInst>(U->getOperand(0))
682 ->getPointerOperand()
683 ->stripPointerCasts()) &&
684 "Should be GlobalVariable");
701 while (!Worklist.
empty()) {
703 for (
const auto *U :
P->users()) {
704 if (
auto *LI = dyn_cast<LoadInst>(U)) {
708 }
else if (
auto *SI = dyn_cast<StoreInst>(U)) {
710 if (SI->getPointerOperand() !=
P)
712 }
else if (
auto *CE = dyn_cast<ConstantExpr>(U)) {
713 if (CE->stripPointerCasts() != GV)
732 while (!Worklist.
empty()) {
734 for (
auto *U :
P->users()) {
735 if (
auto *CE = dyn_cast<ConstantExpr>(U)) {
740 assert((isa<LoadInst>(U) || isa<StoreInst>(U)) &&
741 "Expect only load or store instructions");
748 bool Changed =
false;
749 for (
auto UI = V->user_begin(), E = V->user_end(); UI != E; ) {
755 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
756 LI->setOperand(0, NewV);
758 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(
I)) {
759 if (SI->getOperand(1) == V) {
760 SI->setOperand(1, NewV);
763 }
else if (isa<CallInst>(
I) || isa<InvokeInst>(
I)) {
770 bool PassedAsArg =
false;
771 for (
unsigned i = 0, e = CB->
arg_size(); i != e; ++i)
779 UI = V->user_begin();
785 if (CI->use_empty()) {
787 CI->eraseFromParent();
792 Idxs.
reserve(GEPI->getNumOperands()-1);
795 if (
Constant *
C = dyn_cast<Constant>(*i))
799 if (Idxs.
size() == GEPI->getNumOperands()-1)
803 if (GEPI->use_empty()) {
805 GEPI->eraseFromParent();
820 bool Changed =
false;
824 bool AllNonStoreUsesGone =
true;
828 if (
LoadInst *LI = dyn_cast<LoadInst>(GlobalUser)) {
831 if (LI->use_empty()) {
832 LI->eraseFromParent();
835 AllNonStoreUsesGone =
false;
837 }
else if (isa<StoreInst>(GlobalUser)) {
839 assert(GlobalUser->getOperand(1) == GV &&
840 "Must be storing *to* the global");
842 AllNonStoreUsesGone =
false;
846 assert((isa<PHINode>(GlobalUser) || isa<SelectInst>(GlobalUser) ||
847 isa<ConstantExpr>(GlobalUser) || isa<CmpInst>(GlobalUser) ||
848 isa<BitCastInst>(GlobalUser) ||
849 isa<GetElementPtrInst>(GlobalUser) ||
850 isa<AddrSpaceCastInst>(GlobalUser)) &&
851 "Only expect load and stores!");
856 LLVM_DEBUG(
dbgs() <<
"OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV
863 if (AllNonStoreUsesGone) {
887 I->replaceAllUsesWith(NewC);
891 while (UI != E && *UI ==
I)
894 I->eraseFromParent();
908 LLVM_DEBUG(
errs() <<
"PROMOTING GLOBAL: " << *GV <<
" CALL = " << *CI
927 if (!isa<UndefValue>(InitVal)) {
930 Builder.
CreateMemSet(NewGV, InitVal, AllocSize, std::nullopt);
943 bool InitBoolUsed =
false;
948 for (
auto *U : Guses) {
949 if (
StoreInst *SI = dyn_cast<StoreInst>(U)) {
954 !isa<ConstantPointerNull>(SI->getValueOperand())),
955 InitBool,
false,
Align(1), SI->getOrdering(),
956 SI->getSyncScopeID(), SI->getIterator());
957 SI->eraseFromParent();
978 case ICmpInst::ICMP_ULT:
981 case ICmpInst::ICMP_UGE:
984 case ICmpInst::ICMP_ULE:
985 case ICmpInst::ICMP_EQ:
988 case ICmpInst::ICMP_NE:
989 case ICmpInst::ICMP_UGT:
1001 cast<StoreInst>(InitBool->
user_back())->eraseFromParent();
1028 while (!Worklist.
empty()) {
1030 if (!Visited.
insert(V).second)
1033 for (
const Use &VUse : V->uses()) {
1034 const User *U = VUse.getUser();
1035 if (isa<LoadInst>(U) || isa<CmpInst>(U))
1038 if (
auto *SI = dyn_cast<StoreInst>(U)) {
1039 if (SI->getValueOperand() == V &&
1040 SI->getPointerOperand()->stripPointerCasts() != GV)
1045 if (
auto *BCI = dyn_cast<BitCastInst>(U)) {
1050 if (
auto *GEPI = dyn_cast<GetElementPtrInst>(U)) {
1087 if (AllocSize >= 2048)
1129 if (
Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) {
1134 if (
auto *CI = dyn_cast<CallInst>(StoredOnceVal)) {
1135 auto *TLI = &GetTLI(*CI->getFunction());
1165 if (!isa<LoadInst>(U) && !isa<StoreInst>(U))
1186 "No reason to shrink to bool!");
1193 bool IsOneZero =
false;
1194 bool EmitOneOrZero =
true;
1195 auto *CI = dyn_cast<ConstantInt>(OtherVal);
1196 if (CI && CI->getValue().getActiveBits() <= 64) {
1197 IsOneZero = InitVal->
isNullValue() && CI->isOne();
1200 if (CIInit && CIInit->getValue().getActiveBits() <= 64) {
1201 uint64_t ValInit = CIInit->getZExtValue();
1202 uint64_t ValOther = CI->getZExtValue();
1203 uint64_t ValMinus = ValOther - ValInit;
1205 for(
auto *GVe : GVs){
1209 unsigned SizeInOctets =
1221 dwarf::DW_OP_deref_size, SizeInOctets,
1222 dwarf::DW_OP_constu, ValMinus,
1223 dwarf::DW_OP_mul, dwarf::DW_OP_constu, ValInit,
1225 bool WithStackValue =
true;
1228 DIGlobalVariableExpression::get(NewGV->
getContext(), DGV, E);
1231 EmitOneOrZero =
false;
1235 if (EmitOneOrZero) {
1244 if (
StoreInst *SI = dyn_cast<StoreInst>(UI)) {
1246 bool StoringOther = SI->getOperand(0) == OtherVal;
1249 if (StoringOther || SI->getOperand(0) == InitVal) {
1256 Instruction *StoredVal = cast<Instruction>(SI->getOperand(0));
1261 if (
LoadInst *LI = dyn_cast<LoadInst>(StoredVal)) {
1262 assert(LI->getOperand(0) == GV &&
"Not a copy!");
1266 false,
Align(1), LI->getOrdering(),
1267 LI->getSyncScopeID(), LI->getIterator());
1269 assert((isa<CastInst>(StoredVal) || isa<SelectInst>(StoredVal)) &&
1270 "This is not a form that we understand!");
1272 assert(isa<LoadInst>(StoreVal) &&
"Not a load of NewGV!");
1276 new StoreInst(StoreVal, NewGV,
false,
Align(1), SI->getOrdering(),
1277 SI->getSyncScopeID(), SI->getIterator());
1321 if (
auto *
F = dyn_cast<Function>(&GV))
1322 Dead = (
F->isDeclaration() &&
F->use_empty()) ||
F->isDefTriviallyDead();
1329 if (
auto *
F = dyn_cast<Function>(&GV)) {
1330 if (DeleteFnCallback)
1331 DeleteFnCallback(*
F);
1354 for (
auto *U : GV->
users()) {
1358 assert(
I->getParent()->getParent() ==
F);
1360 if (
auto *LI = dyn_cast<LoadInst>(
I))
1362 else if (
auto *SI = dyn_cast<StoreInst>(
I))
1372 auto &DT = LookupDomTree(*
const_cast<Function *
>(
F));
1383 const unsigned Threshold = 100;
1384 if (Loads.
size() * Stores.
size() > Threshold)
1387 for (
auto *L : Loads) {
1388 auto *LTy = L->getType();
1394 return DT.dominates(S, L) &&
1395 DL.getTypeStoreSize(LTy).getFixedValue() <=
1396 DL.getTypeStoreSize(STy).getFixedValue();
1414 if (!isa<Constant>(StoredOnceValue))
1419 if (
auto *LI = dyn_cast<LoadInst>(U)) {
1420 if (LI->getFunction() ==
F &&
1421 LI->getType() == StoredOnceValue->
getType() && LI->isSimple())
1426 bool MadeChange =
false;
1427 if (!Loads.
empty()) {
1428 auto &DT = LookupDomTree(*
const_cast<Function *
>(
F));
1429 for (
auto *LI : Loads) {
1430 if (DT.dominates(StoredOnceStore, LI)) {
1431 LI->replaceAllUsesWith(
const_cast<Value *
>(StoredOnceValue));
1432 LI->eraseFromParent();
1456 if (!GS.HasMultipleAccessingFunctions &&
1457 GS.AccessingFunction &&
1461 GS.AccessingFunction->doesNotRecurse() &&
1468 GS.AccessingFunction->getEntryBlock().begin().getNonConst();
1472 nullptr, GV->
getName(), FirstI);
1482 bool Changed =
false;
1513 if (GS.Ordering == AtomicOrdering::NotAtomic) {
1524 LLVM_DEBUG(
dbgs() <<
" *** Marking constant allowed us to simplify "
1525 <<
"all users and delete global!\n");
1539 Value *StoredOnceValue = GS.getStoredOnceValue();
1542 const_cast<Function &
>(*GS.StoredOnceStore->getFunction());
1543 bool CanHaveNonUndefGlobalInitializer =
1544 GetTTI(StoreFn).canHaveNonUndefGlobalInitializerInAddressSpace(
1553 auto *SOVConstant = dyn_cast<Constant>(StoredOnceValue);
1555 DL.getTypeAllocSize(SOVConstant->getType()) ==
1557 CanHaveNonUndefGlobalInitializer) {
1568 NGV->copyAttributesFrom(GV);
1578 LLVM_DEBUG(
dbgs() <<
" *** Substituting initializer allowed us to "
1579 <<
"simplify all users and delete global!\n");
1594 if (GS.NumStores == 1)
1600 if (SOVConstant && GS.Ordering == AtomicOrdering::NotAtomic &&
1602 CanHaveNonUndefGlobalInitializer)) {
1628 bool Changed =
false;
1630 auto NewUnnamedAddr = GV.
hasLocalLinkage() ? GlobalValue::UnnamedAddr::Global
1631 : GlobalValue::UnnamedAddr::Local;
1643 auto *GVar = dyn_cast<GlobalVariable>(&GV);
1647 if (GVar->isConstant() || !GVar->hasInitializer())
1657 for (
User *U :
F->users()) {
1658 if (isa<BlockAddress>(U))
1667 if (Attrs.hasAttrSomewhere(
A, &AttrIndex))
1668 return Attrs.removeAttributeAtIndex(
C, AttrIndex,
A);
1673 F->setAttributes(
StripAttr(
F->getContext(),
F->getAttributes(),
A));
1674 for (
User *U :
F->users()) {
1675 if (isa<BlockAddress>(U))
1700 for (
User *U :
F->users()) {
1701 if (isa<BlockAddress>(U))
1703 CallInst* CI = dyn_cast<CallInst>(U);
1712 if (BB.getTerminatingMustTailCall())
1715 return !
F->hasAddressTaken();
1724 return Res.first->second;
1732 auto CallSiteFreq = CallerBFI.
getBlockFreq(CallSiteBB);
1733 auto CallerEntryFreq =
1735 return CallSiteFreq < CallerEntryFreq * ColdProb;
1745 const std::vector<Function *> &AllCallsCold) {
1750 for (
User *U :
F.users()) {
1751 if (isa<BlockAddress>(U))
1766 for (
User *U :
F->users()) {
1767 if (isa<BlockAddress>(U))
1782 if (
CallInst *CI = dyn_cast<CallInst>(&
I)) {
1784 if (CI->isInlineAsm())
1786 Function *CalledFn = CI->getCalledFunction();
1810 for (
User *U :
F->users()) {
1811 CallBase *CB = dyn_cast<CallBase>(U);
1813 assert(isa<BlockAddress>(U) &&
1814 "Expected either CallBase or BlockAddress");
1824 for (
User *U :
F->users())
1825 if (isa<InvokeInst>(U))
1833 auto *M =
F->getParent();
1839 for (
User *U : PreallocatedCalls) {
1840 CallBase *CB = dyn_cast<CallBase>(U);
1846 "Shouldn't call RemotePreallocated() on a musttail preallocated call");
1850 CallBase *PreallocatedSetup =
nullptr;
1851 for (
auto *It = OpBundles.
begin(); It != OpBundles.
end(); ++It) {
1852 if (It->getTag() ==
"preallocated") {
1853 PreallocatedSetup = cast<CallBase>(*It->input_begin());
1854 OpBundles.
erase(It);
1858 assert(PreallocatedSetup &&
"Did not find preallocated bundle");
1860 cast<ConstantInt>(PreallocatedSetup->
getArgOperand(0))->getZExtValue();
1862 assert((isa<CallInst>(CB) || isa<InvokeInst>(CB)) &&
1863 "Unknown indirect call type");
1883 for (
auto *
User : PreallocatedArgs) {
1884 auto *UseCall = cast<CallBase>(
User);
1885 assert(UseCall->getCalledFunction()->getIntrinsicID() ==
1886 Intrinsic::call_preallocated_arg &&
1887 "preallocated token use was not a llvm.call.preallocated.arg");
1889 cast<ConstantInt>(UseCall->getArgOperand(1))->getZExtValue();
1890 Value *AllocaReplacement = ArgAllocas[AllocArgIndex];
1891 if (!AllocaReplacement) {
1892 auto AddressSpace = UseCall->getType()->getPointerAddressSpace();
1894 UseCall->getFnAttr(Attribute::Preallocated).getValueAsType();
1899 ArgAllocas[AllocArgIndex] = Alloca;
1900 AllocaReplacement = Alloca;
1904 UseCall->eraseFromParent();
1907 cast<Instruction>(PreallocatedSetup)->eraseFromParent();
1921 bool Changed =
false;
1924 std::vector<Function *> AllCallsCold;
1927 AllCallsCold.push_back(&
F);
1933 if (
F.hasFnAttribute(Attribute::Naked))
1937 if (!
F.hasName() && !
F.isDeclaration() && !
F.hasLocalLinkage())
1940 if (
deleteIfDead(
F, NotDiscardableComdats, DeleteFnCallback)) {
1954 if (!
F.isDeclaration()) {
1957 ChangedCFGCallback(
F);
1963 if (!
F.hasLocalLinkage())
1971 if (
F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) &&
1979 if (
F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
1998 ChangeableCCCache.
erase(&
F);
2016 if (
F.getAttributes().hasAttrSomewhere(Attribute::Nest) &&
2017 !
F.hasAddressTaken()) {
2034 bool Changed =
false;
2041 if (GV.hasInitializer())
2042 if (
auto *
C = dyn_cast<Constant>(GV.getInitializer())) {
2043 auto &
DL = M.getDataLayout();
2049 GV.setInitializer(New);
2057 Changed |=
processGlobal(GV, GetTTI, GetTLI, LookupDomTree);
2067 if (
F->isDeclaration())
2076 ++NumCtorsEvaluated;
2081 <<
F->getName() <<
"' to " << NewInitializers.size()
2083 for (
const auto &Pair : NewInitializers)
2084 Pair.first->setInitializer(Pair.second);
2086 GV->setConstant(
true);
2101 V.eraseFromParent();
2106 const Type *UsedArrayType = V.getValueType();
2107 const auto *VAT = cast<ArrayType>(UsedArrayType);
2108 const auto *VEPT = cast<PointerType>(VAT->getArrayElementType());
2112 PointerType::get(V.getContext(), VEPT->getAddressSpace());
2124 Module *M = V.getParent();
2125 V.removeFromParent();
2130 NV->setSection(
"llvm.metadata");
2150 CompilerUsed = {Vec.
begin(), Vec.
end()};
2156 iterator usedBegin() {
return Used.begin(); }
2157 iterator usedEnd() {
return Used.end(); }
2159 used_iterator_range used() {
2160 return used_iterator_range(usedBegin(), usedEnd());
2163 iterator compilerUsedBegin() {
return CompilerUsed.
begin(); }
2164 iterator compilerUsedEnd() {
return CompilerUsed.
end(); }
2166 used_iterator_range compilerUsed() {
2167 return used_iterator_range(compilerUsedBegin(), compilerUsedEnd());
2173 return CompilerUsed.
count(GV);
2181 return CompilerUsed.
insert(GV).second;
2184 void syncVariablesAndSets() {
2198 assert((!U.usedCount(&GA) || !U.compilerUsedCount(&GA)) &&
2199 "We should have removed the duplicated "
2200 "element from llvm.compiler.used");
2207 return !U.usedCount(&GA) && !U.compilerUsedCount(&GA);
2214 return U.usedCount(&GV) || U.compilerUsedCount(&GV);
2218 bool &RenameTarget) {
2219 RenameTarget =
false;
2240 RenameTarget =
true;
2247 bool Changed =
false;
2251 Used.compilerUsedErase(GV);
2262 if (!J.hasName() && !J.isDeclaration() && !J.hasLocalLinkage())
2271 if (!IsModuleLocal(J))
2274 Constant *Aliasee = J.getAliasee();
2285 Target->removeDeadConstantUsers();
2292 J.replaceAllUsesWith(Aliasee);
2293 ++NumAliasesResolved;
2299 Target->setLinkage(J.getLinkage());
2300 Target->setDSOLocal(J.isDSOLocal());
2301 Target->setVisibility(J.getVisibility());
2302 Target->setDLLStorageClass(J.getDLLStorageClass());
2304 if (Used.usedErase(&J))
2307 if (Used.compilerUsedErase(&J))
2308 Used.compilerUsedInsert(
Target);
2314 ++NumAliasesRemoved;
2318 Used.syncVariablesAndSets();
2326 auto FuncIter = M.begin();
2327 if (FuncIter == M.end())
2329 auto *TLI = &GetTLI(*FuncIter);
2335 Function *Fn = M.getFunction(TLI->getName(
F));
2343 if (!TLI->getLibFunc(*Fn,
F) ||
F != LibFunc_cxa_atexit)
2360 if (
I.isDebugOrPseudoInst())
2362 if (isa<ReturnInst>(
I))
2384 bool Changed =
false;
2390 CallInst *CI = dyn_cast<CallInst>(U);
2403 ++NumCXXDtorsRemoved;
2412 if (IF.isInterposable())
2436 return dyn_cast<Function>(Ret->getReturnValue());
2442 bool Changed =
false;
2445 if (!IF.use_empty()) {
2446 IF.replaceAllUsesWith(Callee);
2447 NumIFuncsResolved++;
2456 bool Changed =
false;
2474 bool Changed =
false;
2475 bool LocalChange =
true;
2476 std::optional<uint32_t> FirstNotFullyEvaluatedPriority;
2478 while (LocalChange) {
2479 LocalChange =
false;
2481 NotDiscardableComdats.
clear();
2485 NotDiscardableComdats.
insert(
C);
2487 if (
const Comdat *
C =
F.getComdat())
2488 if (!
F.isDefTriviallyDead())
2489 NotDiscardableComdats.
insert(
C);
2491 if (
const Comdat *
C = GA.getComdat())
2492 if (!GA.isDiscardableIfUnused() || !GA.use_empty())
2493 NotDiscardableComdats.
insert(
C);
2497 NotDiscardableComdats, ChangedCFGCallback,
2503 if (FirstNotFullyEvaluatedPriority &&
2504 *FirstNotFullyEvaluatedPriority != Priority)
2508 FirstNotFullyEvaluatedPriority = Priority;
2514 NotDiscardableComdats);
2531 Changed |= LocalChange;
2541 auto &
DL = M.getDataLayout();
2563 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.
Rewrite Partial Register Uses
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 * FindCXAAtExit(Module &M, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
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 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.
Returns whether the given function is an empty C destructor 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 cxxDtorIsEmpty(const Function &Fn)
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 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 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 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 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 OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn)
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 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 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 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.
FunctionAnalysisManager FAM
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)
This defines the Use class.
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
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.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
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, BasicBlock::iterator InsertBefore)
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.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
static CallBase * Create(CallBase *CB, ArrayRef< OperandBundleDef > Bundles, BasicBlock::iterator InsertPt)
Create a clone of CB with a different set of operand bundles and insert it before InsertPt.
Value * getCalledOperand() const
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
void setCalledOperand(Value *V)
unsigned arg_size() const
AttributeList getAttributes() const
Return the parameter 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)
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 * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static Constant * getAddrSpaceCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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.
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.
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 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
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.
const BasicBlock * getParent() const
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.
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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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, BasicBlock::iterator InsertBefore, Instruction *MDFrom=nullptr)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
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.
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.
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.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
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.
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.
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 and pointer casts from the specified value,...
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.
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.
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.
Type * getLoadStoreType(Value *I)
A helper function that returns the type of a load or store instruction.
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, 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::...