83#define DEBUG_TYPE "argpromotion"
85STATISTIC(NumArgumentsPromoted,
"Number of pointer arguments promoted");
86STATISTIC(NumArgumentsDead,
"Number of dead pointer args eliminated");
98using OffsetAndArgPart = std::pair<int64_t, ArgPart>;
122 std::vector<Type *> Params;
131 AttributeList PAL =
F->getAttributes();
135 unsigned ArgNo = 0, NewArgNo = 0;
138 auto It = ArgsToPromote.find(&*
I);
139 if (It == ArgsToPromote.end()) {
141 Params.push_back(
I->getType());
142 ArgAttrVec.
push_back(PAL.getParamAttrs(ArgNo));
144 }
else if (
I->use_empty()) {
149 <<
"eliminating argument " <<
ore::NV(
"ArgName",
I->getName())
150 <<
"(" <<
ore::NV(
"ArgIndex", ArgNo) <<
")";
155 const auto &ArgParts = It->second;
156 for (
const auto &Pair : ArgParts) {
157 Params.push_back(Pair.second.Ty);
160 ++NumArgumentsPromoted;
163 <<
"promoting argument " <<
ore::NV(
"ArgName",
I->getName())
164 <<
"(" <<
ore::NV(
"ArgIndex", ArgNo) <<
")"
165 <<
" to pass by value";
169 NewArgNo += ArgParts.size();
173 Type *RetTy = FTy->getReturnType();
187 F->setSubprogram(
nullptr);
189 LLVM_DEBUG(
dbgs() <<
"ARG PROMOTION: Promoting to:" << *NF <<
"\n"
193 for (
auto *
I : Params)
195 LargestVectorWidth = std::max(
196 LargestVectorWidth, VT->getPrimitiveSizeInBits().getKnownMinValue());
200 NF->
setAttributes(AttributeList::get(
F->getContext(), PAL.getFnAttrs(),
201 PAL.getRetAttrs(), ArgAttrVec));
204 if (
auto AllocSize = NF->
getAttributes().getFnAttrs().getAllocSizeArgs()) {
205 unsigned Arg1 = NewArgIndices[AllocSize->first];
206 assert(Arg1 != (
unsigned)-1 &&
"allocsize cannot be promoted argument");
207 std::optional<unsigned> Arg2;
208 if (AllocSize->second) {
209 Arg2 = NewArgIndices[*AllocSize->second];
210 assert(Arg2 != (
unsigned)-1 &&
"allocsize cannot be promoted argument");
215 AttributeFuncs::updateMinLegalVectorWidthAttr(*NF, LargestVectorWidth);
218 F->getParent()->getFunctionList().insert(
F->getIterator(), NF);
227 while (!
F->use_empty()) {
238 ++
I, ++AI, ++ArgNo) {
239 auto ArgIt = ArgsToPromote.find(&*
I);
240 if (ArgIt == ArgsToPromote.end()) {
242 ArgAttrVec.
push_back(CallPAL.getParamAttrs(ArgNo));
243 }
else if (!
I->use_empty()) {
245 for (
const auto &Pair : ArgIt->second) {
249 Pair.second.Alignment, V->getName() +
".val");
250 if (Pair.second.MustExecInstr) {
251 LI->
setAAMetadata(Pair.second.MustExecInstr->getAAMetadata());
253 {LLVMContext::MD_dereferenceable,
254 LLVMContext::MD_dereferenceable_or_null,
255 LLVMContext::MD_noundef,
256 LLVMContext::MD_nontemporal});
275 for (; AI != CB.
arg_end(); ++AI, ++ArgNo) {
277 ArgAttrVec.
push_back(CallPAL.getParamAttrs(ArgNo));
295 CallPAL.getFnAttrs(),
296 CallPAL.getRetAttrs(), ArgAttrVec));
297 NewCS->
copyMetadata(CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
301 AttributeFuncs::updateMinLegalVectorWidthAttr(*CB.
getCaller(),
329 if (!ArgsToPromote.count(&Arg)) {
332 Arg.replaceAllUsesWith(&*I2);
351 assert(Arg.getType()->isPointerTy() &&
352 "Only arguments with a pointer type are promotable");
358 for (
const auto &Pair : ArgsToPromote.find(&Arg)->second) {
359 int64_t
Offset = Pair.first;
360 const ArgPart &Part = Pair.second;
366 Part.Ty,
nullptr, Arg.getName() +
"." +
Twine(
Offset) +
".allc");
374 auto GetAlloca = [&](
Value *Ptr) {
376 Ptr = Ptr->stripAndAccumulateConstantOffsets(
DL,
Offset,
378 assert(Ptr == &Arg &&
"Not constant offset from arg?");
387 while (!Worklist.
empty()) {
396 Value *Ptr = LI->getPointerOperand();
402 assert(!
SI->isVolatile() &&
"Volatile operations can't be promoted.");
403 Value *Ptr =
SI->getPointerOperand();
413 I->eraseFromParent();
417 for (
const auto &Pair : OffsetToAlloca) {
419 "By design, only promotable allocas should be produced.");
425 <<
" alloca(s) are promotable by Mem2Reg\n");
427 if (!Allocas.
empty()) {
442 auto Temp = SP->getType()->cloneWithCC(llvm::dwarf::DW_CC_nocall);
456 APInt Bytes(64, NeededDerefBytes);
465 CallBase &CB = cast<CallBase>(*U);
490 if (RecursiveCalls.contains(&CB))
493 return isDereferenceableAndAlignedPointer(CB.getArgOperand(Arg->getArgNo()),
494 NeededAlign, Bytes, DL);
522 unsigned MaxElements,
bool IsRecursive,
543 Align NeededAlign(1);
555 auto HandleEndUser = [&](
auto *
I,
Type *Ty,
556 bool GuaranteedToExecute) -> std::optional<bool> {
561 Value *Ptr =
I->getPointerOperand();
568 if (
Offset.getSignificantBits() >= 64)
573 if (
Size.isScalable())
578 if (IsRecursive && Ty->isPointerTy())
581 int64_t Off =
Offset.getSExtValue();
583 Off, ArgPart{Ty,
I->getAlign(), GuaranteedToExecute ?
I :
nullptr});
584 ArgPart &Part = Pair.first->second;
585 bool OffsetNotSeenBefore = Pair.second;
589 if (MaxElements > 0 && ArgParts.
size() > MaxElements) {
591 <<
"more than " << MaxElements <<
" parts\n");
599 <<
"accessed as both " << *Part.Ty <<
" and " << *Ty
600 <<
" at offset " << Off <<
"\n");
610 if (!GuaranteedToExecute &&
611 (OffsetNotSeenBefore || Part.Alignment <
I->getAlign())) {
620 NeededDerefBytes = std::max(NeededDerefBytes, Off +
Size.getFixedValue());
621 NeededAlign = std::max(NeededAlign,
I->getAlign());
624 Part.Alignment = std::max(Part.Alignment,
I->getAlign());
630 std::optional<bool> Res{};
632 Res = HandleEndUser(LI, LI->getType(),
true);
634 Res = HandleEndUser(
SI,
SI->getValueOperand()->getType(),
649 auto AppendUses = [&](
const Value *V) {
651 if (Visited.
insert(&U).second)
655 while (!Worklist.
empty()) {
657 Value *V = U->getUser();
660 if (!
GEP->hasAllConstantIndices())
667 if (!*HandleEndUser(LI, LI->getType(),
false))
675 if (AreStoresAllowed &&
SI &&
677 if (!*HandleEndUser(
SI,
SI->getValueOperand()->getType(),
686 Value *PtrArg = U->get();
687 if (CB && CB->getCalledFunction() == CB->getFunction()) {
690 <<
"pointer offset is not equal to zero\n");
694 unsigned int ArgNo = Arg->
getArgNo();
695 if (U->getOperandNo() != ArgNo) {
697 <<
"arg position is different in callee\n");
703 if (MaxElements > 0 && ArgParts.
size() > MaxElements) {
705 <<
"more than " << MaxElements <<
" parts\n");
709 RecursiveCalls.
insert(CB);
714 <<
"unknown user " << *V <<
"\n");
718 if (NeededDerefBytes || NeededAlign > 1) {
723 <<
"not dereferenceable or aligned\n");
728 if (ArgParts.
empty())
736 int64_t
Offset = ArgPartsVec[0].first;
737 for (
const auto &Pair : ArgPartsVec) {
741 Offset = Pair.first +
DL.getTypeStoreSize(Pair.second.Ty);
747 if (AreStoresAllowed)
791 CallBase *CB = dyn_cast<CallBase>(U.getUser());
795 const Function *Caller = CB->getCaller();
796 const Function *Callee = CB->getCalledFunction();
797 return TTI.areTypesABICompatible(Caller, Callee, Types);
806 unsigned MaxElements,
bool IsRecursive) {
810 if (
F->hasFnAttribute(Attribute::Naked))
814 if (!
F->hasLocalLinkage())
827 if (
F->getAttributes().hasAttrSomewhere(Attribute::InAlloca))
833 if (
I.getType()->isPointerTy())
835 if (PointerArgs.
empty())
841 for (
Use &U :
F->uses()) {
844 if (CB ==
nullptr || !CB->
isCallee(&U) ||
859 if (BB.getTerminatingMustTailCall())
869 unsigned NumArgsAfterPromote =
F->getFunctionType()->getNumParams();
870 for (
Argument *PtrArg : PointerArgs) {
873 if (PtrArg->hasStructRetAttr()) {
874 unsigned ArgNo = PtrArg->getArgNo();
875 F->removeParamAttr(ArgNo, Attribute::StructRet);
876 F->addParamAttr(ArgNo, Attribute::NoAlias);
877 for (
Use &U :
F->uses()) {
887 if (
findArgParts(PtrArg,
DL, AAR, MaxElements, IsRecursive, ArgParts,
890 for (
const auto &Pair : ArgParts)
894 NumArgsAfterPromote += ArgParts.size() - 1;
895 ArgsToPromote.
insert({PtrArg, std::move(ArgParts)});
901 if (ArgsToPromote.
empty())
904 if (NumArgsAfterPromote >
TTI.getMaxNumArgs())
914 bool Changed =
false, LocalChange;
923 bool IsRecursive =
C.size() > 1;
936 C.getOuterRefSCC().replaceNodeFunction(
N, *NewF);
942 for (
auto *U : NewF->
users()) {
944 FAM.invalidate(*UserF, FuncPA);
949 }
while (LocalChange);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
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)
A manager for alias analyses.
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
Check whether or not an instruction may read or write the optionally specified memory location.
LLVM_ABI bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2, const MemoryLocation &Loc, const ModRefInfo Mode)
Check if it is possible for the execution of the specified instructions to mod(according to the mode)...
LLVM_ABI bool canBasicBlockModify(const BasicBlock &BB, const MemoryLocation &Loc)
Check if it is possible for execution of the specified basic block to modify the location Loc.
Class for arbitrary precision integers.
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
an instruction to allocate memory on the stack
void setAlignment(Align Align)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
const Function * getParent() const
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
LLVM_ABI Type * getParamByValType() const
If this is a byval argument, return its type.
LLVM_ABI MaybeAlign getParamAlign() const
If this is a byval or inalloca argument, return its alignment.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A function analysis which provides an AssumptionCache.
This class holds the attributes for a particular argument, parameter, function, or return value.
static LLVM_ABI Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const std::optional< unsigned > &NumElemsArg)
LLVM Basic Block Representation.
const Instruction & front() const
Represents analyses that only rely on functions' control flow.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void setCallingConv(CallingConv::ID CC)
LLVM_ABI void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Removes the attribute from the given argument.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
void setAttributes(AttributeList A)
Set the attributes for this call.
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
FunctionType * getFunctionType() const
AttributeList getAttributes() const
Return the attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Subprogram description. Uses SubclassData1.
A parsed version of the target data layout string in and methods for querying it.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Analysis pass which computes a DominatorTree.
A proxy from a FunctionAnalysisManager to an SCC.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
void splice(Function::iterator ToIt, Function *FromF)
Transfer all blocks from FromF to this function at ToIt.
const BasicBlock & getEntryBlock() const
DISubprogram * getSubprogram() const
Get the attached subprogram.
AttributeList getAttributes() const
Return the attribute list for this Function.
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
LLVM_ABI void copyMetadata(const GlobalObject *Src, unsigned Offset)
Copy metadata from Src, adjusting offsets by Offset.
Common base class shared among various IRBuilders.
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr, InsertPosition InsertBefore=nullptr)
A node in the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
An instruction for reading from memory.
static unsigned getPointerOperandIndex()
static std::enable_if_t< std::is_base_of< MDNode, T >::value, T * > replaceWithPermanent(std::unique_ptr< T, TempMDNodeDeleter > N)
Replace a temporary node with a permanent one.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static LLVM_ABI MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
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.
static unsigned getPointerOperandIndex()
Analysis pass providing the TargetTransformInfo.
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.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void PromoteMemToReg(ArrayRef< AllocaInst * > Allocas, DominatorTree &DT, AssumptionCache *AC=nullptr)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
LLVM_ABI bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, Align Alignment, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Returns true if V is always a dereferenceable pointer with alignment greater or equal than requested.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
bool isModSet(const ModRefInfo MRI)
void sort(IteratorTy Start, IteratorTy End)
iterator_range< idf_iterator< T > > inverse_depth_first(const T &G)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Mod
The access may modify the value stored in memory.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(SmallVectorImpl< WeakTrackingVH > &DeadInsts, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow instructions that are not...
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
Function object to check whether the first component of a container supported by std::get (like std::...