OpenVDB: Types.h Source File

OpenVDB 8.1.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 "openvdb_ax/ast/Tokens.h"
15 #include "openvdb_ax/Exceptions.h"
16 #include "String.h"
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<codegen::String>
173 {
174 static inline llvm::StructType*
175 get(llvm::LLVMContext& C) {
176 const std::vector<llvm::Type*> types {
177 LLVMType<char*>::get(C), // ptr
178 LLVMType<char[codegen::String::SSO_LENGTH]>::get(C), // SSO
179 LLVMType<int64_t>::get(C) // size
180 };
181 return llvm::StructType::get(C, types);
182 }
183 static inline llvm::Constant*
184 get(llvm::LLVMContext& C, const codegen::String* const string)
185 {
186 return LLVMType<uintptr_t>::get(C,
187 reinterpret_cast<uintptr_t>(string));
188 }
189 };
190
191 template <>
192 struct LLVMType<void>
193 {
194 static inline llvm::Type*
195 get(llvm::LLVMContext& C) {
196 return llvm::Type::getVoidTy(C);
197 }
198 };
199
201 template <> struct LLVMType<void*> : public LLVMType<int_t<sizeof(void*)>::type*> {};
202
203 template <typename T> struct LLVMType<const T> : public LLVMType<T> {};
204 template <typename T> struct LLVMType<const T*> : public LLVMType<T*> {};
205
217 template <typename T1, typename T2>
218 struct AliasTypeMap
219 {
220 using LLVMTypeT = LLVMType<T2>;
221
222 static_assert(sizeof(T1) == sizeof(T2),
223 "T1 differs in size to T2 during alias mapping. Types should have "
224 "the same memory layout.");
225 static_assert(std::is_standard_layout<T1>::value,
226 "T1 in instantiation of an AliasTypeMap does not have a standard layout. "
227 "This will most likely cause undefined behaviour when attempting to map "
228 "T1->T2.");
229
230 static inline llvm::Type*
231 get(llvm::LLVMContext& C) {
232 return LLVMTypeT::get(C);
233 }
234 static inline llvm::Constant*
235 get(llvm::LLVMContext& C, const T1& value) {
236 return LLVMTypeT::get(C, reinterpret_cast<const T2&>(value));
237 }
238 static inline llvm::Constant*
239 get(llvm::LLVMContext& C, const T1* const value) {
240 return LLVMTypeT::get(C, reinterpret_cast<const T2* const>(value));
241 }
242 };
243
246 template <typename T> struct LLVMType<math::Vec2<T>> : public AliasTypeMap<math::Vec2<T>, T[2]> {};
247 template <typename T> struct LLVMType<math::Vec3<T>> : public AliasTypeMap<math::Vec3<T>, T[3]> {};
248 template <typename T> struct LLVMType<math::Vec4<T>> : public AliasTypeMap<math::Vec4<T>, T[4]> {};
249 template <typename T> struct LLVMType<math::Mat3<T>> : public AliasTypeMap<math::Mat3<T>, T[9]> {};
250 template <typename T> struct LLVMType<math::Mat4<T>> : public AliasTypeMap<math::Mat4<T>, T[16]> {};
251
254
258 template<typename SignatureT>
259 struct FunctionTraits;
260
261 template<typename R, typename... Args>
262 struct FunctionTraits<R(&)(Args...)> : public FunctionTraits<R(Args...)> {};
263
264 template<typename R, typename... Args>
265 struct FunctionTraits<R(*)(Args...)> : public FunctionTraits<R(Args...)> {};
266
267 template<typename ReturnT, typename ...Args>
268 struct FunctionTraits<ReturnT(Args...)>
269 {
270 using ReturnType = ReturnT;
271 using SignatureType = ReturnType(Args...);
272 static const size_t N_ARGS = sizeof...(Args);
273
274 template <size_t I>
275 struct Arg
276 {
277 public:
278 static_assert(I < N_ARGS,
279 "Invalid index specified for function argument access");
280 using Type = typename std::tuple_element<I, std::tuple<Args...>>::type;
281 static_assert(!std::is_reference<Type>::value,
282 "Reference types/arguments are not supported for automatic "
283 "LLVM Type conversion. Use pointers instead.");
284 };
285 };
286
289
295 template <typename T>
296 inline llvm::Constant*
297 llvmConstant(const T t, llvm::Type* type)
298 {
299 static_assert(std::is_floating_point<T>::value || std::is_integral<T>::value,
300 "T type for llvmConstant must be a floating point or integral type.");
301
302 if (type->isIntegerTy()) {
303 return llvm::ConstantInt::get(type, static_cast<uint64_t>(t), /*signed*/true);
304 }
305 else {
306 assert(type->isFloatingPointTy());
307 return llvm::ConstantFP::get(type, static_cast<double>(t));
308 }
309 }
310
315 llvm::IntegerType* llvmIntType(const uint32_t size, llvm::LLVMContext& C);
316
321 llvm::Type* llvmFloatType(const uint32_t size, llvm::LLVMContext& C);
322
330 llvm::Type* llvmTypeFromToken(const ast::tokens::CoreType& type, llvm::LLVMContext& C);
331
337 ast::tokens::CoreType tokenFromLLVMType(const llvm::Type* type);
338
339 } // namespace codegen
340 } // namespace ax
341 } // namespace OPENVDB_VERSION_NAME
342 } // namespace openvdb
343
344 #endif // OPENVDB_AX_CODEGEN_TYPES_HAS_BEEN_INCLUDED
345
Mat3.h
Mat4.h
String.h
Provides the class definition for the equivalent IR representation and logic for strings in AX.
Tokens.h
Various function and operator tokens used throughout the AST and code generation.
Vec3.h
Exceptions.h
OpenVDB AX Exceptions.
openvdb::v8_1::AXCodeGenError
Definition: ax/openvdb_ax/Exceptions.h:36
openvdb::v8_1::math::Mat3
3x3 matrix class.
Definition: Mat3.h:29
openvdb::v8_1::math::Mat4
4x4 -matrix class.
Definition: Mat4.h:24
openvdb::v8_1::math::Vec2
Definition: Vec2.h:24
openvdb::v8_1::math::Vec3
Definition: Vec3.h:24
openvdb::v8_1::math::Vec4
Definition: Vec4.h:25
openvdb::v8_1::ax::ast::tokens::CoreType
CoreType
Definition: Tokens.h:32
openvdb::v8_1::ax::codegen::llvmIntType
llvm::IntegerType * llvmIntType(const uint32_t size, llvm::LLVMContext &C)
Returns an llvm IntegerType given a requested size and context.
openvdb::v8_1::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_1::ax::codegen::tokenFromLLVMType
ast::tokens::CoreType tokenFromLLVMType(const llvm::Type *type)
Return a corresponding AX token which represents the given LLVM Type.
openvdb::v8_1::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_1::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:297
openvdb
Definition: openvdb/Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: openvdb/Exceptions.h:74
Types.h
openvdb::v8_1::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:219
openvdb::v8_1::ax::codegen::AliasTypeMap::get
static llvm::Type * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:231
openvdb::v8_1::ax::codegen::AliasTypeMap::get
static llvm::Constant * get(llvm::LLVMContext &C, const T1 &value)
Definition: ax/openvdb_ax/codegen/Types.h:235
openvdb::v8_1::ax::codegen::AliasTypeMap::get
static llvm::Constant * get(llvm::LLVMContext &C, const T1 *const value)
Definition: ax/openvdb_ax/codegen/Types.h:239
openvdb::v8_1::ax::codegen::FunctionTraits< ReturnT(Args...)>::Arg::Type
typename std::tuple_element< I, std::tuple< Args... > >::type Type
Definition: ax/openvdb_ax/codegen/Types.h:280
openvdb::v8_1::ax::codegen::FunctionTraits< ReturnT(Args...)>::ReturnType
ReturnT ReturnType
Definition: ax/openvdb_ax/codegen/Types.h:270
openvdb::v8_1::ax::codegen::FunctionTraits< ReturnT(Args...)>::SignatureType
ReturnType(Args...) SignatureType
Definition: ax/openvdb_ax/codegen/Types.h:271
openvdb::v8_1::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:259
openvdb::v8_1::ax::codegen::LLVMType< T * >
Definition: ax/openvdb_ax/codegen/Types.h:157
openvdb::v8_1::ax::codegen::LLVMType< T * >::get
static llvm::PointerType * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:159
openvdb::v8_1::ax::codegen::LLVMType< T[S]>::get
static llvm::Type * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:140
openvdb::v8_1::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_1::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_1::ax::codegen::LLVMType< codegen::String >::get
static llvm::Constant * get(llvm::LLVMContext &C, const codegen::String *const string)
Definition: ax/openvdb_ax/codegen/Types.h:184
openvdb::v8_1::ax::codegen::LLVMType< codegen::String >::get
static llvm::StructType * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:175
openvdb::v8_1::ax::codegen::LLVMType< void >::get
static llvm::Type * get(llvm::LLVMContext &C)
Definition: ax/openvdb_ax/codegen/Types.h:195
openvdb::v8_1::ax::codegen::LLVMType
LLVM type mapping from pod types.
Definition: ax/openvdb_ax/codegen/Types.h:55
openvdb::v8_1::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_1::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_1::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_1::ax::codegen::String
An extremely basic but native representation of a string class with SSO support. This exists to provi...
Definition: String.h:34
openvdb::v8_1::ax::codegen::int_t< 16 >::type
int16_t type
Definition: ax/openvdb_ax/codegen/Types.h:39
openvdb::v8_1::ax::codegen::int_t< 32 >::type
int32_t type
Definition: ax/openvdb_ax/codegen/Types.h:40
openvdb::v8_1::ax::codegen::int_t< 64 >::type
int64_t type
Definition: ax/openvdb_ax/codegen/Types.h:41
openvdb::v8_1::ax::codegen::int_t< 8 >::type
int8_t type
Definition: ax/openvdb_ax/codegen/Types.h:38
openvdb::v8_1::ax::codegen::int_t
Definition: ax/openvdb_ax/codegen/Types.h:37
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178