39#define DEBUG_TYPE "nvptx-promote-param-align"
44class NVPTXPromoteParamAlignLegacyPass :
public ModulePass {
45 bool runOnModule(
Module &M)
override;
49 NVPTXPromoteParamAlignLegacyPass() :
ModulePass(ID) {}
51 return "Promote alignment of parameters and return values (NVPTX)";
56char NVPTXPromoteParamAlignLegacyPass::ID = 0;
59 "Promote alignment of parameters and return values (NVPTX)",
65 if (CalleeAttrs.getByValType() !=
CallAttrs.getByValType() ||
66 CalleeAttrs.getStackAlignment() !=
CallAttrs.getStackAlignment())
70 return !CalleeAttrs.getByValType() ||
71 CalleeAttrs.getAlignment() ==
CallAttrs.getAlignment();
75 const AttributeList CalleeAttrs =
F.getAttributes();
78 if (!layoutAttrsMatch(CalleeAttrs.getRetAttrs(),
CallAttrs.getRetAttrs()))
82 return layoutAttrsMatch(CalleeAttrs.getParamAttrs(I),
83 CallAttrs.getParamAttrs(I));
90 if (
F.isDeclaration() || !
F.hasLocalLinkage())
93 if (
F.hasAddressTaken(
nullptr,
false,
99 const auto *CB = dyn_cast<CallBase>(U);
100 if (!CB || CB->getCalledOperand() != &F)
102 return CB->getFunctionType() == F.getFunctionType() &&
103 callSiteMatchesCalleeABI(*CB, F);
122 std::queue<LoadContext> Worklist;
123 Worklist.push({Val, 0});
125 while (!Worklist.empty()) {
126 LoadContext Ctx = Worklist.front();
129 for (
User *CurUser : Ctx.InitialVal->
users()) {
135 APInt OffsetAccumulated =
138 if (!
I->accumulateConstantOffset(
DL, OffsetAccumulated))
143 assert(
Offset != OffsetLimit &&
"Expect Offset less than UINT64_MAX");
145 Worklist.push({
I, Ctx.Offset +
Offset});
151 for (
Load &CurLoad : Loads) {
153 if (NewLoadAlign > CurLoad.Inst->getAlign()) {
154 CurLoad.Inst->setAlignment(NewLoadAlign);
164 const Align PromotedAlign = std::max(CurrentAlign,
Align(16));
165 if (PromotedAlign > CurrentAlign)
166 return PromotedAlign;
183 const bool IsByVal = Arg.hasByValAttr();
184 Type *ArgTy = IsByVal ? Arg.getParamByValType() : Arg.getType();
189 if (Arg.getParamStackAlign())
191 const unsigned ArgNo = Arg.getArgNo();
196 CurrentAlign = std::max(CurrentAlign, Arg.getParamAlign().valueOrOne());
202 << PromotedAlign->value() <<
'\n');
208 Type *RetTy =
F.getReturnType();
210 !
F.getAttributes().getRetStackAlignment()) {
215 PromotedRet = *PromotedAlign;
219 if (PromotedParams.
empty() && !PromotedRet)
225 for (
User *U :
F.users()) {
227 if (!CB || CB->getCalledOperand() != &
F)
230 for (
const auto &[ArgNo, PromotedAlign] : PromotedParams)
231 CB->addParamAttr(ArgNo,
237 "mirroring must preserve call-site/callee ABI compatibility");
247 if (
F.isDeclaration())
254 if (!Arg.hasByValAttr())
256 Type *ETy = Arg.getParamByValType();
260 if (Arg.getParamAlign().valueOrOne() >= ABIAlign)
262 Arg.removeAttr(Attribute::Alignment);
274 if (
F.isDeclaration())
280 if (!Arg.hasByValAttr())
282 Type *ETy = Arg.getParamByValType();
285 const unsigned ParamIdx = Arg.getArgNo() + AttributeList::FirstArgIndex;
304bool NVPTXPromoteParamAlignLegacyPass::runOnModule(
Module &M) {
309 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()
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.
@ Load
The value being inserted comes from a load (InsertElement only).
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.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
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.