77#define DEBUG_TYPE "globalopt"
79STATISTIC(NumMarked ,
"Number of globals marked constant");
80STATISTIC(NumUnnamed ,
"Number of globals marked unnamed_addr");
81STATISTIC(NumSRA ,
"Number of aggregate globals broken into scalars");
82STATISTIC(NumSubstitute,
"Number of globals with initializers stored into them");
84STATISTIC(NumGlobUses ,
"Number of global uses devirtualized");
85STATISTIC(NumLocalized ,
"Number of globals localized");
86STATISTIC(NumShrunkToBool ,
"Number of global vars shrunk to booleans");
87STATISTIC(NumFastCallFns ,
"Number of functions converted to fastcc");
88STATISTIC(NumCtorsEvaluated,
"Number of static ctors evaluated");
89STATISTIC(NumNestRemoved ,
"Number of nest attributes removed");
90STATISTIC(NumAliasesResolved,
"Number of global aliases resolved");
91STATISTIC(NumAliasesRemoved,
"Number of global aliases eliminated");
92STATISTIC(NumCXXDtorsRemoved,
"Number of global C++ destructors removed");
93STATISTIC(NumInternalFunc,
"Number of internal functions");
94STATISTIC(NumColdCC,
"Number of functions marked coldcc");
98 cl::desc(
"Enable stress test of coldcc by adding "
99 "calling conv to all internal functions."),
105 "Maximum block frequency, expressed as a percentage of caller's "
106 "entry frequency, for a call site to be considered cold for enabling"
128 Type *Ty = Types.pop_back_val();
135 if (cast<VectorType>(Ty)->getElementType()->isPointerTy())
139 Types.push_back(cast<ArrayType>(Ty)->getElementType());
145 if (isa<PointerType>(InnerTy))
return true;
146 if (isa<StructType>(InnerTy) || isa<ArrayType>(InnerTy) ||
147 isa<VectorType>(InnerTy))
148 Types.push_back(InnerTy);
153 if (--Limit == 0)
return true;
154 }
while (!Types.empty());
164 if (isa<Constant>(V))
168 if (isa<LoadInst>(V) || isa<InvokeInst>(V) || isa<Argument>(V) ||
175 if (
I->mayHaveSideEffects())
178 if (!
GEP->hasAllConstantIndices())
180 }
else if (
I->getNumOperands() != 1) {
184 V =
I->getOperand(0);
203 bool Changed =
false;
212 Value *V =
SI->getValueOperand();
213 if (isa<Constant>(V)) {
215 SI->eraseFromParent();
218 Dead.push_back(std::make_pair(
I,
SI));
220 }
else if (
MemSetInst *MSI = dyn_cast<MemSetInst>(U)) {
221 if (isa<Constant>(MSI->getValue())) {
223 MSI->eraseFromParent();
224 }
else if (
Instruction *
I = dyn_cast<Instruction>(MSI->getValue())) {
226 Dead.push_back(std::make_pair(
I, MSI));
229 GlobalVariable *MemSrc = dyn_cast<GlobalVariable>(MTI->getSource());
232 MTI->eraseFromParent();
233 }
else if (
Instruction *
I = dyn_cast<Instruction>(MTI->getSource())) {
235 Dead.push_back(std::make_pair(
I, MTI));
237 }
else if (
ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
238 if (CE->use_empty()) {
239 CE->destroyConstant();
242 }
else if (
Constant *
C = dyn_cast<Constant>(U)) {
244 C->destroyConstant();
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();
282 bool Changed =
false;
286 for (
Value *Op :
I->operands())
287 if (
auto *OpI = dyn_cast<Instruction>(Op))
289 I->eraseFromParent();
292 while (!WorkList.
empty()) {
294 if (!Visited.
insert(U).second)
297 if (
auto *BO = dyn_cast<BitCastOperator>(U))
299 if (
auto *ASC = dyn_cast<AddrSpaceCastOperator>(U))
301 else if (
auto *
GEP = dyn_cast<GEPOperator>(U))
303 else if (
auto *LI = dyn_cast<LoadInst>(U)) {
306 Type *Ty = LI->getType();
308 LI->replaceAllUsesWith(Res);
313 Value *PtrOp = LI->getPointerOperand();
323 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(U)) {
344 auto AppendUses = [&](
Value *V) {
346 if (Visited.
insert(&U).second)
350 while (!Worklist.
empty()) {
352 User *V = U->getUser();
354 auto *
GEP = dyn_cast<GEPOperator>(V);
355 if (isa<BitCastOperator>(V) || isa<AddrSpaceCastOperator>(V) ||
356 (
GEP &&
GEP->hasAllConstantIndices())) {
364 if (isa<StoreInst>(V) && U->getOperandNo() == 0)
370 if (
Ptr != GV ||
Offset.getActiveBits() >= 64)
376 auto It = Types.try_emplace(
Offset.getZExtValue(), Ty).first;
377 if (Ty != It->second)
381 if (isa<ScalableVectorType>(Ty))
388 if (
auto *
C = dyn_cast<Constant>(V)) {
408 for (
auto *GVE : GVs) {
411 int64_t CurVarOffsetInBytes = 0;
419 if (CurVarOffsetInBytes < 0)
423 CurVarOffsetInBits = CHAR_BIT * (
uint64_t)CurVarOffsetInBytes;
426 if (CurVarOffsetInBits >= (FragmentOffsetInBits + FragmentSizeInBits))
431 if (CurVarSize != 0 &&
432 (CurVarOffsetInBits + CurVarSize) <= FragmentOffsetInBits)
436 if (CurVarOffsetInBits == FragmentOffsetInBits &&
437 CurVarSize == FragmentSizeInBits)
438 Expr = DIExpression::get(Expr->
getContext(), {});
441 else if (FragmentSizeInBits < VarSize) {
443 Expr, FragmentOffsetInBits, FragmentSizeInBits))
448 auto *NGVE = DIGlobalVariableExpression::get(GVE->getContext(), Var, Expr);
467 if (Types.size() == 1 && Types.begin()->second == GV->
getValueType())
471 if (Types.size() > 16)
481 for (
const auto &Pair : TypesVector) {
486 Offset = Pair.first +
DL.getTypeAllocSize(Pair.second);
496 for (
const auto &Pair : Types) {
500 LLVM_DEBUG(
dbgs() <<
"Global SRA: Failed to evaluate initializer of "
501 << *GV <<
" with type " << *Pair.second <<
" at offset "
502 << Pair.first <<
"\n");
505 Initializers.
insert({Pair.first, NewInit});
508 LLVM_DEBUG(
dbgs() <<
"PERFORMING GLOBAL SRA ON: " << *GV <<
"\n");
511 Align StartAlignment =
517 unsigned NameSuffix = 0;
518 for (
auto &Pair : TypesVector) {
520 Type *Ty = Pair.second;
522 *GV->
getParent(), Ty,
false, GlobalVariable::InternalLinkage,
532 if (NewAlign >
DL.getABITypeAlign(Ty))
544 auto AppendUsers = [&](
Value *V) {
546 if (Visited.
insert(U).second)
550 while (!Worklist.
empty()) {
552 if (isa<BitCastOperator>(V) || isa<AddrSpaceCastOperator>(V) ||
553 isa<GEPOperator>(V)) {
555 if (isa<Instruction>(V))
564 assert(
Ptr == GV &&
"Load/store must be from/to global");
566 assert(NGV &&
"Must have replacement global for this offset");
573 if (
auto *LI = dyn_cast<LoadInst>(V)) {
574 LI->setOperand(0, NGV);
575 LI->setAlignment(NewAlign);
577 auto *
SI = cast<StoreInst>(V);
578 SI->setOperand(1, NGV);
579 SI->setAlignment(NewAlign);
585 "Other users can only be dead constants");
595 return NewGlobals.
begin()->second;
610 if (isa<LoadInst>(U)) {
612 }
else if (
const StoreInst *
SI = dyn_cast<StoreInst>(U)) {
613 if (
SI->getOperand(0) == V) {
616 }
else if (
const CallInst *CI = dyn_cast<CallInst>(U)) {
617 if (CI->getCalledOperand() != V) {
620 }
else if (
const InvokeInst *II = dyn_cast<InvokeInst>(U)) {
621 if (II->getCalledOperand() != V) {
624 }
else if (
const BitCastInst *CI = dyn_cast<BitCastInst>(U)) {
628 }
else if (
const PHINode *PN = dyn_cast<PHINode>(U)) {
633 }
else if (isa<ICmpInst>(U) &&
634 !ICmpInst::isSigned(cast<ICmpInst>(U)->getPredicate()) &&
635 isa<LoadInst>(U->getOperand(0)) &&
636 isa<ConstantPointerNull>(U->getOperand(1))) {
637 assert(isa<GlobalValue>(cast<LoadInst>(U->getOperand(0))
638 ->getPointerOperand()
639 ->stripPointerCasts()) &&
640 "Should be GlobalVariable");
657 while (!Worklist.
empty()) {
659 for (
const auto *U :
P->users()) {
660 if (
auto *LI = dyn_cast<LoadInst>(U)) {
664 }
else if (
auto *
SI = dyn_cast<StoreInst>(U)) {
666 if (
SI->getPointerOperand() !=
P)
668 }
else if (
auto *CE = dyn_cast<ConstantExpr>(U)) {
669 if (CE->stripPointerCasts() != GV)
688 while (!Worklist.
empty()) {
690 for (
auto *U :
P->users()) {
691 if (
auto *CE = dyn_cast<ConstantExpr>(U)) {
696 assert((isa<LoadInst>(U) || isa<StoreInst>(U)) &&
697 "Expect only load or store instructions");
704 bool Changed =
false;
711 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
712 LI->setOperand(0, NewV);
715 if (
SI->getOperand(1) == V) {
716 SI->setOperand(1, NewV);
719 }
else if (isa<CallInst>(
I) || isa<InvokeInst>(
I)) {
726 bool PassedAsArg =
false;
727 for (
unsigned i = 0, e = CB->
arg_size(); i != e; ++i)
738 }
else if (
CastInst *CI = dyn_cast<CastInst>(
I)) {
742 if (CI->use_empty()) {
744 CI->eraseFromParent();
749 Idxs.
reserve(GEPI->getNumOperands()-1);
752 if (
Constant *
C = dyn_cast<Constant>(*i))
756 if (Idxs.
size() == GEPI->getNumOperands()-1)
760 if (GEPI->use_empty()) {
762 GEPI->eraseFromParent();
777 bool Changed =
false;
781 bool AllNonStoreUsesGone =
true;
785 if (
LoadInst *LI = dyn_cast<LoadInst>(GlobalUser)) {
788 if (LI->use_empty()) {
789 LI->eraseFromParent();
792 AllNonStoreUsesGone =
false;
794 }
else if (isa<StoreInst>(GlobalUser)) {
796 assert(GlobalUser->getOperand(1) == GV &&
797 "Must be storing *to* the global");
799 AllNonStoreUsesGone =
false;
803 assert((isa<PHINode>(GlobalUser) || isa<SelectInst>(GlobalUser) ||
804 isa<ConstantExpr>(GlobalUser) || isa<CmpInst>(GlobalUser) ||
805 isa<BitCastInst>(GlobalUser) ||
806 isa<GetElementPtrInst>(GlobalUser)) &&
807 "Only expect load and stores!");
812 LLVM_DEBUG(
dbgs() <<
"OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV
819 if (AllNonStoreUsesGone) {
843 I->replaceAllUsesWith(NewC);
847 while (UI !=
E && *UI ==
I)
850 I->eraseFromParent();
864 LLVM_DEBUG(
errs() <<
"PROMOTING GLOBAL: " << *GV <<
" CALL = " << *CI
883 if (!isa<UndefValue>(InitVal)) {
886 Builder.CreateMemSet(NewGV, InitVal, AllocSize, std::nullopt);
894 if (BCI->getType() == NewGV->
getType()) {
895 BCI->replaceAllUsesWith(NewGV);
896 BCI->eraseFromParent();
898 BCI->setOperand(0, NewGV);
917 bool InitBoolUsed =
false;
922 for (
auto *U : Guses) {
928 !isa<ConstantPointerNull>(
SI->getValueOperand())),
929 InitBool,
false,
Align(1),
SI->getOrdering(),
930 SI->getSyncScopeID(),
SI);
931 SI->eraseFromParent();
953 case ICmpInst::ICMP_ULT:
956 case ICmpInst::ICMP_UGE:
959 case ICmpInst::ICMP_ULE:
960 case ICmpInst::ICMP_EQ:
963 case ICmpInst::ICMP_NE:
964 case ICmpInst::ICMP_UGT:
976 cast<StoreInst>(InitBool->
user_back())->eraseFromParent();
988 for (
auto *CE : RepValues)
1004 while (!Worklist.
empty()) {
1006 if (!Visited.
insert(V).second)
1009 for (
const Use &VUse : V->
uses()) {
1010 const User *U = VUse.getUser();
1011 if (isa<LoadInst>(U) || isa<CmpInst>(U))
1014 if (
auto *
SI = dyn_cast<StoreInst>(U)) {
1015 if (
SI->getValueOperand() == V &&
1016 SI->getPointerOperand()->stripPointerCasts() != GV)
1021 if (
auto *BCI = dyn_cast<BitCastInst>(U)) {
1026 if (
auto *GEPI = dyn_cast<GetElementPtrInst>(U)) {
1063 if (AllocSize >= 2048)
1105 if (
Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) {
1113 if (
auto *CI = dyn_cast<CallInst>(StoredOnceVal)) {
1114 auto *TLI = &GetTLI(*CI->getFunction());
1144 if (!isa<LoadInst>(U) && !isa<StoreInst>(U))
1165 "No reason to shrink to bool!");
1172 bool IsOneZero =
false;
1173 bool EmitOneOrZero =
true;
1174 auto *CI = dyn_cast<ConstantInt>(OtherVal);
1175 if (CI && CI->getValue().getActiveBits() <= 64) {
1176 IsOneZero = InitVal->
isNullValue() && CI->isOne();
1179 if (CIInit && CIInit->getValue().getActiveBits() <= 64) {
1180 uint64_t ValInit = CIInit->getZExtValue();
1181 uint64_t ValOther = CI->getZExtValue();
1182 uint64_t ValMinus = ValOther - ValInit;
1184 for(
auto *GVe : GVs){
1188 unsigned SizeInOctets =
1200 dwarf::DW_OP_deref_size, SizeInOctets,
1201 dwarf::DW_OP_constu, ValMinus,
1202 dwarf::DW_OP_mul, dwarf::DW_OP_constu, ValInit,
1204 bool WithStackValue =
true;
1207 DIGlobalVariableExpression::get(NewGV->
getContext(), DGV,
E);
1210 EmitOneOrZero =
false;
1214 if (EmitOneOrZero) {
1225 bool StoringOther =
SI->getOperand(0) == OtherVal;
1228 if (StoringOther ||
SI->getOperand(0) == InitVal) {
1235 Instruction *StoredVal = cast<Instruction>(
SI->getOperand(0));
1240 if (
LoadInst *LI = dyn_cast<LoadInst>(StoredVal)) {
1241 assert(LI->getOperand(0) == GV &&
"Not a copy!");
1245 LI->getOrdering(), LI->getSyncScopeID(), LI);
1247 assert((isa<CastInst>(StoredVal) || isa<SelectInst>(StoredVal)) &&
1248 "This is not a form that we understand!");
1250 assert(isa<LoadInst>(StoreVal) &&
"Not a load of NewGV!");
1255 SI->getSyncScopeID(),
SI);
1299 if (
auto *
F = dyn_cast<Function>(&GV))
1300 Dead = (
F->isDeclaration() &&
F->use_empty()) ||
F->isDefTriviallyDead();
1307 if (
auto *
F = dyn_cast<Function>(&GV)) {
1308 if (DeleteFnCallback)
1309 DeleteFnCallback(*
F);
1332 for (
auto *U : GV->
users()) {
1334 for (
auto *UU : U->users()) {
1335 if (
auto *LI = dyn_cast<LoadInst>(UU))
1337 else if (
auto *
SI = dyn_cast<StoreInst>(UU))
1348 assert(
I->getParent()->getParent() ==
F);
1350 if (
auto *LI = dyn_cast<LoadInst>(
I))
1352 else if (
auto *
SI = dyn_cast<StoreInst>(
I))
1362 auto &DT = LookupDomTree(*
const_cast<Function *
>(
F));
1373 const unsigned Threshold = 100;
1374 if (Loads.
size() * Stores.
size() > Threshold)
1377 for (
auto *L : Loads) {
1378 auto *LTy = L->getType();
1384 return DT.dominates(S, L) &&
1385 DL.getTypeStoreSize(LTy).getFixedValue() <=
1386 DL.getTypeStoreSize(STy).getFixedValue();
1403 for (
auto *U :
C->users()) {
1404 if (isa<Instruction>(U))
1406 if (!isa<ConstantExpr>(U))
1409 for (
auto *UU : U->users())
1410 if (!isa<Instruction>(UU))
1424 for (
auto *U :
C->users()) {
1425 if (isa<ConstantExpr>(U))
1426 Users.push_back(cast<ConstantExpr>(U));
1431 isa<Instruction>(U) &&
1432 "Can't transform non-constantexpr non-instruction to instruction!");
1436 for (
auto *U :
Users) {
1439 for (
auto *UU : UUsers) {
1446 U->destroyConstant();
1460 if (!isa<Constant>(StoredOnceValue))
1465 if (
auto *LI = dyn_cast<LoadInst>(U)) {
1466 if (LI->getFunction() ==
F &&
1467 LI->getType() == StoredOnceValue->
getType() && LI->isSimple())
1472 bool MadeChange =
false;
1473 if (!Loads.
empty()) {
1474 auto &DT = LookupDomTree(*
const_cast<Function *
>(
F));
1475 for (
auto *LI : Loads) {
1476 if (DT.dominates(StoredOnceStore, LI)) {
1477 LI->replaceAllUsesWith(
const_cast<Value *
>(StoredOnceValue));
1478 LI->eraseFromParent();
1502 if (!GS.HasMultipleAccessingFunctions &&
1503 GS.AccessingFunction &&
1508 GS.AccessingFunction->doesNotRecurse() &&
1515 ->getEntryBlock().begin());
1531 bool Changed =
false;
1562 if (GS.Ordering == AtomicOrdering::NotAtomic) {
1573 LLVM_DEBUG(
dbgs() <<
" *** Marking constant allowed us to simplify "
1574 <<
"all users and delete global!\n");
1588 Value *StoredOnceValue = GS.getStoredOnceValue();
1591 const_cast<Function &
>(*GS.StoredOnceStore->getFunction());
1592 bool CanHaveNonUndefGlobalInitializer =
1593 GetTTI(StoreFn).canHaveNonUndefGlobalInitializerInAddressSpace(
1602 auto *SOVConstant = dyn_cast<Constant>(StoredOnceValue);
1604 DL.getTypeAllocSize(SOVConstant->getType()) ==
1606 CanHaveNonUndefGlobalInitializer) {
1617 NGV->copyAttributesFrom(GV);
1627 LLVM_DEBUG(
dbgs() <<
" *** Substituting initializer allowed us to "
1628 <<
"simplify all users and delete global!\n");
1643 if (GS.NumStores == 1)
1649 if (SOVConstant && GS.Ordering == AtomicOrdering::NotAtomic &&
1651 CanHaveNonUndefGlobalInitializer)) {
1677 bool Changed =
false;
1679 auto NewUnnamedAddr = GV.
hasLocalLinkage() ? GlobalValue::UnnamedAddr::Global
1680 : GlobalValue::UnnamedAddr::Local;
1692 auto *GVar = dyn_cast<GlobalVariable>(&GV);
1696 if (GVar->isConstant() || !GVar->hasInitializer())
1706 for (
User *U :
F->users()) {
1707 if (isa<BlockAddress>(U))
1716 if (Attrs.hasAttrSomewhere(
A, &AttrIndex))
1717 return Attrs.removeAttributeAtIndex(
C, AttrIndex,
A);
1722 F->setAttributes(
StripAttr(
F->getContext(),
F->getAttributes(),
A));
1723 for (
User *U :
F->users()) {
1724 if (isa<BlockAddress>(U))
1746 for (
User *U :
F->users()) {
1747 if (isa<BlockAddress>(U))
1749 CallInst* CI = dyn_cast<CallInst>(U);
1758 if (BB.getTerminatingMustTailCall())
1769 auto CallSiteFreq = CallerBFI.
getBlockFreq(CallSiteBB);
1770 auto CallerEntryFreq =
1772 return CallSiteFreq < CallerEntryFreq * ColdProb;
1782 const std::vector<Function *> &AllCallsCold) {
1787 for (
User *U :
F.users()) {
1788 if (isa<BlockAddress>(U))
1803 for (
User *U :
F->users()) {
1804 if (isa<BlockAddress>(U))
1818 if (
CallInst *CI = dyn_cast<CallInst>(&
I)) {
1820 if (CI->isInlineAsm())
1822 Function *CalledFn = CI->getCalledFunction();
1847 for (
User *U :
F->users()) {
1848 CallBase *CB = dyn_cast<CallBase>(U);
1850 assert(isa<BlockAddress>(U) &&
1851 "Expected either CallBase or BlockAddress");
1861 for (
User *U :
F->users())
1862 if (isa<InvokeInst>(U))
1870 auto *M =
F->getParent();
1876 for (
User *U : PreallocatedCalls) {
1877 CallBase *CB = dyn_cast<CallBase>(U);
1883 "Shouldn't call RemotePreallocated() on a musttail preallocated call");
1887 CallBase *PreallocatedSetup =
nullptr;
1888 for (
auto *It = OpBundles.
begin(); It != OpBundles.
end(); ++It) {
1889 if (It->getTag() ==
"preallocated") {
1890 PreallocatedSetup = cast<CallBase>(*It->input_begin());
1891 OpBundles.
erase(It);
1895 assert(PreallocatedSetup &&
"Did not find preallocated bundle");
1897 cast<ConstantInt>(PreallocatedSetup->
getArgOperand(0))->getZExtValue();
1899 assert((isa<CallInst>(CB) || isa<InvokeInst>(CB)) &&
1900 "Unknown indirect call type");
1906 Builder.SetInsertPoint(PreallocatedSetup);
1923 for (
auto *
User : PreallocatedArgs) {
1924 auto *UseCall = cast<CallBase>(
User);
1925 assert(UseCall->getCalledFunction()->getIntrinsicID() ==
1926 Intrinsic::call_preallocated_arg &&
1927 "preallocated token use was not a llvm.call.preallocated.arg");
1929 cast<ConstantInt>(UseCall->getArgOperand(1))->getZExtValue();
1930 Value *AllocaReplacement = ArgAllocas[AllocArgIndex];
1931 if (!AllocaReplacement) {
1932 auto AddressSpace = UseCall->getType()->getPointerAddressSpace();
1934 UseCall->getFnAttr(Attribute::Preallocated).getValueAsType();
1936 Builder.SetInsertPoint(InsertBefore);
1939 auto *BitCast =
Builder.CreateBitCast(
1941 ArgAllocas[AllocArgIndex] = BitCast;
1942 AllocaReplacement = BitCast;
1946 UseCall->eraseFromParent();
1949 cast<Instruction>(PreallocatedSetup)->eraseFromParent();
1963 bool Changed =
false;
1965 std::vector<Function *> AllCallsCold;
1968 AllCallsCold.push_back(&
F);
1974 if (
F.hasFnAttribute(Attribute::Naked))
1978 if (!
F.hasName() && !
F.isDeclaration() && !
F.hasLocalLinkage())
1981 if (
deleteIfDead(
F, NotDiscardableComdats, DeleteFnCallback)) {
1995 if (!
F.isDeclaration()) {
1998 ChangedCFGCallback(
F);
2004 if (!
F.hasLocalLinkage())
2012 if (
F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) &&
2020 if (
F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
2056 if (
F.getAttributes().hasAttrSomewhere(Attribute::Nest) &&
2057 !
F.hasAddressTaken()) {
2074 bool Changed =
false;
2081 if (GV.hasInitializer())
2082 if (
auto *
C = dyn_cast<Constant>(GV.getInitializer())) {
2083 auto &
DL = M.getDataLayout();
2089 GV.setInitializer(New);
2097 Changed |=
processGlobal(GV, GetTTI, GetTLI, LookupDomTree);
2107 if (
F->isDeclaration())
2116 ++NumCtorsEvaluated;
2121 <<
F->getName() <<
"' to " << NewInitializers.size()
2123 for (
const auto &Pair : NewInitializers)
2124 Pair.first->setInitializer(Pair.second);
2126 GV->setConstant(
true);
2156 ArrayType *ATy = ArrayType::get(Int8PtrTy, UsedArray.
size());
2164 NV->setSection(
"llvm.metadata");
2184 CompilerUsed = {Vec.
begin(), Vec.
end()};
2190 iterator usedBegin() {
return Used.begin(); }
2191 iterator usedEnd() {
return Used.end(); }
2193 used_iterator_range used() {
2194 return used_iterator_range(usedBegin(), usedEnd());
2197 iterator compilerUsedBegin() {
return CompilerUsed.
begin(); }
2198 iterator compilerUsedEnd() {
return CompilerUsed.
end(); }
2200 used_iterator_range compilerUsed() {
2201 return used_iterator_range(compilerUsedBegin(), compilerUsedEnd());
2207 return CompilerUsed.
count(GV);
2215 return CompilerUsed.
insert(GV).second;
2218 void syncVariablesAndSets() {
2232 assert((!U.usedCount(&GA) || !U.compilerUsedCount(&GA)) &&
2233 "We should have removed the duplicated "
2234 "element from llvm.compiler.used");
2241 return !U.usedCount(&GA) && !U.compilerUsedCount(&GA);
2245 const LLVMUsed &U) {
2247 assert((!U.usedCount(&V) || !U.compilerUsedCount(&V)) &&
2248 "We should have removed the duplicated "
2249 "element from llvm.compiler.used");
2250 if (U.usedCount(&V) || U.compilerUsedCount(&V))
2259 return U.usedCount(&GA) || U.compilerUsedCount(&GA);
2263 bool &RenameTarget) {
2264 RenameTarget =
false;
2281 if (!
Target->hasLocalLinkage())
2290 RenameTarget =
true;
2297 bool Changed =
false;
2301 Used.compilerUsedErase(GV);
2312 if (!J.hasName() && !J.isDeclaration() && !J.hasLocalLinkage())
2321 if (!IsModuleLocal(J))
2324 Constant *Aliasee = J.getAliasee();
2335 Target->removeDeadConstantUsers();
2343 ++NumAliasesResolved;
2349 Target->setLinkage(J.getLinkage());
2350 Target->setDSOLocal(J.isDSOLocal());
2351 Target->setVisibility(J.getVisibility());
2352 Target->setDLLStorageClass(J.getDLLStorageClass());
2354 if (Used.usedErase(&J))
2357 if (Used.compilerUsedErase(&J))
2358 Used.compilerUsedInsert(
Target);
2363 M.getAliasList().erase(&J);
2364 ++NumAliasesRemoved;
2368 Used.syncVariablesAndSets();
2376 auto FuncIter = M.begin();
2377 if (FuncIter == M.end())
2379 auto *TLI = &GetTLI(*FuncIter);
2385 Function *Fn = M.getFunction(TLI->getName(
F));
2393 if (!TLI->getLibFunc(*Fn,
F) ||
F != LibFunc_cxa_atexit)
2410 if (
I.isDebugOrPseudoInst())
2412 if (isa<ReturnInst>(
I))
2434 bool Changed =
false;
2440 CallInst *CI = dyn_cast<CallInst>(U);
2453 ++NumCXXDtorsRemoved;
2470 bool Changed =
false;
2471 bool LocalChange =
true;
2472 std::optional<uint32_t> FirstNotFullyEvaluatedPriority;
2474 while (LocalChange) {
2475 LocalChange =
false;
2477 NotDiscardableComdats.
clear();
2481 NotDiscardableComdats.
insert(
C);
2483 if (
const Comdat *
C =
F.getComdat())
2484 if (!
F.isDefTriviallyDead())
2485 NotDiscardableComdats.
insert(
C);
2487 if (
const Comdat *
C = GA.getComdat())
2488 if (!GA.isDiscardableIfUnused() || !GA.use_empty())
2489 NotDiscardableComdats.
insert(
C);
2493 NotDiscardableComdats, ChangedCFGCallback,
2499 if (FirstNotFullyEvaluatedPriority &&
2500 *FirstNotFullyEvaluatedPriority != Priority)
2504 FirstNotFullyEvaluatedPriority = Priority;
2510 NotDiscardableComdats);
2521 Changed |= LocalChange;
2531 auto &
DL = M.getDataLayout();
2553 ChangedCFGCallback, DeleteFnCallback))
2568struct GlobalOptLegacyPass :
public ModulePass {
2575 bool runOnModule(
Module &M)
override {
2579 auto &
DL = M.getDataLayout();
2581 return this->getAnalysis<DominatorTreeWrapperPass>(
F).getDomTree();
2584 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
2587 return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
2591 return this->getAnalysis<BlockFrequencyInfoWrapperPass>(
F).getBFI();
2594 auto ChangedCFGCallback = [&LookupDomTree](
Function &
F) {
2595 auto &DT = LookupDomTree(
F);
2600 ChangedCFGCallback,
nullptr);
2613char GlobalOptLegacyPass::ID = 0;
2616 "Global Variable Optimizer",
false,
false)
2625 return new GlobalOptLegacyPass();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
SmallPtrSet< MachineInstr *, 2 > Uses
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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
static bool IsSafeComputationToRemove(Value *V, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
Given a value that is stored to a global but never read, determine whether it's safe to remove the st...
static Function * FindCXAAtExit(Module &M, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
static bool optimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal, const DataLayout &DL, function_ref< TargetLibraryInfo &(Function &)> GetTLI)
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 allUsesOfLoadedValueWillTrapIfNull(const GlobalVariable *GV)
Return true if all uses of any loads from GV will trap if the loaded value is null.
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 bool hasMoreThanOneUseOtherThanLLVMUsed(GlobalValue &V, const LLVMUsed &U)
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 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 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 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 void makeAllConstantUsesInstructions(Constant *C)
C may have non-instruction users, and allNonInstructionUsersCanBeMadeInstructions has returned true.
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 mayHaveOtherReferences(GlobalAlias &GA, const LLVMUsed &U)
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 hasChangeableCC(Function *F)
Return true if this is a calling convention that we'd like to change.
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 hasOnlyColdCalls(Function &F, function_ref< BlockFrequencyInfo &(Function &)> GetBFI)
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.
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 bool collectSRATypes(DenseMap< uint64_t, Type * > &Types, GlobalValue *GV, const DataLayout &DL)
Look at all uses of the global and determine which (offset, type) pairs it can be split into.
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 allNonInstructionUsersCanBeMadeInstructions(Constant *C)
C may have non-instruction users.
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)
iv Induction Variable Users
static M68kRelType getType(unsigned Kind, MCSymbolRefExpr::VariantKind &Modifier, bool &IsPCRel)
Module.h This file contains the declarations for the Module class.
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
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)
This defines the Use class.
Class for arbitrary precision integers.
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.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
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.
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
This class represents a no-op cast from one type to another.
Analysis pass which computes BlockFrequencyInfo.
Legacy 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, Instruction *InsertPt=nullptr)
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
This is the base class for all instructions that perform data casts.
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 * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, std::optional< unsigned > InRangeIndex=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static ConstantInt * getTrue(LLVMContext &Context)
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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.
A parsed version of the target data layout string in and methods for querying it.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Analysis pass which computes a DominatorTree.
Legacy 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.
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
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 removeFromParent()
removeFromParent - This method unlinks 'this' from the containing module, but does not delete it.
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.
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
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
const Function * getFunction() const
Return the function this instruction belongs to.
const Instruction * getNextNonDebugInstruction(bool SkipPseudoOp=false) const
Return a pointer to the next non-debug instruction in the same basic block as 'this',...
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void 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.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
const GlobalListType & getGlobalList() const
Get the Module's list of global variables (constant).
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
bool insert(const value_type &X)
Insert a new element into the SetVector.
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.
A SetVector that performs no allocations if smaller than a certain size.
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 startswith(StringRef Prefix) const
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)
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
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.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
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()
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
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.
iterator insert(iterator where, pointer New)
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ X86_ThisCall
Similar to X86_StdCall.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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 a range to a container.
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 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.
void initializeGlobalOptLegacyPassPass(PassRegistry &)
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 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.
Constant * ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty)
If C is a uniform value where all bits are the same (either all zero, all ones, all undef or all pois...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Global
Append to llvm.global_dtors.
ModulePass * createGlobalOptimizerPass()
createGlobalOptimizerPass - This function returns a new pass that optimizes non-address taken interna...
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...
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)
Wrapper function around std::find to detect if an element exists in a container.
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 ...
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 std::pair compares less than the first comp...