40#define DEBUG_TYPE "nvptx-promote-param-align"
45class NVPTXPromoteParamAlignLegacyPass :
public ModulePass {
46 bool runOnModule(
Module &M)
override;
52 return "Promote alignment of parameters and return values (NVPTX)";
57char NVPTXPromoteParamAlignLegacyPass::ID = 0;
60 "Promote alignment of parameters and return values (NVPTX)",
66 if (CalleeAttrs.getByValType() !=
CallAttrs.getByValType() ||
67 CalleeAttrs.getStackAlignment() !=
CallAttrs.getStackAlignment())
71 return !CalleeAttrs.getByValType() ||
72 CalleeAttrs.getAlignment() ==
CallAttrs.getAlignment();
76 const AttributeList CalleeAttrs =
F.getAttributes();
79 if (!layoutAttrsMatch(CalleeAttrs.getRetAttrs(),
CallAttrs.getRetAttrs()))
83 return layoutAttrsMatch(CalleeAttrs.getParamAttrs(I),
84 CallAttrs.getParamAttrs(I));
91 if (
F.isDeclaration() || !
F.hasLocalLinkage())
94 if (
F.hasAddressTaken(
nullptr,
false,
100 const auto *CB = dyn_cast<CallBase>(U);
101 if (!CB || CB->getCalledOperand() != &F)
103 return CB->getFunctionType() == F.getFunctionType() &&
104 callSiteMatchesCalleeABI(*CB, F);
123 std::queue<LoadContext> Worklist;
124 Worklist.push({Val, 0});
126 while (!Worklist.empty()) {
127 LoadContext Ctx = Worklist.front();
130 for (
User *CurUser : Ctx.InitialVal->
users()) {
136 APInt OffsetAccumulated =
139 if (!
I->accumulateConstantOffset(
DL, OffsetAccumulated))
144 assert(
Offset != OffsetLimit &&
"Expect Offset less than UINT64_MAX");
146 Worklist.push({
I, Ctx.Offset +
Offset});
152 for (Load &CurLoad : Loads) {
154 if (NewLoadAlign > CurLoad.Inst->getAlign()) {
155 CurLoad.Inst->setAlignment(NewLoadAlign);
165 const Align PromotedAlign = std::max(CurrentAlign,
Align(16));
166 if (PromotedAlign > CurrentAlign)
167 return PromotedAlign;
184 const bool IsByVal = Arg.hasByValAttr();
185 Type *ArgTy = IsByVal ? Arg.getParamByValType() : Arg.getType();
190 if (Arg.getParamStackAlign())
192 const unsigned ArgNo = Arg.getArgNo();
197 CurrentAlign = std::max(CurrentAlign, Arg.getParamAlign().valueOrOne());
203 << PromotedAlign->value() <<
'\n');
209 Type *RetTy =
F.getReturnType();
211 !
F.getAttributes().getRetStackAlignment()) {
216 PromotedRet = *PromotedAlign;
220 if (PromotedParams.
empty() && !PromotedRet)
226 for (
User *U :
F.users()) {
228 if (!CB || CB->getCalledOperand() != &
F)
231 for (
const auto &[ArgNo, PromotedAlign] : PromotedParams)
232 CB->addParamAttr(ArgNo,
238 "mirroring must preserve call-site/callee ABI compatibility");
248 if (
F.isDeclaration())
255 if (!Arg.hasByValAttr())
257 Type *ETy = Arg.getParamByValType();
261 if (Arg.getParamAlign().valueOrOne() >= ABIAlign)
263 Arg.removeAttr(Attribute::Alignment);
275 if (
F.isDeclaration())
281 if (!Arg.hasByValAttr())
283 Type *ETy = Arg.getParamByValType();
286 const unsigned ParamIdx = Arg.getArgNo() + AttributeList::FirstArgIndex;
305bool NVPTXPromoteParamAlignLegacyPass::runOnModule(
Module &M) {
310 return new NVPTXPromoteParamAlignLegacyPass();
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...
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Provides some synthesis utilities to produce sequences of values.
Class for arbitrary precision integers.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
This class represents an incoming formal argument to a Function.
This class holds the attributes for a particular argument, parameter, function, or return value.
static LLVM_ABI Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)
static LLVM_ABI Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
AttributeList getAttributes() const
Return the attributes for this call.
A parsed version of the target data layout string in and methods for querying it.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
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.
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.
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.
Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
LLVM Value Representation.
iterator_range< user_iterator > users()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
Align getDeviceByValParamAlign(const Function *F, Type *ArgTy, unsigned AttrIdx, const DataLayout &DL)
The .param-space alignment for a byval parameter or call argument: the (possibly promoted) parameter ...
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Align getPTXParamTypeAlign(Type *ArgTy, const DataLayout &DL)
ABI alignment of ArgTy in .param space, capped at the PTX maximum of 128.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool shouldPassAsArray(Type *Ty)
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...
ModulePass * createNVPTXPromoteParamAlignPass()
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
This struct is a compact representation of a valid (non-zero power of two) alignment.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.