1//===-- NVPTXUtilities - Utilities -----------------------------*- C++ -*-====//
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 the declaration of the NVVM specific utility functions.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_NVPTX_NVPTXUTILITIES_H
14#define LLVM_LIB_TARGET_NVPTX_NVPTXUTILITIES_H
15
16#include "NVPTX.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/StringExtras.h"
19#include "llvm/CodeGen/ValueTypes.h"
20#include "llvm/IR/CallingConv.h"
21#include "llvm/IR/Function.h"
22#include "llvm/IR/GlobalVariable.h"
23#include "llvm/IR/IntrinsicInst.h"
24#include "llvm/IR/Value.h"
25#include "llvm/Support/Alignment.h"
26#include "llvm/Support/FormatVariadic.h"
27#include <cstdarg>
28#include <set>
29#include <string>
30#include <vector>
31
32namespace llvm {
33
34class TargetMachine;
35
36void clearAnnotationCache(const Module *);
37
38bool isTexture(const Value &);
39bool isSurface(const Value &);
40bool isSampler(const Value &);
41bool isImage(const Value &);
42bool isImageReadOnly(const Value &);
43bool isImageWriteOnly(const Value &);
44bool isImageReadWrite(const Value &);
45bool isManaged(const Value &);
46
47StringRef getTextureName(const Value &);
48StringRef getSurfaceName(const Value &);
49StringRef getSamplerName(const Value &);
50
51SmallVector<unsigned, 3> getMaxNTID(const Function &);
52SmallVector<unsigned, 3> getReqNTID(const Function &);
53SmallVector<unsigned, 3> getClusterDim(const Function &);
54
55std::optional<uint64_t> getOverallMaxNTID(const Function &);
56std::optional<uint64_t> getOverallReqNTID(const Function &);
57std::optional<uint64_t> getOverallClusterRank(const Function &);
58
59std::optional<unsigned> getMaxClusterRank(const Function &);
60std::optional<unsigned> getMinCTASm(const Function &);
61std::optional<unsigned> getMaxNReg(const Function &);
62
63inline bool isKernelFunction(const Function &F) {
64 return F.getCallingConv() == CallingConv::PTX_Kernel;
65}
66
67bool isParamGridConstant(const Argument &);
68
69inline MaybeAlign getAlign(const Function &F, unsigned Index) {
70 return F.getAttributes().getAttributes(Index).getStackAlignment();
71}
72
73MaybeAlign getAlign(const CallInst &, unsigned);
74Function *getMaybeBitcastedCallee(const CallBase *CB);
75
76// PTX ABI requires all scalar argument/return values to have
77// bit-size as a power of two of at least 32 bits.
78inline unsigned promoteScalarArgumentSize(unsigned size) {
79 if (size <= 32)
80 return 32;
81 if (size <= 64)
82 return 64;
83 return size;
84}
85
86bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM);
87
88inline bool Isv2x16VT(EVT VT) {
89 return (VT == MVT::v2f16 || VT == MVT::v2bf16 || VT == MVT::v2i16);
90}
91
92inline bool shouldPassAsArray(Type *Ty) {
93 return Ty->isAggregateType() || Ty->isVectorTy() ||
94 Ty->getScalarSizeInBits() == 128 || Ty->isHalfTy() || Ty->isBFloatTy();
95}
96
97namespace NVPTX {
98inline std::string getValidPTXIdentifier(StringRef Name) {
99 std::string ValidName;
100 ValidName.reserve(res_arg: Name.size() + 4);
101 for (char C : Name)
102 // While PTX also allows '%' at the start of identifiers, LLVM will throw a
103 // fatal error for '%' in symbol names in MCSymbol::print. Exclude for now.
104 if (isAlnum(C) || C == '_' || C == '$')
105 ValidName.push_back(c: C);
106 else
107 ValidName.append(l: {'_', '$', '_'});
108
109 return ValidName;
110}
111
112inline std::string OrderingToString(Ordering Order) {
113 switch (Order) {
114 case Ordering::NotAtomic:
115 return "NotAtomic";
116 case Ordering::Relaxed:
117 return "Relaxed";
118 case Ordering::Acquire:
119 return "Acquire";
120 case Ordering::Release:
121 return "Release";
122 case Ordering::AcquireRelease:
123 return "AcquireRelease";
124 case Ordering::SequentiallyConsistent:
125 return "SequentiallyConsistent";
126 case Ordering::Volatile:
127 return "Volatile";
128 case Ordering::RelaxedMMIO:
129 return "RelaxedMMIO";
130 }
131 report_fatal_error(reason: formatv(Fmt: "Unknown NVPTX::Ordering \"{}\".",
132 Vals: static_cast<OrderingUnderlyingType>(Order)));
133}
134
135inline raw_ostream &operator<<(raw_ostream &O, Ordering Order) {
136 O << OrderingToString(Order);
137 return O;
138}
139
140inline std::string ScopeToString(Scope S) {
141 switch (S) {
142 case Scope::Thread:
143 return "Thread";
144 case Scope::System:
145 return "System";
146 case Scope::Block:
147 return "Block";
148 case Scope::Cluster:
149 return "Cluster";
150 case Scope::Device:
151 return "Device";
152 }
153 report_fatal_error(reason: formatv(Fmt: "Unknown NVPTX::Scope \"{}\".",
154 Vals: static_cast<ScopeUnderlyingType>(S)));
155}
156
157inline raw_ostream &operator<<(raw_ostream &O, Scope S) {
158 O << ScopeToString(S);
159 return O;
160}
161
162inline std::string AddressSpaceToString(AddressSpace A) {
163 switch (A) {
164 case AddressSpace::Generic:
165 return "generic";
166 case AddressSpace::Global:
167 return "global";
168 case AddressSpace::Const:
169 return "const";
170 case AddressSpace::Shared:
171 return "shared";
172 case AddressSpace::SharedCluster:
173 return "shared::cluster";
174 case AddressSpace::Param:
175 return "param";
176 case AddressSpace::Local:
177 return "local";
178 }
179 report_fatal_error(reason: formatv(Fmt: "Unknown NVPTX::AddressSpace \"{}\".",
180 Vals: static_cast<AddressSpaceUnderlyingType>(A)));
181}
182
183inline raw_ostream &operator<<(raw_ostream &O, AddressSpace A) {
184 O << AddressSpaceToString(A);
185 return O;
186}
187
188} // namespace NVPTX
189} // namespace llvm
190
191#endif
192