1 //===-- AMDGPULibFunc.h ----------------------------------------*- C++ -*--===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef _AMDGPU_LIBFUNC_H_
10 #define _AMDGPU_LIBFUNC_H_
12 #include "llvm/ADT/StringRef.h"
23 class AMDGPULibFuncBase
{
28 // IMPORTANT: enums below should go in ascending by 1 value order
29 // because they are used as indexes in the mangling rules table.
30 // don't use explicit value assignment.
32 // There are two types of library functions: those with mangled
33 // name and those with unmangled name. The enums for the library
34 // functions with mangled name are defined before enums for the
35 // library functions with unmangled name. The enum for the last
36 // library function with mangled name is EI_LAST_MANGLED.
38 // Library functions with mangled name.
50 EI_ASYNC_WORK_GROUP_COPY
,
51 EI_ASYNC_WORK_GROUP_STRIDED_COPY
,
103 EI_GET_IMAGE_ARRAY_SIZE
,
104 EI_GET_IMAGE_CHANNEL_DATA_TYPE
,
105 EI_GET_IMAGE_CHANNEL_ORDER
,
109 EI_GET_PIPE_MAX_PACKETS
,
110 EI_GET_PIPE_NUM_PACKETS
,
160 EI_RESERVE_READ_PIPE
,
161 EI_RESERVE_WRITE_PIPE
,
180 EI_SUB_GROUP_BROADCAST
,
181 EI_SUB_GROUP_COMMIT_READ_PIPE
,
182 EI_SUB_GROUP_COMMIT_WRITE_PIPE
,
183 EI_SUB_GROUP_REDUCE_ADD
,
184 EI_SUB_GROUP_REDUCE_MAX
,
185 EI_SUB_GROUP_REDUCE_MIN
,
186 EI_SUB_GROUP_RESERVE_READ_PIPE
,
187 EI_SUB_GROUP_RESERVE_WRITE_PIPE
,
188 EI_SUB_GROUP_SCAN_EXCLUSIVE_ADD
,
189 EI_SUB_GROUP_SCAN_EXCLUSIVE_MAX
,
190 EI_SUB_GROUP_SCAN_EXCLUSIVE_MIN
,
191 EI_SUB_GROUP_SCAN_INCLUSIVE_ADD
,
192 EI_SUB_GROUP_SCAN_INCLUSIVE_MAX
,
193 EI_SUB_GROUP_SCAN_INCLUSIVE_MIN
,
208 EI_WORK_GROUP_COMMIT_READ_PIPE
,
209 EI_WORK_GROUP_COMMIT_WRITE_PIPE
,
210 EI_WORK_GROUP_REDUCE_ADD
,
211 EI_WORK_GROUP_REDUCE_MAX
,
212 EI_WORK_GROUP_REDUCE_MIN
,
213 EI_WORK_GROUP_RESERVE_READ_PIPE
,
214 EI_WORK_GROUP_RESERVE_WRITE_PIPE
,
215 EI_WORK_GROUP_SCAN_EXCLUSIVE_ADD
,
216 EI_WORK_GROUP_SCAN_EXCLUSIVE_MAX
,
217 EI_WORK_GROUP_SCAN_EXCLUSIVE_MIN
,
218 EI_WORK_GROUP_SCAN_INCLUSIVE_ADD
,
219 EI_WORK_GROUP_SCAN_INCLUSIVE_MAX
,
220 EI_WORK_GROUP_SCAN_INCLUSIVE_MIN
,
237 EI_RCBRT
, /* The last library function with mangled name */
239 // Library functions with unmangled name.
263 BASE_TYPE_MASK
= 0x30,
288 ADDR_SPACE
= 0xF, // Address space takes value 0x1 ~ 0xF.
294 unsigned char ArgType
= 0;
295 unsigned char VectorSize
= 1;
296 unsigned char PtrKind
= 0;
298 unsigned char Reserved
= 0;
306 static Param
getIntN(unsigned char NumElts
) {
307 return Param
{I32
, NumElts
, 0, 0};
310 static Param
getFromTy(Type
*Ty
, bool Signed
);
312 template <typename Stream
>
313 void mangleItanium(Stream
& os
);
315 static bool isMangled(EFuncId Id
) {
316 return static_cast<unsigned>(Id
) <= static_cast<unsigned>(EI_LAST_MANGLED
);
319 static unsigned getEPtrKindFromAddrSpace(unsigned AS
) {
320 assert(((AS
+ 1) & ~ADDR_SPACE
) == 0);
324 static unsigned getAddrSpaceFromEPtrKind(unsigned Kind
) {
325 Kind
= Kind
& ADDR_SPACE
;
331 class AMDGPULibFuncImpl
: public AMDGPULibFuncBase
{
333 AMDGPULibFuncImpl() = default;
334 virtual ~AMDGPULibFuncImpl() = default;
336 /// Get unmangled name for mangled library function and name for unmangled
337 /// library function.
338 virtual std::string
getName() const = 0;
339 virtual unsigned getNumArgs() const = 0;
340 EFuncId
getId() const { return FuncId
; }
341 ENamePrefix
getPrefix() const { return FKind
; }
343 bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId
); }
345 void setId(EFuncId id
) { FuncId
= id
; }
346 virtual bool parseFuncName(StringRef
&mangledName
) = 0;
348 /// \return The mangled function name for mangled library functions
349 /// and unmangled function name for unmangled library functions.
350 virtual std::string
mangle() const = 0;
352 void setName(StringRef N
) { Name
= std::string(N
); }
353 void setPrefix(ENamePrefix pfx
) { FKind
= pfx
; }
355 virtual FunctionType
*getFunctionType(Module
&M
) const = 0;
360 ENamePrefix FKind
= NOPFX
;
363 /// Wrapper class for AMDGPULIbFuncImpl
364 class AMDGPULibFunc
: public AMDGPULibFuncBase
{
366 explicit AMDGPULibFunc() : Impl(std::unique_ptr
<AMDGPULibFuncImpl
>()) {}
367 AMDGPULibFunc(const AMDGPULibFunc
&F
);
368 /// Clone a mangled library func with the Id \p Id and argument info from \p
370 explicit AMDGPULibFunc(EFuncId Id
, const AMDGPULibFunc
&CopyFrom
);
371 explicit AMDGPULibFunc(EFuncId Id
, FunctionType
*FT
, bool SignedInts
);
373 /// Construct an unmangled library function on the fly.
374 explicit AMDGPULibFunc(StringRef FName
, FunctionType
*FT
);
376 AMDGPULibFunc
&operator=(const AMDGPULibFunc
&F
);
378 /// Get unmangled name for mangled library function and name for unmangled
379 /// library function.
380 std::string
getName() const { return Impl
->getName(); }
381 unsigned getNumArgs() const { return Impl
->getNumArgs(); }
382 EFuncId
getId() const { return Impl
->getId(); }
383 ENamePrefix
getPrefix() const { return Impl
->getPrefix(); }
384 /// Get leading parameters for mangled lib functions.
386 const Param
*getLeads() const;
388 bool isMangled() const { return Impl
->isMangled(); }
389 void setId(EFuncId Id
) { Impl
->setId(Id
); }
390 bool parseFuncName(StringRef
&MangledName
) {
391 return Impl
->parseFuncName(MangledName
);
394 // Validate the call type matches the expected libfunc type.
395 bool isCompatibleSignature(const FunctionType
*FuncTy
) const;
397 /// \return The mangled function name for mangled library functions
398 /// and unmangled function name for unmangled library functions.
399 std::string
mangle() const { return Impl
->mangle(); }
401 void setName(StringRef N
) { Impl
->setName(N
); }
402 void setPrefix(ENamePrefix PFX
) { Impl
->setPrefix(PFX
); }
404 FunctionType
*getFunctionType(Module
&M
) const {
405 return Impl
->getFunctionType(M
);
407 static Function
*getFunction(llvm::Module
*M
, const AMDGPULibFunc
&fInfo
);
409 static FunctionCallee
getOrInsertFunction(llvm::Module
*M
,
410 const AMDGPULibFunc
&fInfo
);
411 static bool parse(StringRef MangledName
, AMDGPULibFunc
&Ptr
);
414 /// Initialize as a mangled library function.
416 std::unique_ptr
<AMDGPULibFuncImpl
> Impl
;
419 class AMDGPUMangledLibFunc
: public AMDGPULibFuncImpl
{
423 explicit AMDGPUMangledLibFunc();
424 explicit AMDGPUMangledLibFunc(EFuncId id
,
425 const AMDGPUMangledLibFunc
©From
);
426 explicit AMDGPUMangledLibFunc(EFuncId id
, FunctionType
*FT
,
427 bool SignedInts
= true);
429 std::string
getName() const override
;
430 unsigned getNumArgs() const override
;
431 FunctionType
*getFunctionType(Module
&M
) const override
;
432 static StringRef
getUnmangledName(StringRef MangledName
);
434 bool parseFuncName(StringRef
&mangledName
) override
;
436 // Methods for support type inquiry through isa, cast, and dyn_cast:
437 static bool classof(const AMDGPULibFuncImpl
*F
) { return F
->isMangled(); }
439 std::string
mangle() const override
;
442 std::string
mangleNameItanium() const;
444 std::string
mangleName(StringRef Name
) const;
445 bool parseUnmangledName(StringRef MangledName
);
447 template <typename Stream
> void writeName(Stream
&OS
) const;
450 class AMDGPUUnmangledLibFunc
: public AMDGPULibFuncImpl
{
451 FunctionType
*FuncTy
;
454 explicit AMDGPUUnmangledLibFunc();
455 explicit AMDGPUUnmangledLibFunc(StringRef FName
, FunctionType
*FT
) {
456 Name
= std::string(FName
);
459 std::string
getName() const override
{ return Name
; }
460 unsigned getNumArgs() const override
;
461 FunctionType
*getFunctionType(Module
&M
) const override
{ return FuncTy
; }
463 bool parseFuncName(StringRef
&Name
) override
;
465 // Methods for support type inquiry through isa, cast, and dyn_cast:
466 static bool classof(const AMDGPULibFuncImpl
*F
) { return !F
->isMangled(); }
468 std::string
mangle() const override
{ return Name
; }
470 void setFunctionType(FunctionType
*FT
) { FuncTy
= FT
; }
473 #endif // _AMDGPU_LIBFUNC_H_