LLVM 24.0.0git
SPIRV.cpp
Go to the documentation of this file.
1//===- SPIRV.cpp - SPIR-V ABI Implementation -----------------------------===//
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
11#include "llvm/ABI/TargetInfo.h"
12#include "llvm/ABI/Types.h"
13#include "llvm/IR/CallingConv.h"
16
17namespace llvm::abi {
18
19// The default classification applies, except for SPIR_KERNEL arguments, which
20// SPIR-V restricts in which address spaces they may point to and requires to be
21// copied when they are aggregates.
22class SPIRVTargetInfo final : public DefaultTargetInfo {
23private:
24 ABICompatInfo CompatInfo;
25
26 /// Target address space of the language's default address space.
27 unsigned DefaultAddrSpace;
28
29 /// Pass kernel aggregates byval. Set by the front end for device
30 /// compilations.
31 bool KernelPassAggregatesIndirect;
32
33 ArgInfo classifyKernelArgumentType(const Type *ArgTy) const {
34 // Kernel arguments may not be default address space pointers, so pass them
35 // as CrossWorkgroup pointers. An atomic pointer of the same size is passed
36 // as the pointer itself.
37 const Type *Ty = ArgTy;
38 if (const auto *AT = dyn_cast<AtomicType>(Ty);
39 AT && AT->getSizeInBits() == AT->getValueType()->getSizeInBits())
40 Ty = AT->getValueType();
41 if (const auto *PtrTy = dyn_cast<PointerType>(Ty);
42 PtrTy && PtrTy->getAddrSpace() == DefaultAddrSpace) {
43 const Type *Coerced = TB.getPointerType(
44 PtrTy->getSizeInBits().getFixedValue(), PtrTy->getAlignment(),
45 SPIRVAS::CrossWorkgroup, /*HasAddressSpaceQualifier=*/true);
46 return ArgInfo::getDirect(Coerced, /*Offset=*/0, /*Align=*/std::nullopt,
47 /*CanBeFlattened=*/false);
48 }
49
50 // Force copying aggregate type in kernel arguments by value. This is
51 // required for the object copied to be valid on the device. TODO:
52 // hardcoding to 0 should be revisited if HIPSPV / byval starts making use
53 // of the AS of an indirect arg.
54 if (KernelPassAggregatesIndirect && isAggregateTypeForABI(ArgTy))
55 return getNaturalAlignIndirect(ArgTy, /*AddrSpace=*/0, /*ByVal=*/true);
56
57 return classifyArgumentType(ArgTy);
58 }
59
60public:
61 SPIRVTargetInfo(TypeBuilder &Builder, unsigned DefaultAddrSpace,
62 bool KernelPassAggregatesIndirect)
63 : DefaultTargetInfo(Builder), DefaultAddrSpace(DefaultAddrSpace),
64 KernelPassAggregatesIndirect(KernelPassAggregatesIndirect) {}
65
66 const ABICompatInfo &getABICompatInfo() const override { return CompatInfo; }
67
68 bool hasInt128Type() const override { return false; }
69
70 // A record that cannot be copied is constructed in place, so its sret
71 // pointer follows the default address space like a "this" pointer.
72 unsigned getSRetAddrSpace() const override { return DefaultAddrSpace; }
73
74 void computeInfo(FunctionInfo &FI) const override {
75 // The logic is the same as in DefaultTargetInfo, except for kernel
76 // arguments.
79
80 bool IsKernel = FI.getCallingConvention() == CallingConv::SPIR_KERNEL;
81 for (auto &I : FI.arguments())
82 I.Info = IsKernel ? classifyKernelArgumentType(I.ABIType)
83 : classifyArgumentType(I.ABIType);
84 }
85};
86
87std::unique_ptr<TargetInfo>
88createSPIRVTargetInfo(TypeBuilder &TB, unsigned DefaultAddrSpace,
89 bool KernelPassAggregatesIndirect) {
90 return std::make_unique<SPIRVTargetInfo>(TB, DefaultAddrSpace,
91 KernelPassAggregatesIndirect);
92}
93
94} // namespace llvm::abi
Default ABI classification shared by targets without special rules.
#define I(x, y, z)
Definition MD5.cpp:57
SPIR-V address space definition.
Target-specific ABI information and factory functions.
Helper class to encapsulate information about how a specific type should be passed to or returned fro...
static ArgInfo getDirect(const Type *T=nullptr, unsigned Offset=0, MaybeAlign Align=std::nullopt, bool CanBeFlattened=true)
Self-consistent classification that conforms to no particular ABI.
ArgInfo classifyArgumentType(const Type *Ty) const
ArgInfo classifyReturnType(const Type *RetTy) const
ArrayRef< ArgEntry > arguments() const
CallingConv::ID getCallingConvention() const
const Type * getReturnType() const
unsigned getSRetAddrSpace() const override
Address space of the sret pointer of a record that cannot be passed in registers (e....
Definition SPIRV.cpp:72
bool hasInt128Type() const override
Whether the target has a 128-bit integer type. Default true.
Definition SPIRV.cpp:68
const ABICompatInfo & getABICompatInfo() const override
Return this target's ABI compatibility flags.
Definition SPIRV.cpp:66
SPIRVTargetInfo(TypeBuilder &Builder, unsigned DefaultAddrSpace, bool KernelPassAggregatesIndirect)
Definition SPIRV.cpp:61
void computeInfo(FunctionInfo &FI) const override
Populate FI with the target's ABI-lowering decisions for each argument and return value.
Definition SPIRV.cpp:74
LLVM_ABI bool maybeCommonClassifyReturnType(FunctionInfo &FI) const
Apply rules for classifying return types that are common to all targets.
LLVM_ABI bool isAggregateTypeForABI(const Type *Ty) const
TypeBuilder & TB
Definition TargetInfo.h:67
LLVM_ABI ArgInfo getNaturalAlignIndirect(const Type *Ty, unsigned AddrSpace, bool ByVal=true) const
TypeBuilder manages the lifecycle of ABI types using bump pointer allocation.
Definition Types.h:490
Represents the ABI-specific view of a type in LLVM.
Definition Types.h:48
This file defines the type system for the LLVMABI library, which mirrors ABI-relevant aspects of fron...
@ SPIR_KERNEL
Used for SPIR kernel functions.
LLVM_ABI std::unique_ptr< TargetInfo > createSPIRVTargetInfo(TypeBuilder &TB, unsigned DefaultAddrSpace, bool KernelPassAggregatesIndirect=false)
Definition SPIRV.cpp:88
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
Flags controlling ABI compatibility behaviour that applies to every target.
Definition TargetInfo.h:43