OpenVDB: Types.h Source File

OpenVDB 8.0.0

ax/openvdb_ax/codegen/Types.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
10
11 #ifndef OPENVDB_AX_CODEGEN_TYPES_HAS_BEEN_INCLUDED
12 #define OPENVDB_AX_CODEGEN_TYPES_HAS_BEEN_INCLUDED
13
14 #include "../ast/Tokens.h"
15 #include "../Exceptions.h"
16 #include "../compiler/CustomData.h" // for AXString
17
18 #include <openvdb/version.h>
19 #include <openvdb/Types.h>
20 #include <openvdb/math/Mat3.h>
21 #include <openvdb/math/Mat4.h>
22 #include <openvdb/math/Vec3.h>
23
24 #include <llvm/IR/Constants.h>
25 #include <llvm/IR/IRBuilder.h>
26 #include <llvm/IR/LLVMContext.h>
27
28 #include <type_traits>
29
30 namespace openvdb {
31 OPENVDB_USE_VERSION_NAMESPACE
32 namespace OPENVDB_VERSION_NAME {
33
34 namespace ax {
35 namespace codegen {
36
37 template <size_t Bits> struct int_t;
38 template <> struct int_t<8> { using type = int8_t; };
39 template <> struct int_t<16> { using type = int16_t; };
40 template <> struct int_t<32> { using type = int32_t; };
41 template <> struct int_t<64> { using type = int64_t; };
42
53 template <typename T>
54 struct LLVMType
55 {
56 static_assert(!std::is_reference<T>::value,
57 "Reference types/arguments are not supported for automatic "
58 "LLVM Type conversion. Use pointers instead.");
59 static_assert(!std::is_class<T>::value,
60 "Object types/arguments are not supported for automatic "
61 "LLVM Type conversion.");
62
65 static inline llvm::Type*
66 get(llvm::LLVMContext& C)
67 {
68 // @note bools always treated as i1 values as the constants
69 // true and false from the IRBuilder are i1
70 if (std::is_same<T, bool>::value) {
71 return llvm::Type::getInt1Ty(C);
72 }
73
74 #if LLVM_VERSION_MAJOR > 6
75 return llvm::Type::getScalarTy<T>(C);
76 #else
77 int bits = sizeof(T) * CHAR_BIT;
78 if (std::is_integral<T>::value) {
79 return llvm::Type::getIntNTy(C, bits);
80 }
81 else if (std::is_floating_point<T>::value) {
82 switch (bits) {
83 case 32: return llvm::Type::getFloatTy(C);
84 case 64: return llvm::Type::getDoubleTy(C);
85 }
86 }
87 OPENVDB_THROW(AXCodeGenError, "LLVMType called with an unsupported type \"" +
88 std::string(typeNameAsString<T>()) + "\".");
89 #endif
90 }
91
97 static inline llvm::Constant*
98 get(llvm::LLVMContext& C, const T V)
99 {
100 llvm::Type* type = LLVMType<T>::get(C);
101 llvm::Constant* constant = nullptr;
102
103 if (std::is_floating_point<T>::value) {
104 assert(llvm::ConstantFP::isValueValidForType(type,
105 llvm::APFloat(static_cast<typename std::conditional
106 <std::is_floating_point<T>::value, T, double>::type>(V))));
107 constant = llvm::ConstantFP::get(type, static_cast<double>(V));
108 }
109 else if (std::is_integral<T>::value) {
110 const constexpr bool isSigned = std::is_signed<T>::value;
111 assert((isSigned && llvm::ConstantInt::isValueValidForType(type, static_cast<int64_t>(V))) ||
112 (!isSigned && llvm::ConstantInt::isValueValidForType(type, static_cast<uint64_t>(V))));
113 constant = llvm::ConstantInt::get(type, static_cast<uint64_t>(V), isSigned);
114 }
115
116 assert(constant);
117 return constant;
118 }
119
124 static inline llvm::Constant*
125 get(llvm::LLVMContext& C, const T* const V)
126 {
127 return LLVMType<uintptr_t>::get(C,
128 reinterpret_cast<uintptr_t>(V));
129 }
130 };
131
132 template <typename T, size_t S>
133 struct LLVMType<T[S]>
134 {
135 static_assert(S != 0,
136 "Zero size array types are not supported for automatic LLVM "
137 "Type conversion");
138
139 static inline llvm::Type*
140 get(llvm::LLVMContext& C) {
141 return llvm::ArrayType::get(LLVMType<T>::get(C), S);
142 }
143 static inline llvm::Constant*
144 get(llvm::LLVMContext& C, const T(&array)[S]) {
145 return llvm::ConstantDataArray::get(C, array);
146 }
147 static inline llvm::Constant*
148 get(llvm::LLVMContext& C, const T(*array)[S])
149 {
150 return LLVMType<uintptr_t>::get(C,
151 reinterpret_cast<uintptr_t>(array));
152 }
153 };
154
155 template <typename T>
156 struct LLVMType<T*>
157 {
158 static inline llvm::PointerType*
159 get(llvm::LLVMContext& C) {
160 return LLVMType<T>::get(C)->getPointerTo(0);
161 }
162 };
163
164 template <>
165 struct LLVMType<char> : public LLVMType<uint8_t>
166 {
167 static_assert(std::is_same<uint8_t, unsigned char>::value,
168 "This library requires std::uint8_t to be implemented as unsigned char.");
169 };
170
171 template <>
172 struct LLVMType<AXString>
173 {
174 static inline llvm::StructType*
175 get(llvm::LLVMContext& C) {
176 const std::vector<llvm::Type*> types {
177 LLVMType<char*>::get(C), // array
178 LLVMType<AXString::SizeType>::get(C) // size
179 };
180 return llvm::StructType::get(C, types);
181 }
182 static inline llvm::Value*
183 get(llvm::LLVMContext& C, llvm::Constant* string, llvm::Constant* size) {
184 return llvm::ConstantStruct::get(LLVMType<AXString>::get(C), {string, size});
185 }
191 static inline llvm::Value*
192 get(llvm::LLVMContext& C, const std::string& string, llvm::IRBuilder<>& builder) {
193 llvm::Constant* constant =
194 llvm::ConstantDataArray::getString(C, string, /*terminator*/true);
195 llvm::Constant* size = llvm::cast<llvm::Constant>
196 (LLVMType<AXString::SizeType>::get(C, static_cast<AXString::SizeType>(string.size())));
197 llvm::Value* zero = LLVMType<int32_t>::get(C, 0);
198 llvm::Value* args[] = { zero, zero };
199 constant = llvm::cast<llvm::Constant>
200 (builder.CreateInBoundsGEP(constant->getType(), constant, args));
201 return LLVMType<AXString>::get(C, constant, size);
202 }
203 static inline llvm::Constant*
204 get(llvm::LLVMContext& C, const AXString* const string)
205 {
206 return LLVMType<uintptr_t>::get(C,
207 reinterpret_cast<uintptr_t>(string));
208 }
209 };
210
211 template <>
212 struct LLVMType<void>
213 {
214 static inline llvm::Type*
215 get(llvm::LLVMContext& C) {
216 return llvm::Type::getVoidTy(C);
217 }
218 };
219
221 template <> struct LLVMType<void*> : public LLVMType<int_t<sizeof(void*)>::type*> {};
222
223 template <typename T> struct LLVMType<const T> : public LLVMType<T> {};
224 template <typename T> struct LLVMType<const T*> : public LLVMType<T*> {};
225
237 template <typename T1, typename T2>
238 struct AliasTypeMap
239 {
240 using LLVMTypeT = LLVMType<T2>;
241
242 static_assert(sizeof(T1) == sizeof(T2),
243 "T1 differs in size to T2 during alias mapping. Types should have "
244 "the same memory layout.");
245 static_assert(std::is_standard_layout<T1>::value,
246 "T1 in instantiation of an AliasTypeMap does not have a standard layout. "
247 "This will most likely cause undefined behaviour when attempting to map "
248 "T1->T2.");
249
250 static inline llvm::Type*
251 get(llvm::LLVMContext& C) {
252 return LLVMTypeT::get(C);
253 }
254 static inline llvm::Constant*
255 get(llvm::LLVMContext& C, const T1& value) {
256 return LLVMTypeT::get(C, reinterpret_cast<const T2&>(value));
257 }
258 static inline llvm::Constant*
259 get(llvm::LLVMContext& C, const T1* const value) {
260 return LLVMTypeT::get(C, reinterpret_cast<const T2* const>(value));
261 }
262 };
263
266 template <typename T> struct LLVMType<math::Vec2<T>> : public AliasTypeMap<math::Vec2<T>, T[2]> {};
267 template <typename T> struct LLVMType<math::Vec3<T>> : public AliasTypeMap<math::Vec3<T>, T[3]> {};
268 template <typename T> struct LLVMType<math::Vec4<T>> : public AliasTypeMap<math::Vec4<T>, T[4]> {};
269 template <typename T> struct LLVMType<math::Mat3<T>> : public AliasTypeMap<math::Mat3<T>, T[9]> {};
270 template <typename T> struct LLVMType<math::Mat4<T>> : public AliasTypeMap<math::Mat4<T>, T[16]> {};
271
274
278 template<typename SignatureT>
279 struct FunctionTraits;
280
281 template<typename R, typename... Args>
282 struct FunctionTraits<R(&)(Args...)> : public FunctionTraits<R(Args...)> {};
283
284 template<typename R, typename... Args>
285 struct FunctionTraits<R(*)(Args...)> : public FunctionTraits<R(Args...)> {};
286
287 template<typename ReturnT, typename ...Args>
288 struct FunctionTraits<ReturnT(Args...)>
289 {
290 using ReturnType = ReturnT;
291 using SignatureType = ReturnType(Args...);
292 static const size_t N_ARGS = sizeof...(Args);
293
294 template <size_t I>
295 struct Arg
296 {
297 public:
298 static_assert(I < N_ARGS,
299 "Invalid index specified for function argument access");
300 using Type = typename std::tuple_element<I, std::tuple<Args...>>::type;
301 static_assert(!std::is_reference<Type>::value,
302 "Reference types/arguments are not supported for automatic "
303 "LLVM Type conversion. Use pointers instead.");
304 };
305 };
306
309
315 template <typename T>
316 inline llvm::Constant*
317 llvmConstant(const T t, llvm::Type* type)
318 {
319 static_assert(std::is_floating_point<T>::value || std::is_integral<T>::value,
320 "T type for llvmConstant must be a floating point or integral type.");
321
322 if (type->isIntegerTy()) {
323 return llvm::ConstantInt::get(type, static_cast<uint64_t>(t), /*signed*/true);
324 }
325 else {
326 assert(type->isFloatingPointTy());
327 return llvm::ConstantFP::get(type, static_cast<double>(t));
328 }
329 }
330
335 llvm::IntegerType* llvmIntType(const uint32_t size, llvm::LLVMContext& C);
336
341 llvm::Type* llvmFloatType(const uint32_t size, llvm::LLVMContext& C);
342
350 llvm::Type* llvmTypeFromToken(const ast::tokens::CoreType& type, llvm::LLVMContext& C);
351
357 ast::tokens::CoreType tokenFromLLVMType(const llvm::Type* type);
358
359 } // namespace codegen
360 } // namespace ax
361 } // namespace OPENVDB_VERSION_NAME
362 } // namespace openvdb
363
364 #endif // OPENVDB_AX_CODEGEN_TYPES_HAS_BEEN_INCLUDED
365
Types.h
openvdb::v8_2::math::Mat3
3x3 matrix class.
Definition: Mat3.h:29
openvdb::v8_2::ax::codegen::LLVMType::get
static llvm::Constant * get(llvm::LLVMContext &C, const T *const V)
Return an LLVM constant which holds an uintptr_t, representing the current address of the given value...
Definition: ax/openvdb_ax/codegen/Types.h:125
openvdb::v8_2::ax::codegen::FunctionTraits
Templated function traits which provides compile-time index access to the types of the function signa...
Definition: ax/openvdb_ax/codegen/Types.h:279
openvdb::v8_2::ax::codegen::int_t< 16 >::type
int16_t type
Definition: ax/openvdb_ax/codegen/Types.h:39
openvdb::v8_2::ax::codegen::LLVMType< T[S]>::get
static llvm::Constant * get(llvm::LLVMContext &C, const T(*array)[S])
Definition: ax/openvdb_ax/codegen/Types.h:148
openvdb::v8_2::ax::codegen::LLVMType< AXString >::get
static llvm::Constant * get(llvm::LLVMContext &C, const AXString *const string)
Definition: ax/openvdb_ax/codegen/Types.h:204
openvdb::v8_2::ax::codegen::LLVMType< T * >::get
static llvm::PointerType * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:159
openvdb::v8_2::ax::AXString
The backend representation of strings in AX. This is also how strings are passed from the AX code gen...
Definition: CustomData.h:31
openvdb::v8_2::ax::codegen::LLVMType< void >::get
static llvm::Type * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:215
openvdb::v8_2::ax::codegen::llvmFloatType
llvm::Type * llvmFloatType(const uint32_t size, llvm::LLVMContext &C)
Returns an llvm floating point Type given a requested size and context.
openvdb::v8_2::ax::codegen::AliasTypeMap::get
static llvm::Constant * get(llvm::LLVMContext &C, const T1 *const value)
Definition: ax/openvdb_ax/codegen/Types.h:259
openvdb::v8_2::math::Vec4
Definition: Vec4.h:25
openvdb::v8_2::ax::codegen::llvmTypeFromToken
llvm::Type * llvmTypeFromToken(const ast::tokens::CoreType &type, llvm::LLVMContext &C)
Returns an llvm type representing a type defined by a string.
openvdb::v8_2::ax::codegen::llvmConstant
llvm::Constant * llvmConstant(const T t, llvm::Type *type)
Returns an llvm Constant holding a scalar value.
Definition: ax/openvdb_ax/codegen/Types.h:317
openvdb::v8_2::ax::codegen::FunctionTraits< ReturnT(Args...)>::Arg::Type
typename std::tuple_element< I, std::tuple< Args... > >::type Type
Definition: ax/openvdb_ax/codegen/Types.h:300
version.h
Library and file format version numbers.
openvdb::v8_2::AXCodeGenError
Definition: ax/openvdb_ax/Exceptions.h:36
openvdb::v8_2::ax::codegen::llvmIntType
llvm::IntegerType * llvmIntType(const uint32_t size, llvm::LLVMContext &C)
Returns an llvm IntegerType given a requested size and context.
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
openvdb::v8_2::math::Vec3
Definition: Vec3.h:24
openvdb::v8_2::ax::codegen::AliasTypeMap
Alias mapping between two types, a frontend type T1 and a backend type T2. This class is the intended...
Definition: ax/openvdb_ax/codegen/Types.h:239
openvdb::v8_2::ax::codegen::LLVMType< AXString >::get
static llvm::Value * get(llvm::LLVMContext &C, const std::string &string, llvm::IRBuilder<> &builder)
Definition: ax/openvdb_ax/codegen/Types.h:192
openvdb::v8_2::ax::codegen::FunctionTraits< ReturnT(Args...)>::SignatureType
ReturnType(Args...) SignatureType
Definition: ax/openvdb_ax/codegen/Types.h:291
Vec3.h
openvdb::v8_2::ax::codegen::int_t< 64 >::type
int64_t type
Definition: ax/openvdb_ax/codegen/Types.h:41
openvdb::v8_2::ax::codegen::LLVMType< AXString >::get
static llvm::Value * get(llvm::LLVMContext &C, llvm::Constant *string, llvm::Constant *size)
Definition: ax/openvdb_ax/codegen/Types.h:183
openvdb::v8_2::ax::codegen::LLVMType< T[S]>::get
static llvm::Constant * get(llvm::LLVMContext &C, const T(&array)[S])
Definition: ax/openvdb_ax/codegen/Types.h:144
openvdb::v8_2::ax::codegen::tokenFromLLVMType
ast::tokens::CoreType tokenFromLLVMType(const llvm::Type *type)
Return a corresponding AX token which represents the given LLVM Type.
openvdb::v8_2::ax::codegen::LLVMType< T * >
Definition: ax/openvdb_ax/codegen/Types.h:157
Mat4.h
openvdb::v8_2::ax::codegen::AliasTypeMap::get
static llvm::Type * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:251
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:153
openvdb::v8_2::ax::codegen::int_t< 8 >::type
int8_t type
Definition: ax/openvdb_ax/codegen/Types.h:38
Mat3.h
openvdb::v8_2::ax::ast::tokens::CoreType
CoreType
Definition: Tokens.h:32
openvdb::v8_2::ax::codegen::LLVMType< AXString >::get
static llvm::StructType * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:175
openvdb::v8_2::ax::codegen::AliasTypeMap::get
static llvm::Constant * get(llvm::LLVMContext &C, const T1 &value)
Definition: ax/openvdb_ax/codegen/Types.h:255
openvdb::v8_2::math::Mat4
4x4 -matrix class.
Definition: Mat4.h:24
openvdb::v8_2::ax::AXString::SizeType
std::allocator< char >::size_type SizeType
Definition: CustomData.h:33
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:101
openvdb::v8_2::ax::codegen::FunctionTraits< ReturnT(Args...)>::ReturnType
ReturnT ReturnType
Definition: ax/openvdb_ax/codegen/Types.h:290
openvdb::v8_2::ax::codegen::LLVMType< T[S]>::get
static llvm::Type * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:140
openvdb
Definition: openvdb/Exceptions.h:13
openvdb::v8_2::math::Vec2
Definition: Vec2.h:24
openvdb::v8_2::ax::codegen::LLVMType::get
static llvm::Type * get(llvm::LLVMContext &C)
Return an LLVM type which represents T.
Definition: ax/openvdb_ax/codegen/Types.h:66
openvdb::v8_2::ax::codegen::LLVMType
LLVM type mapping from pod types.
Definition: ax/openvdb_ax/codegen/Types.h:55
openvdb::v8_2::ax::codegen::LLVMType::get
static llvm::Constant * get(llvm::LLVMContext &C, const T V)
Return an LLVM constant Value which represents T value.
Definition: ax/openvdb_ax/codegen/Types.h:98
openvdb::v8_2::ax::codegen::int_t
Definition: ax/openvdb_ax/codegen/Types.h:37
openvdb::v8_2::ax::codegen::int_t< 32 >::type
int32_t type
Definition: ax/openvdb_ax/codegen/Types.h:40