LLVM 24.0.0git
NVPTXUtilities.cpp
Go to the documentation of this file.
1//===- NVPTXUtilities.cpp - Utility Functions -----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains miscellaneous utility functions
10//
11//===----------------------------------------------------------------------===//
12
13#include "NVPTXUtilities.h"
14#include "NVVMProperties.h"
16#include "llvm/IR/Attributes.h"
17#include "llvm/IR/DataLayout.h"
18#include "llvm/IR/Function.h"
21#include <algorithm>
22
23using namespace llvm;
24
26 "nvptx-force-min-byval-param-align", cl::Hidden,
27 cl::desc("NVPTX Specific: force 4-byte minimal alignment for byval"
28 " params of device functions."),
29 cl::init(false));
30
34
36 auto TotalWidth = Mem->getMemoryVT().getSizeInBits();
37 auto NumElts = Mem->getNumValues() - 1;
38 auto ElementBitWidth = TotalWidth / NumElts;
39 assert(isPowerOf2_32(ElementBitWidth) && ElementBitWidth >= 8 &&
40 ElementBitWidth <= 128 && TotalWidth <= 256 &&
41 "Invalid width for load");
42 return ElementBitWidth;
43}
44
46 // Capping the alignment to 128 bytes as that is the maximum alignment
47 // supported by PTX.
48 return std::min(Align(128), DL.getABITypeAlign(ArgTy));
49}
50
52 // Old ptx versions have a bug. When PTX code takes address of
53 // byval parameter with alignment < 4, ptxas generates code to
54 // spill argument into memory. Alas on sm_50+ ptxas generates
55 // SASS code that fails with misaligned access. To work around
56 // the problem, make sure that we align byval parameters by at
57 // least 4. This bug seems to be fixed at least starting from
58 // ptxas > 9.0.
59 // TODO: remove this after verifying the bug is not reproduced
60 // on non-deprecated ptxas versions.
61 const bool ShouldForceMinAlign =
63 return ShouldForceMinAlign ? Align(4) : Align(1);
64}
65
67 unsigned AttrIdx, const DataLayout &DL) {
68 return std::max(getPTXParamAlign(F, ArgTy, AttrIdx, DL),
70}
71
73 unsigned AttrIdx, const DataLayout &DL) {
74 Align ParamAlign = getPTXParamAlign(CB, ArgTy, AttrIdx, DL);
75
76 // For an indirect call getPTXParamAlign can't see the call's own byval
77 // alignment, so fold it in.
78 if (CB && AttrIdx >= AttributeList::FirstArgIndex)
79 ParamAlign = std::max(
80 ParamAlign,
81 CB->getParamAlign(AttrIdx - AttributeList::FirstArgIndex).valueOrOne());
82
83 return std::max(ParamAlign, getByValParamAlignFloor(
84 CB ? CB->getCalledFunction() : nullptr));
85}
86
87Align llvm::getPTXParamAlign(const Function *F, Type *Ty, unsigned AttrIdx,
88 const DataLayout &DL) {
89 if (F)
90 if (MaybeAlign StackAlign = getStackAlign(*F, AttrIdx))
91 return StackAlign.value();
92
93 Align TypeAlign = getPTXParamTypeAlign(Ty, DL);
94 if (F && AttrIdx >= AttributeList::FirstArgIndex) {
95 unsigned ArgNo = AttrIdx - AttributeList::FirstArgIndex;
96 if (F->getAttributes().hasParamAttr(ArgNo, Attribute::ByVal))
97 return std::max(TypeAlign, F->getParamAlign(ArgNo).valueOrOne());
98 }
99 return TypeAlign;
100}
101
102Align llvm::getPTXParamAlign(const CallBase *CB, Type *Ty, unsigned Idx,
103 const DataLayout &DL) {
104 if (CB)
105 if (MaybeAlign StackAlign = getStackAlign(*CB, Idx))
106 return StackAlign.value();
107
108 // Otherwise resolve the direct callee and use its parameter alignment.
109 const Function *DirectCallee = CB ? CB->getCalledFunction() : nullptr;
110 if (!DirectCallee && CB)
111 DirectCallee = getMaybeBitcastedCallee(CB);
112
113 return getPTXParamAlign(DirectCallee, Ty, Idx, DL);
114}
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...
#define F(x, y, z)
Definition MD5.cpp:54
static Align getByValParamAlignFloor(const Function *F)
static cl::opt< bool > ForceMinByValParamAlign("nvptx-force-min-byval-param-align", cl::Hidden, cl::desc("NVPTX Specific: force 4-byte minimal alignment for byval" " params of device functions."), cl::init(false))
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Value * getCalledOperand() const
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
This is an abstract virtual class for memory operations.
EVT getMemoryVT() const
Return the type of the in-memory value.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:713
initializer< Ty > init(const Ty &Val)
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 ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
Align getPTXParamTypeAlign(Type *ArgTy, const DataLayout &DL)
ABI alignment of ArgTy in .param space, capped at the PTX maximum of 128.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
Align getPTXParamAlign(const Function *F, Type *Ty, unsigned AttrIdx, const DataLayout &DL)
Alignment for a function parameter or return value at AttributeList index AttrIdx (FirstArgIndex + ar...
bool isKernelFunction(const Function &F)
Function * getMaybeBitcastedCallee(const CallBase *CB)
MaybeAlign getStackAlign(const Function &F, unsigned Index)
unsigned getFromTypeWidthForLoad(const MemSDNode *Mem)
The bit-width of a single element loaded by Mem, i.e.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition Alignment.h:130