OpenVDB 13.0.0

Loading...
Searching...
No Matches
FunctionTypes.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/// @file codegen/FunctionTypes.h
5///
6/// @authors Nick Avramoussis
7///
8/// @brief Contains frameworks for creating custom AX functions which can
9/// be registered within the FunctionRegistry and used during code
10/// generation. The intended and safest way to build a function is to
11/// use the FunctionBuilder struct with its addSignature methods. Note
12/// that the derived Function classes provided can also be subclassed
13/// for more granular control, however may be subject to more substantial
14/// API changes.
15///
16/// @details There are a variety of different ways to build a function
17/// which are tailored towards different function types. The two currently
18/// supported function implementations are C Bindings and IR generation.
19/// Additionally, depending on the return type of the function, you may
20/// need to declare your function an SRET (structural return) function.
21///
22/// C Bindings:
23/// As the name suggests, the CFunction class infrastructure provides
24/// the quickest and easiest way to bind to methods in your host
25/// application. The most important thing to consider when choosing
26/// this approach is performance. LLVM will have no knowledge of the
27/// function body during optimization passes. Depending on the
28/// implementation of your method and the user's usage from AX, C
29/// bindings may be subject to limited optimizations in comparison to
30/// IR functions. For example, a static function which is called from
31/// within a loop cannot be unrolled. See the CFunction templated
32/// class.
33///
34/// IR Functions:
35/// IR Functions expect implementations to generate the body of the
36/// function directly into IR during code generation. This ensures
37/// optimal performance during optimization passes however can be
38/// trickier to design. Note that, in the future, AX functions will
39/// be internally supported to provide a better solution for
40/// IR generated functions. See the IRFunction templated class.
41///
42/// SRET Functions:
43/// Both C Bindings and IR Functions can be marked as SRET methods.
44/// SRET methods, in AX, are any function which returns a value which
45/// is not a scalar (e.g. vectors, matrices). This follows the same
46/// optimization logic as clang which will rebuild function signatures
47/// with their return type as the first argument if the return type is
48/// greater than a given size. You should never attempt to return
49/// alloca's directly from functions (unless malloced).
50///
51/// Some other things to consider:
52/// - Ensure C Binding dependencies have been correctly mapped.
53/// - Avoid calling B.CreateAlloca inside of IR functions - instead
54/// rely on the utility method insertStaticAlloca() where possible.
55/// - Ensure both floating point and integer argument signatures are
56/// provided if you wish to avoid floats truncating.
57/// - Array arguments (vectors/matrices) are always passed by pointer.
58/// Scalar arguments are always passed by copy.
59/// - Ensure array arguments which will not be modified are marked as
60/// readonly. Currently, only array arguments can be passed by
61/// "reference".
62/// - Ensure function bodies, return types and parameters and marked
63/// with desirable llvm attributes.
64///
65
66#ifndef OPENVDB_AX_CODEGEN_FUNCTION_TYPES_HAS_BEEN_INCLUDED
67#define OPENVDB_AX_CODEGEN_FUNCTION_TYPES_HAS_BEEN_INCLUDED
68
69#include "Types.h"
70#include "Value.h"
71#include "Utils.h" // isValidCast
72#include "ConstantFolding.h"
73
74#include <openvdb/version.h>
75#include <openvdb/util/Assert.h>
76
77#include <llvm/ADT/SmallVector.h>
78#include <llvm/IR/Constants.h>
79#include <llvm/IR/IRBuilder.h>
80#include <llvm/IR/Module.h>
81
82#include <algorithm>
83#include <functional>
84#include <memory>
85#include <stack>
86#include <type_traits>
87#include <map>
88#include <vector>
89
90
91 namespace openvdb {
92 OPENVDB_USE_VERSION_NAMESPACE
93 namespace OPENVDB_VERSION_NAME {
94
95 namespace ax {
96 namespace codegen {
97
98 struct Function; // fwd
99
100////////////////////////////////////////////////////////////////////////////////
101////////////////////////////////////////////////////////////////////////////////
102
103/// @brief Typedef a stack allocated array with malloc grow support for
104/// anything which is relatively small and bases its container size on the
105/// number of function arguments.
106/// @note LLVM computes N as 3 (currently) for Value types, but we explicitly
107/// set this as this is a well-motivates choice for average/median amount of
108/// function arguments in builtin AX functions.
109 template <typename T>
110 using SmallArgumentVector = llvm::SmallVector<T, 3>;
111
112/// @brief Object to array conversion methods to allow functions to return
113/// vector types. These containers provided an interface for automatic
114/// conversion of C++ objects to LLVM types as array types.
115
116 template <typename T, size_t _SIZE = 1>
117 struct ArgType {
118 using Type = T;
119 static const size_t SIZE = _SIZE;
120 using ArrayType = Type[SIZE];
121 ArrayType mmArgs;
122};
123
124 template <typename T, size_t S>
125 struct LLVMType<ArgType<T,S>> : public AliasTypeMap<ArgType<T,S>, T[S]> {};
126
127 using V2D = ArgType<double, 2>;
128 using V2F = ArgType<float, 2>;
129 using V2I = ArgType<int32_t, 2>;
130 using V3D = ArgType<double, 3>;
131 using V3F = ArgType<float, 3>;
132 using V3I = ArgType<int32_t, 3>;
133 using V4D = ArgType<double, 4>;
134 using V4F = ArgType<float, 4>;
135 using V4I = ArgType<int32_t, 4>;
136 using M3D = ArgType<double, 9>;
137 using M3F = ArgType<float, 9>;
138 using M4D = ArgType<double, 16>;
139 using M4F = ArgType<float, 16>;
140
141////////////////////////////////////////////////////////////////////////////////
142
143/// @brief Type to symbol conversions - these characters are used to build each
144/// functions unique signature. They differ from standard AX or LLVM
145/// syntax to be as short as possible i.e. vec4d, [4 x double] = d4
146
147 template <typename T> struct TypeToSymbol { static inline std::string s() { return "?"; } };
148 template <> struct TypeToSymbol<void> { static inline std::string s() { return "v"; } };
149 template <> struct TypeToSymbol<char> { static inline std::string s() { return "c"; } };
150 template <> struct TypeToSymbol<uint8_t> { static inline std::string s() { return "u8"; } };
151 template <> struct TypeToSymbol<uint16_t> { static inline std::string s() { return "us"; } };
152 template <> struct TypeToSymbol<uint32_t> { static inline std::string s() { return "ui"; } };
153 template <> struct TypeToSymbol<uint64_t> { static inline std::string s() { return "ul"; } };
154 template <> struct TypeToSymbol<int8_t> { static inline std::string s() { return "8"; } };
155 template <> struct TypeToSymbol<int16_t> { static inline std::string s() { return "s"; } };
156 template <> struct TypeToSymbol<int32_t> { static inline std::string s() { return "i"; } };
157 template <> struct TypeToSymbol<int64_t> { static inline std::string s() { return "l"; } };
158 template <> struct TypeToSymbol<float> { static inline std::string s() { return "f"; } };
159 template <> struct TypeToSymbol<double> { static inline std::string s() { return "d"; } };
160 template <> struct TypeToSymbol<codegen::String> { static inline std::string s() { return "a"; } };
161
162 template <typename T>
163 struct TypeToSymbol<T*> {
164 static inline std::string s() { return TypeToSymbol<T>::s() + "*"; }
165};
166
167 template <typename T, size_t S>
168 struct TypeToSymbol<T[S]> {
169 static inline std::string s() { return TypeToSymbol<T>::s() + std::to_string(S); }
170};
171
172 template <typename T, size_t S> struct TypeToSymbol<ArgType<T,S>> : public TypeToSymbol<T[S]> {};
173 template <typename T> struct TypeToSymbol<math::Vec2<T>> : public TypeToSymbol<T[2]> {};
174 template <typename T> struct TypeToSymbol<math::Vec3<T>> : public TypeToSymbol<T[3]> {};
175 template <typename T> struct TypeToSymbol<math::Vec4<T>> : public TypeToSymbol<T[4]> {};
176 template <typename T> struct TypeToSymbol<math::Mat3<T>> : public TypeToSymbol<T[9]> {};
177 template <typename T> struct TypeToSymbol<math::Mat4<T>> : public TypeToSymbol<T[16]> {};
178 template <typename T> struct TypeToSymbol<const T> : public TypeToSymbol<T> {};
179 template <typename T> struct TypeToSymbol<const T*> : public TypeToSymbol<T*> {};
180
181////////////////////////////////////////////////////////////////////////////////
182////////////////////////////////////////////////////////////////////////////////
183
184/// @brief Templated argument iterator which implements various small functions
185/// per argument type, resolved at compile time.
186///
187template <typename SignatureT, size_t I = FunctionTraits<SignatureT>::N_ARGS>
188 struct ArgumentIterator
189{
190 using ArgT = typename FunctionTraits<SignatureT>::template Arg<I-1>;
191 using ArgumentValueType = typename ArgT::Type;
192
193 /// @brief Whether this signature contains types that are representable
194 /// in AX's Value type.
195 static const bool IsNativeSignature =
196 LLVMType<ArgumentValueType>::CXXUTypeIsNativeType &&
197 ArgumentIterator<SignatureT, I-1>::IsNativeSignature;
198
199 template <typename OpT>
200 static void apply(const OpT& op, const bool forwards) {
201 if (forwards) {
202 ArgumentIterator<SignatureT, I-1>::apply(op, forwards);
203 op(ArgumentValueType());
204 }
205 else {
206 op(ArgumentValueType());
207 ArgumentIterator<SignatureT, I-1>::apply(op, forwards);
208 }
209 }
210};
211
212 template <typename SignatureT>
213 struct ArgumentIterator<SignatureT, 0>
214{
215 static const bool IsNativeSignature = true;
216 template <typename OpT>
217 static void apply(const OpT&, const bool) {}
218};
219
220////////////////////////////////////////////////////////////////////////////////
221////////////////////////////////////////////////////////////////////////////////
222
223/// @brief Metadata associated with a function argument or return value.
224 struct ArgInfo
225{
226 explicit ArgInfo(const Value& val)
227 : ArgInfo(val.GetUnderlyingType(), val.IsPtr() ? 1 : 0) {}
228 explicit ArgInfo(llvm::Type* utype) : ArgInfo(utype, 0) {}
229 ArgInfo(llvm::Type* utype, uint8_t ptrs, bool ret = false)
230 : mUType(utype), mPtrs(ptrs), mReturn(ret) {
231 OPENVDB_ASSERT(mUType);
232 OPENVDB_ASSERT(!mUType->isPointerTy());
233 // void*'s need to be provided as int8_t's
234 OPENVDB_ASSERT(!(mUType->isVoidTy() && mPtrs > 0));
235 }
236 ArgInfo(ArgInfo&&) = default;
237 ArgInfo(const ArgInfo&) = default;
238 ArgInfo& operator=(ArgInfo&&) = default;
239 ArgInfo& operator=(const ArgInfo&) = default;
240 bool operator==(const ArgInfo& other) const
241 {
242 return
243 mUType == other.mUType &&
244 mPtrs == other.mPtrs &&
245 mReturn == other.mReturn;
246 }
247 bool operator!=(const ArgInfo& other) const { return !this->operator==(other); }
248 bool IsMatchingType(const ArgInfo& other) const
249 {
250 return
251 mUType == other.mUType &&
252 mPtrs == other.mPtrs;
253 }
254 bool IsPtr() const { return mPtrs > 0; }
255 uint8_t NumPtrs() const { return mPtrs; }
256 bool IsNative() const { return Value::Supports(mUType) && mPtrs <= 1; }
257 bool IsVoid() const { return mUType->isVoidTy(); }
258 bool IsReturn() const { return mReturn; }
259 llvm::Type* GetUnderlyingType() const { return mUType; }
260 llvm::Type* GetType() const
261 {
262 llvm::Type* type = mUType;
263 for (uint8_t i = 0; i < mPtrs; ++i) {
264 type = llvm::PointerType::get(type, 0);
265 }
266 return type;
267 }
268 void SetIsReturn() { mReturn = true; }
269 private:
270 llvm::Type* mUType; // the underlying argument type
271 uint8_t mPtrs; // num ptrs to the type
272 // true if this is the return argument. For Sret functions, both the
273 // void return and first argument are marked as true.
274 bool mReturn;
275};
276
277/// @brief Container of ArgInfos. This class makes up part of the Function
278/// API for querying signature information.
279 struct ArgInfoVector
280{
281 public:
282 using ContainerT = SmallArgumentVector<ArgInfo>;
283
284 ArgInfoVector() = default;
285 ArgInfoVector(const std::initializer_list<ArgInfo>& info)
286 : mInfoVec(info) {}
287 ArgInfoVector(ArgInfoVector&&) = default;
288 ArgInfoVector(const ArgInfoVector&) = default;
289 ArgInfoVector& operator=(ArgInfoVector&&) = default;
290 ArgInfoVector& operator=(const ArgInfoVector&) = default;
291
292 bool operator==(const ArgInfoVector& other) const { return mInfoVec == other.mInfoVec; }
293 bool operator!=(const ArgInfoVector& other) const { return !this->operator==(other); }
294
295 auto begin() { return mInfoVec.begin(); }
296 auto end() { return mInfoVec.end(); }
297 auto begin() const { return mInfoVec.begin(); }
298 auto end() const { return mInfoVec.end(); }
299 auto rbegin() { return mInfoVec.rbegin(); }
300 auto rend() { return mInfoVec.rend(); }
301 auto rbegin() const { return mInfoVec.rbegin(); }
302 auto rend() const { return mInfoVec.rend(); }
303 auto& front() { return mInfoVec.front(); }
304 auto& front() const { return mInfoVec.front(); }
305 auto& back() { return mInfoVec.back(); }
306 auto& back() const { return mInfoVec.back(); }
307 auto pop_back() { return mInfoVec.pop_back(); }
308 auto clear() { return mInfoVec.clear(); }
309 auto size() const { return mInfoVec.size(); }
310 auto empty() const { return mInfoVec.empty(); }
311 auto erase(ContainerT::const_iterator iter) { return mInfoVec.erase(iter); }
312
313 void reserve(size_t i) { mInfoVec.reserve(i); }
314 template <typename ...Args>
315 void emplace_back(Args&& ...args) { mInfoVec.emplace_back(std::move(args)...); }
316 ArgInfo& operator[](size_t pos)
317 {
318 OPENVDB_ASSERT(pos < mInfoVec.size());
319 return mInfoVec[pos];
320 }
321 const ArgInfo& operator[](size_t pos) const
322 {
323 OPENVDB_ASSERT(pos < mInfoVec.size());
324 return mInfoVec[pos];
325 }
326
327 SmallArgumentVector<llvm::Type*> AsLLVMTypes() const
328 {
329 SmallArgumentVector<llvm::Type*> types;
330 types.reserve(mInfoVec.size());
331 for (auto& info : mInfoVec) {
332 types.emplace_back(info.GetType());
333 }
334 return types;
335 }
336
337 private:
338 ContainerT mInfoVec;
339};
340
341/// @brief Wrapper struct to represent "native" function arguments; that is,
342/// the set of Value type that the AX grammar supports. NativeArguments
343/// have two benefits; they support casting and implicit function matching
344/// through FunctionGroups and can be used directly in IR generators (to
345/// leverage the AX Value API). Functions can still be generated and called
346/// with "non-native" arguments, but in these cases FunctionGroup::execute
347/// must result in an explicit signature match
348 struct NativeArguments
349{
350 NativeArguments() = default;
351 NativeArguments(const std::initializer_list<Value>& args)
352 : mArgs(args) {}
353 explicit NativeArguments(const std::vector<Value>& args)
354 : mArgs(args.begin(), args.end()) {}
355 NativeArguments(NativeArguments&&) = default;
356 NativeArguments(const NativeArguments&) = default;
357 NativeArguments& operator=(NativeArguments&&) = default;
358 NativeArguments& operator=(const NativeArguments&) = default;
359 size_t size() const { return mArgs.size(); }
360 Value& operator[](size_t pos)
361 {
362 OPENVDB_ASSERT(pos < mArgs.size());
363 return mArgs[pos];
364 }
365 const Value& operator[](size_t pos) const
366 {
367 OPENVDB_ASSERT(pos < mArgs.size());
368 return mArgs[pos];
369 }
370 void AddArg(const Value& val) { mArgs.emplace_back(val); }
371 /// @brief Cast these arguments to match the given function's signature
372 OPENVDB_AX_API NativeArguments Cast(const Function& F, llvm::IRBuilder<>& B) const;
373 private:
374 SmallArgumentVector<Value> mArgs;
375};
376
377/// @brief Arbitrary, potentially "non-native" arguments. This wrapper struct
378/// can be used when generating function which cannot be called from AX
379/// itself (e.g. VDB accessor functions or Volume/Point kernels etc). They
380/// do not support implicit function signature matching or casting.
381 struct Arguments
382{
383 Arguments() = default;
384
385 /// @biref Create a set of arguments from native arguments. The function
386 /// framework typically works on generic arguments types.
387 explicit Arguments(const NativeArguments& args) {
388 mArgs.reserve(args.size());
389 mTypes.reserve(args.size());
390 for (size_t i = 0; i < args.size(); ++i) {
391 this->AddArg(args[i]);
392 }
393 }
394
395 Arguments(Arguments&&) = default;
396 Arguments(const Arguments&) = default;
397 Arguments& operator=(Arguments&&) = default;
398 Arguments& operator=(const Arguments&) = default;
399
400 size_t size() const { return mArgs.size(); }
401
402 bool AreNativeValues() const
403 {
404 for (const auto& types : mTypes) {
405 if (!types.IsNative()) return false;
406 }
407 return true;
408 }
409
410 Value AsNativeValue(const size_t i) const
411 {
412 OPENVDB_ASSERT(mTypes[i].IsNative());
413 return Value(mArgs[i], mTypes[i].GetUnderlyingType());
414 }
415
416 NativeArguments AsNativeValues() const
417 {
418 OPENVDB_ASSERT(this->AreNativeValues());
419 NativeArguments args;
420 for (size_t i = 0; i < mArgs.size(); ++i) {
421 args.AddArg(this->AsNativeValue(i));
422 }
423 return args;
424 }
425
426 const llvm::ArrayRef<llvm::Value*> AsLLVMValues() const { return mArgs; }
427 const ArgInfo& GetArgInfo(size_t pos) const { return mTypes[pos]; }
428 const ArgInfoVector& GetArgInfo() const { return mTypes; }
429
430 llvm::Value* operator[](size_t pos) const
431 {
432 OPENVDB_ASSERT(pos < mTypes.size());
433 return mArgs[pos];
434 }
435
436 void AddArg(llvm::Value* val, const ArgInfo& type)
437 {
438#if LLVM_VERSION_MAJOR <= 15
439 [[maybe_unused]] llvm::Type* base = val->getType();
440 while (base->isPointerTy()) base = base->getContainedType(0);
441 OPENVDB_ASSERT_MESSAGE((base == type.GetUnderlyingType()),
442 "Base type of val does not match stored underlying type");
443#endif
444 mArgs.emplace_back(val);
445 mTypes.emplace_back(type);
446 }
447
448 void AddArg(const Value& val)
449 {
450 mArgs.emplace_back(val.GetValue());
451 mTypes.emplace_back(val);
452 }
453
454 void PrependArg(const Value& val)
455 {
456 this->AddArg(val);
457 std::rotate(mArgs.rbegin(), mArgs.rbegin() + 1, mArgs.rend());
458 std::rotate(mTypes.rbegin(), mTypes.rbegin() + 1, mTypes.rend());
459 }
460
461 private:
462 SmallArgumentVector<llvm::Value*> mArgs;
463 ArgInfoVector mTypes;
464};
465
466///////////////////////////////////////////////////////////////////////////////
467///////////////////////////////////////////////////////////////////////////////
468
469/// @brief Populate a vector of llvm types from a function signature
470/// declaration.
471/// @warning From LLVM 16 onwards, pointer argument type cannot be
472/// introspected
473///
474/// @param C The llvm context
475/// @param types A vector of types to populate
476///
477 template <typename SignatureT>
478 inline llvm::Type*
479 llvmTypesFromSignature(llvm::LLVMContext& C,
480 std::vector<llvm::Type*>* types = nullptr)
481{
482 using Traits = FunctionTraits<SignatureT>;
483 using ArgumentIteratorT =
484 ArgumentIterator<SignatureT, Traits::N_ARGS>;
485
486 if (types) {
487 types->reserve(Traits::N_ARGS);
488 auto callback = [&types, &C](auto type) {
489 using Type = decltype(type);
490 types->emplace_back(LLVMType<Type>::get(C));
491 };
492 ArgumentIteratorT::apply(callback, /*forwards*/true);
493 }
494 using Type = typename Traits::ReturnType;
495 return LLVMType<Type>::get(C);
496}
497
498/// @brief Populate a vector of ArgInfos from a function signature
499/// declaration.
500///
501/// @param C The llvm context
502/// @param types A ArgInfoVector to populate
503///
504 template <typename SignatureT>
505 inline ArgInfo
506 llvmArgTypesFromSignature(llvm::LLVMContext& C,
507 ArgInfoVector* types = nullptr)
508{
509 using Traits = FunctionTraits<SignatureT>;
510 using ArgumentIteratorT =
511 ArgumentIterator<SignatureT, Traits::N_ARGS>;
512
513 if (types)
514 {
515 types->reserve(Traits::N_ARGS);
516 auto callback = [&types, &C](auto type)
517 {
518 using UnderlyingType = std::remove_cv_t<typename RemoveAllPtrTypes<decltype(type)>::Type>;
519 static constexpr auto NPtrs = CountNPtrs<decltype(type)>::value;
520 static constexpr bool IsVoid = std::is_same_v<UnderlyingType, void>;
521 // args can't be void without pts
522 static_assert(!IsVoid || NPtrs > 0);
523 // void* arguments alias to int8_t
524 using Type = std::conditional_t<IsVoid, int8_t, UnderlyingType>;
525 types->emplace_back(LLVMType<Type>::get(C), NPtrs);
526 };
527 ArgumentIteratorT::apply(callback, /*forwards*/true);
528 }
529
530 using UnderlyingType = std::remove_cv_t<typename RemoveAllPtrTypes<typename Traits::ReturnType>::Type>;
531 static constexpr auto NPtrs = CountNPtrs<typename Traits::ReturnType>::value;
532
533 if constexpr (std::is_same_v<UnderlyingType, void> && NPtrs > 0)
534 {
535 // if underlying type is void, alias to int8_t if its a void*
536 ArgInfo ret{LLVMType<int8_t>::get(C), NPtrs};
537 ret.SetIsReturn();
538 return ret;
539 }
540 else {
541 ArgInfo ret{LLVMType<UnderlyingType>::get(C), NPtrs};
542 ret.SetIsReturn();
543 return ret;
544 }
545}
546
547
548/// @brief Generate an LLVM FunctionType from a function signature
549///
550/// @param C The llvm context
551///
552 template <typename SignatureT>
553 inline llvm::FunctionType*
554 llvmFunctionTypeFromSignature(llvm::LLVMContext& C)
555{
556 ArgInfoVector types;
557 ArgInfo returnType =
558 llvmArgTypesFromSignature<SignatureT>(C, &types);
559 return llvm::FunctionType::get(returnType.GetType(),
560 types.AsLLVMTypes(), /*isVarArg=*/false);
561}
562
563/// @brief Print a function signature to the provided ostream.
564///
565/// @param os The stream to print to
566/// @param types The function argument types
567/// @param returnType The return type of the function. Must not be a nullptr
568/// @param name The name of the function. If not provided, the return type
569/// neighbours the first parenthesis
570/// @param names Names of the function parameters. If a name is nullptr, it
571/// skipped
572/// @param axTypes Whether to try and convert the llvm::Types provided to
573/// AX types. If false, the llvm types are used.
574 OPENVDB_AX_API void
575 printSignature(std::ostream& os,
576 const ArgInfoVector& types,
577 const ArgInfo& returnType,
578 const char* name = nullptr,
579 const llvm::ArrayRef<const char*>& names = {},
580 const bool axTypes = false);
581
582
583#if LLVM_VERSION_MAJOR <= 15
584 OPENVDB_DEPRECATED_MESSAGE("Switch to AX's internal ArgInfo types for LLVM 16 onwards")
585 OPENVDB_AX_API void
586 printSignature(std::ostream& os,
587 const std::vector<llvm::Type*>& types,
588 const llvm::Type* returnType,
589 const char* name = nullptr,
590 const std::vector<const char*>& names = {},
591 const bool axTypes = false);
592#endif
593
594///////////////////////////////////////////////////////////////////////////////
595////////////////////////////////////////////////////////////////////////////////
596
597/// Forward declare builder for private access to Function types
598 struct FunctionBuilder;
599
600/// @brief The base/abstract representation of an AX function. Derived classes
601/// must implement the Function::types call to describe their signature.
602 struct OPENVDB_AX_API Function
603{
604 using Ptr = std::shared_ptr<Function>;
605
606 Function(const size_t size, const std::string& symbol)
607 : mSize(size)
608 , mSymbol(symbol)
609 , mAttributes(nullptr)
610 , mNames()
611 , mDeps() {
612 // symbol must be a valid string
613 OPENVDB_ASSERT(!symbol.empty());
614 }
615
616 virtual ~Function() = default;
617
618 /// @brief Populate a vector of ArgInfos which describe this function
619 /// signature. This method is used by Function::create,
620 /// Function::print and Function::match.
621 /// @note The variant that takes a vector of ArgInfos is optional with
622 /// LLVM 15 for compatibility but must be implemented with newer
623 /// versions.
624#if LLVM_VERSION_MAJOR <= 15
625 virtual ArgInfo types(ArgInfoVector&, llvm::LLVMContext&) const
626 {
627 OPENVDB_THROW(AXCodeGenError,
628 std::string("New AX API for function arguments has been called but has not "
629 "been implemented by function: ") + this->symbol());
630 }
631 OPENVDB_DEPRECATED_MESSAGE("Switch to AX's internal ArgInfo types for LLVM 16 onwards")
632 virtual llvm::Type* types(std::vector<llvm::Type*>&, llvm::LLVMContext&) const = 0;
633#else
634 virtual ArgInfo types(ArgInfoVector&, llvm::LLVMContext&) const = 0;
635#endif
636
637 /// @brief Converts and creates this AX function into a llvm Function.
638 /// @details This method uses the result from Function::types() to construct
639 /// a llvm::FunctionType and a subsequent a llvm::Function. Any
640 /// parameter, return or function attributes are also added to the
641 /// function. If a module is provided, the module if first checked
642 /// to see if the function already exists. If it does, it is
643 /// immediately returned. If the function doesn't exist in the
644 /// module, its prototype is created and also inserted into the end
645 /// of the modules function list. If no module is provided, the
646 /// function is left detached and must be added to a valid Module
647 /// to be callable.
648 /// @warning If a module is not provided, the caller takes ownership of the
649 /// returned function and is responsible for deallocating it.
650 /// @note The body of the function is left to derived classes to
651 /// implement. As you need a Module to generate the prototype/body,
652 /// this function serves two purposes. The first is to return the
653 /// detached function signature if only a context is provided.
654 /// The second is to ensure the function prototype and body (if
655 /// required) is inserted into the module prior to returning.
656 /// @note It is possible to end up with function symbol collisions if you
657 /// do not have unique function symbols in your module
658 ///
659 /// @param C The LLVM Context
660 /// @param M The Module to write the function to
661 virtual llvm::Function*
662 create(llvm::LLVMContext& C, llvm::Module* M = nullptr) const;
663
664 /// @brief Convenience method which always uses the provided module to find
665 /// the function or insert it if necessary.
666 /// @param M The llvm::Module to use
667 llvm::Function* create(llvm::Module& M) const {
668 return this->create(M.getContext(), &M);
669 }
670
671 /// @brief Convenience method for calling M.getFunction(symbol). Returns a
672 /// nullptr if the function has not yet been created or if it is
673 /// embedded IR.
674 /// @param M The llvm::Module to use
675 llvm::Function* get(const llvm::Module& M) const;
676
677 /// @brief Uses the IRBuilder to create a call to this function with the
678 /// given arguments, creating the function and inserting it into the
679 /// IRBuilder's Module if necessary (through Function::create).
680 /// Returns the result of the function call which can be a nullptr
681 /// if the function is a non-sret void call.
682 /// @note The IRBuilder must have a valid llvm Module/Function/Block
683 /// attached
684 /// @note If the number of provided arguments do not match the size of the
685 /// current function, invalid IR will be generated.
686 /// @note If the provided argument types do not match the current function
687 /// and cast is false, invalid IR will be generated. Additionally,
688 /// invalid IR will be generated if cast is true but no valid cast
689 /// exists for a given argument.
690 /// @note When casting arguments, the readonly flags of the function are
691 /// not checked (unlike Function::match). Casting an argument will
692 /// cause a new copy of the argument to be created and passed to the
693 /// function. These new values do not propagate back any changes to
694 /// the original argument. Separate functions for all writable
695 /// argument types must be created.
696 ///
697 /// @param args The llvm Value arguments to call this function with
698 /// @param B The llvm IRBuilder
699 /// @param cast Whether to allow implicit casting of arguments
700#if LLVM_VERSION_MAJOR <= 15
701 OPENVDB_DEPRECATED_MESSAGE("Function::call which takes llvm::Value's and "
702 "supports casting is incompatible with LLVM 16+ and will be removed.")
703 virtual llvm::Value*
704 call(const std::vector<llvm::Value*>& args,
705 llvm::IRBuilder<>& B,
706 const bool cast) const;
707#endif
708 /// From LLVM 16 onwards, this version of call does not support argument
709 /// casting. This must be performed using the NativeArguments struct
710 virtual llvm::Value*
711 call(const std::vector<llvm::Value*>& args,
712 llvm::IRBuilder<>& B) const;
713
714 virtual Value call(const Arguments& args, llvm::IRBuilder<>& B) const;
715
716 Value call(const NativeArguments& args, llvm::IRBuilder<>& B) const
717 {
718 return this->call(Arguments(args.Cast(*this, B)), B);
719 }
720
721 /// @brief The result type from calls to Function::match
722 /// @note Function::match cannot return Ambiguous - this is only returned
723 /// by the FunctionGroup API.
724 enum SignatureMatch
725 {
726 None = 0, // Mismatching argument sizes
727 Size, // Correct number of arguments but incompatible types
728 Implicit, // Correct number of arguments and castable types
729 Ambiguous, // Correct number of arguments and castable types but multiple available signatures
730 Explicit // Correct number of arguments and types match exactly
731 };
732
733 /// @brief The base implementation for determining how a vector of llvm
734 /// arguments translates to this functions signature. Returns an
735 /// enum which represents the available mapping.
736 /// @details This method calls types() to figure out the function signature,
737 /// then compares each argument type to the type in the input
738 /// vector. If the types match exactly, an Explicit match is found.
739 /// If the sizes of the inputs and signature differ, no match is
740 /// found and None is returned. If however, the sizes match and
741 /// there exists a valid implicit cast from the input type to the
742 /// signature type for every input, an Implicit match is returned.
743 /// Finally, if the sizes match but there is no implicit cast
744 /// mapping, Size is returned.
745 /// i8 -> i32 : Implicit
746 /// i32 -> i32 : Explicit
747 /// str -> i32 : Size
748 /// (i32,i32) -> i32 : None
749 /// Never returns Ambiguous (this state is used by FunctionGroup)
750 /// @note Due to the way CFunctionSRet is implemented, the LLVM Context
751 /// must be provided in case we have a zero arg function signature
752 /// with a SRET.
753 /// @param inputs The input types
754 /// @param C The LLVM Context
755 virtual SignatureMatch match(const ArgInfoVector& inputs, llvm::LLVMContext& C) const;
756#if LLVM_VERSION_MAJOR <= 15
757 OPENVDB_DEPRECATED_MESSAGE("Switch to AX's internal ArgInfo types for LLVM 16 onwards")
758 virtual SignatureMatch match(const std::vector<llvm::Type*>& inputs, llvm::LLVMContext& C) const;
759#endif
760
761 /// @brief The number of arguments that this function has
762 inline size_t size() const { return mSize; }
763
764 /// @brief The function symbol name.
765 /// @details This will be used as its identifier in IR and must be unique.
766 inline const char* symbol() const { return mSymbol.c_str(); }
767
768 /// @brief Returns the descriptive name of the given argument index
769 /// @details If the index is greater than the number of arguments, an empty
770 /// string is returned.
771 ///
772 /// @param idx The index of the argument
773 inline const char* argName(const size_t idx) const
774 {
775 return idx < mNames.size() ? mNames[idx] : "";
776 }
777
778 /// @brief Print this function's signature to the provided ostream.
779 /// @details This is intended to return a descriptive front end user string
780 /// rather than the function's IR representation. This function is
781 /// virtual so that derived classes can customize how they present
782 /// frontend information.
783 /// @sa printSignature
784 ///
785 /// @param C The llvm context
786 /// @param os The ostream to print to
787 /// @param name The name to insert into the description.
788 /// @param axTypes Whether to print llvm IR or AX Types.
789 virtual void print(llvm::LLVMContext& C,
790 std::ostream& os,
791 const char* name = nullptr,
792 const bool axTypes = true) const;
793
794 const SmallArgumentVector<const char*>& dependencies() const { return mDeps; }
795
796 /// Deprecated builder methods, no longer public
797
798 OPENVDB_DEPRECATED_MESSAGE("This method incorrectly returns the attributes "
799 "of the function set by the FunctionBuilder, not by the codegen. To "
800 "inspect function attributes, retrieve the created function from the "
801 "llvm::Module.")
802 inline bool hasParamAttribute(const size_t i,
803 const llvm::Attribute::AttrKind& kind) const
804 {
805 if (!mAttributes) return false;
806 const auto iter = mAttributes->mParamAttrs.find(i);
807 if (iter == mAttributes->mParamAttrs.end()) return false;
808 const auto& vec = iter->second;
809 return std::find(vec.begin(), vec.end(), kind) != vec.end();
810 }
811
812 OPENVDB_DEPRECATED_MESSAGE("Use the FunctionBuilder to construct Functions")
813 inline void setArgumentNames(std::vector<const char*> names)
814 {
815 mNames.assign(names.begin(), names.end());
816 }
817
818 OPENVDB_DEPRECATED_MESSAGE("Use the FunctionBuilder to construct Functions")
819 inline void setDependencies(std::vector<const char*> deps)
820 {
821 mDeps.assign(deps.begin(), deps.end());
822 }
823
824 OPENVDB_DEPRECATED_MESSAGE("Use the FunctionBuilder to construct Functions")
825 inline void setFnAttributes(const std::vector<llvm::Attribute::AttrKind>& in)
826 {
827 this->attrs().mFnAttrs.assign(in.begin(), in.end());
828 }
829
830 OPENVDB_DEPRECATED_MESSAGE("Use the FunctionBuilder to construct Functions")
831 inline void setRetAttributes(const std::vector<llvm::Attribute::AttrKind>& in)
832 {
833 this->attrs().mRetAttrs.assign(in.begin(), in.end());
834 }
835
836 OPENVDB_DEPRECATED_MESSAGE("Use the FunctionBuilder to construct Functions")
837 inline void setParamAttributes(const size_t i,
838 const std::vector<llvm::Attribute::AttrKind>& in)
839 {
840 this->attrs().mParamAttrs[i].assign(in.begin(), in.end());
841 }
842
843 protected:
844
845#if LLVM_VERSION_MAJOR <= 15
846 /// @brief Cast the provided arguments to the given type as supported by
847 /// implicit casting of function types. If the types already match
848 /// OR if a cast cannot be performed, nothing is done to the argument.
849 /// @todo This should really be generalized out for Function::call and
850 /// Function::match to both use. However, due to SRET functions,
851 /// this logic must be performed somewhere in the Function class
852 /// hierarchy and not in FunctionGroup
853 static void cast(std::vector<llvm::Value*>& args,
854 const std::vector<llvm::Type*>& types,
855 llvm::IRBuilder<>& B);
856#endif
857
858 private:
859 friend FunctionBuilder;
860
861 enum class Type {
862 kNormal,
863 kBuiltin,
864 kKernel
865 };
866
867 struct Attributes
868 {
869 SmallArgumentVector<llvm::Attribute::AttrKind> mFnAttrs, mRetAttrs;
870 std::map<size_t, SmallArgumentVector<llvm::Attribute::AttrKind>> mParamAttrs;
871 bool mReadOnly {false};
872 Type mType {Type::kNormal};
873 };
874
875 inline Attributes& attrs()
876 {
877 if (!mAttributes) mAttributes.reset(new Attributes());
878 return *mAttributes;
879 }
880
881 /// @brief Temporary method until we move to ArgInfo introspection
882 bool IsParamReadOnly(const size_t idx) const
883 {
884 if (!mAttributes) return false; // can't be certain if no attrs set
885 if (mAttributes->mReadOnly) return true;
886 // @todo REMOVE - switch to using writable info on the ArgInfo types
887 const auto iter = mAttributes->mParamAttrs.find(idx);
888 if (iter == mAttributes->mParamAttrs.end()) return false;
889 const auto& vec = iter->second;
890 return std::find(vec.begin(), vec.end(),
891 llvm::Attribute::AttrKind::ReadOnly) != vec.end();
892 }
893
894 llvm::AttributeList flattenAttrs(llvm::Function* F) const;
895
896 private:
897 const size_t mSize;
898 const std::string mSymbol;
899 std::unique_ptr<Attributes> mAttributes;
900 SmallArgumentVector<const char*> mNames;
901 SmallArgumentVector<const char*> mDeps;
902};
903
904/// @brief Templated interface class for SRET functions. This struct provides
905/// the interface for functions that wish to return arrays (vectors or
906/// matrices) by internally remapping the first argument for the user.
907/// As far as LLVM and any bindings are concerned, the function
908/// signature remains unchanged - however the first argument becomes
909/// "invisible" to the user and is instead allocated by LLVM before the
910/// function is executed. Importantly, the argument has no impact on
911/// the user facing AX signature and doesn't affect declaration selection.
912/// @note This class is not intended to be instantiated directly, but instead
913/// used by derived implementation which hold a valid implementations
914/// of member functions required to create a llvm::Function (such as
915/// Function::types and Function::call). This exists as an interface to
916/// avoid virtual inheritance.
917///
918 template <typename SignatureT, typename DerivedFunction>
919 struct SRetFunction : public DerivedFunction
920{
921 using Ptr = std::shared_ptr<SRetFunction<SignatureT, DerivedFunction>>;
922 using Traits = FunctionTraits<SignatureT>;
923
924 // check there actually are arguments
925 static_assert(Traits::N_ARGS > 0,
926 "SRET Function object has been setup with the first argument as the return "
927 "value, however the provided signature is empty.");
928
929 // check no return value exists
930 static_assert(std::is_same<typename Traits::ReturnType, void>::value,
931 "SRET Function object has been setup with the first argument as the return "
932 "value and a non void return type.");
933
934 private:
935
936 using FirstArgument = typename Traits::template Arg<0>::Type;
937 static_assert(std::is_pointer<FirstArgument>::value,
938 "SRET Function object has been setup with the first argument as the return "
939 "value, but this argument it is not a pointer type.");
940 static_assert(!std::is_const_v<FirstArgument>,
941 "SRET Function object has been setup with the first argument as the return "
942 "value, but this argument is const.");
943 using SRetType = typename std::remove_pointer<FirstArgument>::type;
944
945 public:
946
947 /// @brief Overide the ArgInfo type method. This does NOT change the arg
948 /// order, it simply marks the first argument as a return argument. Note
949 /// that the void ret type is also left as a return type.
950 ArgInfo types(ArgInfoVector& args, llvm::LLVMContext& C) const override
951 {
952 ArgInfo ret = DerivedFunction::types(args, C);
953 OPENVDB_ASSERT(!args.empty());
954 OPENVDB_ASSERT(ret.IsVoid());
955 OPENVDB_ASSERT(!args[0].IsVoid());
956 OPENVDB_ASSERT(args[0].IsPtr());
957 args[0].SetIsReturn();
958 return ret;
959 }
960
961 /// @brief Override of match which inserts the SRET type such that the base
962 /// class methods ignore it.
963 Function::SignatureMatch match(
964 const ArgInfoVector& args,
965 llvm::LLVMContext& C) const override
966 {
967 ArgInfoVector inputs(args);
968 // Create a dummy sret ptr type for derived match impls
969 llvm::Type* stype = LLVMType<SRetType>::get(C);
970 // llvm::Constant* zero = llvmConstant(0, llvm::Type::getInt64Ty(C));
971 // llvm::Constant* dummy = llvm::ConstantExpr::getPointerCast(zero, stype->getPointerTo());
972 inputs.emplace_back(stype, 1);
973 inputs.back().SetIsReturn();
974 std::rotate(inputs.rbegin(), inputs.rbegin() + 1, inputs.rend());
975 return DerivedFunction::match(inputs, C);
976 }
977
978 /// @brief Override of call which allocates the required SRET llvm::Value
979 /// for this function.
980 /// @note Unlike other function where the returned llvm::Value* is a
981 /// llvm::CallInst (which also represents the return value),
982 /// SRET functions return the allocated 1st argument i.e. not a
983 /// llvm::CallInst
984 llvm::Value*
985 call(const std::vector<llvm::Value*>& args,
986 llvm::IRBuilder<>& B) const override
987 {
988 // append return value and right rotate
989 std::vector<llvm::Value*> inputs(args);
990 llvm::Type* sret = LLVMType<SRetType>::get(B.getContext());
991 inputs.emplace_back(insertStaticAlloca(B, sret));
992 std::rotate(inputs.rbegin(), inputs.rbegin() + 1, inputs.rend());
993 DerivedFunction::call(inputs, B);
994 return inputs.front();
995 }
996
997 Value call(const Arguments& args, llvm::IRBuilder<>& B) const override
998 {
999 // append return value and right rotate
1000 Arguments inputs(args);
1001 Value sret = Value::Alloc(B, LLVMType<SRetType>::get(B.getContext()));
1002 inputs.PrependArg(sret);
1003 DerivedFunction::call(inputs, B);
1004 return sret;
1005 }
1006
1007 /// @brief Override of print to avoid printing out the SRET type
1008 void print(llvm::LLVMContext& C,
1009 std::ostream& os,
1010 const char* name = nullptr,
1011 const bool axTypes = true) const override
1012 {
1013 ArgInfoVector current;
1014 ArgInfo ret = this->types(current, C);
1015 // left rotate
1016 std::rotate(current.begin(), current.begin() + 1, current.end());
1017 ret = current.back();
1018 current.pop_back();
1019
1020 SmallArgumentVector<const char*> names;
1021 names.reserve(this->size());
1022 for (size_t i = 0; i < this->size()-1; ++i) {
1023 names.emplace_back(this->argName(i));
1024 }
1025 printSignature(os, current, ret, name, names, axTypes);
1026 }
1027
1028#if LLVM_VERSION_MAJOR <= 15
1029 /// @note Bring in deprecated type methods
1030 using Function::types;
1031
1032 /// @note This is deprecated! Omitting the warning as it invokes the
1033 /// parent function which is also deprecated. Use NativeArguments to
1034 /// perform argument casting
1035 Function::SignatureMatch match(const std::vector<llvm::Type*>& args,
1036 llvm::LLVMContext& C) const override
1037 {
1038 // append return type and right rotate
1039 std::vector<llvm::Type*> inputs(args);
1040 inputs.emplace_back(LLVMType<SRetType*>::get(C));
1041 std::rotate(inputs.rbegin(), inputs.rbegin() + 1, inputs.rend());
1042 return DerivedFunction::match(inputs, C);
1043 }
1044
1045 /// @note This is deprecated! Omitting the warning as it invokes the
1046 /// parent function which is also deprecated. Use NativeArguments to
1047 /// perform argument casting
1048 llvm::Value*
1049 call(const std::vector<llvm::Value*>& args,
1050 llvm::IRBuilder<>& B,
1051 const bool cast) const override
1052 {
1053 // append return value and right rotate
1054 std::vector<llvm::Value*> inputs(args);
1055 llvm::Type* sret = LLVMType<SRetType>::get(B.getContext());
1056 inputs.emplace_back(insertStaticAlloca(B, sret));
1057 std::rotate(inputs.rbegin(), inputs.rbegin() + 1, inputs.rend());
1058 DerivedFunction::call(inputs, B, cast);
1059 return inputs.front();
1060 }
1061#endif
1062
1063 protected:
1064 /// @brief Forward all arguments to the derived class
1065 template <typename ...Args>
1066 SRetFunction(Args&&... ts) : DerivedFunction(ts...) {}
1067};
1068
1069/// @brief The base class for all C bindings.
1070 struct CFunctionBase : public Function
1071{
1072 using Ptr = std::shared_ptr<CFunctionBase>;
1073
1074 ~CFunctionBase() override = default;
1075
1076 /// @brief Returns the global address of this function.
1077 /// @note This is only required for C bindings.
1078 virtual uint64_t address() const = 0;
1079
1080 inline void setConstantFold(bool on) { mConstantFold = on; }
1081 inline bool hasConstantFold() const { return mConstantFold; }
1082
1083#if LLVM_VERSION_MAJOR <= 15
1084 OPENVDB_DEPRECATED
1085 inline virtual llvm::Value* fold(
1086 const std::vector<llvm::Value*>&,
1087 llvm::LLVMContext&) const
1088 {
1089 return nullptr;
1090 }
1091#else
1092 inline virtual llvm::Value* fold(
1093 const llvm::ArrayRef<llvm::Value*>&,
1094 llvm::LLVMContext&) const
1095 {
1096 return nullptr;
1097 }
1098#endif
1099
1100 protected:
1101 CFunctionBase(const size_t size,
1102 const std::string& symbol)
1103 : Function(size, symbol)
1104 , mConstantFold(false) {}
1105
1106 private:
1107 bool mConstantFold;
1108};
1109
1110/// @brief Represents a concrete C function binding.
1111///
1112/// @note This struct is templated on the signature to allow for evaluation of
1113/// the arguments to llvm types from any llvm context.
1114///
1115 template <typename SignatureT>
1116 struct CFunction : public CFunctionBase
1117{
1118 using CFunctionT = CFunction<SignatureT>;
1119 using Ptr = std::shared_ptr<CFunctionT>;
1120 using Traits = FunctionTraits<SignatureT>;
1121
1122 // Assert that the return argument is not a pointer (relaxed for void* for mallocs).
1123 // Note that this is relaxed for IR functions where it's allowed if the function is
1124 // forcefully inlined.
1125 static_assert(std::is_same<typename Traits::ReturnType, void*>::value ||
1126 !std::is_pointer<typename Traits::ReturnType>::value,
1127 "CFunction object has been setup with a pointer return argument. C bindings "
1128 "cannot return memory locations to LLVM - Consider using a CFunctionSRet.");
1129
1130 CFunction(const std::string& symbol, SignatureT* function)
1131 : CFunctionBase(Traits::N_ARGS, symbol)
1132 , mFunction(function) {}
1133
1134 ~CFunction() override = default;
1135
1136 inline ArgInfo types(ArgInfoVector& types, llvm::LLVMContext& C) const override
1137 {
1138 return llvmArgTypesFromSignature<SignatureT>(C, &types);
1139 }
1140
1141 inline uint64_t address() const override final
1142 {
1143 return reinterpret_cast<uint64_t>(mFunction);
1144 }
1145
1146 llvm::Value*
1147 call(const std::vector<llvm::Value*>& args,
1148 llvm::IRBuilder<>& B) const override
1149 {
1150 llvm::Value* result = this->fold(args, B.getContext());
1151 if (result) return result;
1152 return Function::call(args, B);
1153 }
1154
1155 Value call(const Arguments& args, llvm::IRBuilder<>& B) const override
1156 {
1157 llvm::Constant* result = this->fold(args.AsLLVMValues(), B.getContext());
1158 if (result) return Value(result);
1159 return Function::call(args, B);
1160 }
1161
1162#if LLVM_VERSION_MAJOR <= 15
1163 llvm::Constant* fold(const std::vector<llvm::Value*>& args, llvm::LLVMContext& C) const override final
1164#else
1165 llvm::Constant* fold(const llvm::ArrayRef<llvm::Value*>& args, llvm::LLVMContext& C) const override final
1166#endif
1167 {
1168 if (!this->hasConstantFold()) return nullptr;
1169 SmallArgumentVector<llvm::Constant*> constants;
1170 for (auto& value : args) {
1171 if (!llvm::isa<llvm::Constant>(value)) return nullptr;
1172 constants.emplace_back(llvm::cast<llvm::Constant>(value));
1173 }
1174 // no guarantee that fold() will be able to cast all arguments
1175 return ConstantFolder<SignatureT>::fold(constants, *mFunction, C);
1176 }
1177
1178#if LLVM_VERSION_MAJOR <= 15
1179 inline llvm::Type* types(std::vector<llvm::Type*>& types, llvm::LLVMContext& C) const override
1180 {
1181 return llvmTypesFromSignature<SignatureT>(C, &types);
1182 }
1183
1184 /// @note This is deprecated! Omitting the warning as it invokes the
1185 /// parent function which is also deprecated. Use NativeArguments to
1186 /// perform argument casting
1187 llvm::Value*
1188 call(const std::vector<llvm::Value*>& args,
1189 llvm::IRBuilder<>& B,
1190 const bool cast) const override
1191 {
1192 llvm::Value* result = this->fold(args, B.getContext());
1193 if (result) return result;
1194 return Function::call(args, B, cast);
1195 }
1196#endif
1197
1198 private:
1199 SignatureT* mFunction;
1200};
1201
1202/// @brief The base/abstract definition for an IR function.
1203 struct OPENVDB_AX_API IRFunctionBase : public Function
1204{
1205 using Ptr = std::shared_ptr<IRFunctionBase>;
1206
1207 /// @brief The IR callback function which will write the LLVM IR for this
1208 /// function's body.
1209 /// @details The first argument is the vector of functional arguments. i.e.
1210 /// a representation of the value that the callback has been invoked
1211 /// with.
1212 /// The last argument is the IR builder which should be used to
1213 /// generate the function body IR.
1214 /// @note You can return a ret void instruction, an actual value or
1215 /// Value::Invalid() which will cause the function framework to
1216 /// insert a ret void if necessary.
1217 using GeneratorNativeCb = std::function<Value
1218 (const NativeArguments&, llvm::IRBuilder<>&)>;
1219
1220 using GeneratorArgumentsCb = std::function<Value
1221 (const Arguments&, llvm::IRBuilder<>&)>;
1222
1223 /// @brief Legacy callback, will eventually be deprecated in favour of
1224 /// using the GeneratorArgumentsCb
1225 using GeneratorCb = std::function<llvm::Value*
1226 (const std::vector<llvm::Value*>&,
1227 llvm::IRBuilder<>&)>;
1228
1229 /// @brief Enable or disable the embedding of IR. Embedded IR is currently
1230 /// required for function which use parent function parameters.
1231 inline void setEmbedIR(bool on) { mEmbedIR = on; }
1232 inline bool hasEmbedIR() const { return mEmbedIR; }
1233
1234 /// @brief Override for the creation of an IR function. This ensures that
1235 /// the body and prototype of the function are generated if a Module
1236 /// is provided.
1237 /// @note A nullptr is returned if mEmbedIR is true and no action is
1238 /// performed.
1239 /// @note Throws if this function has been initialized with a nullptr
1240 /// generator callback. In this case, the function prototype will
1241 /// be created, but not the function body.
1242 /// @note Throws if the return type of the generator callback does not
1243 /// match the function prototype. In this case, both the prototype
1244 /// and the function body will be created and inserted, but the IR
1245 /// will be invalid.
1246 llvm::Function*
1247 create(llvm::LLVMContext& C, llvm::Module* M) const override;
1248
1249 /// @brief Override for call, which is only necessary if mEmbedIR is true,
1250 /// as the IR generation for embedded functions is delayed until
1251 /// the function is called. If mEmbedIR is false, this simply calls
1252 /// Function::call
1253 llvm::Value*
1254 call(const std::vector<llvm::Value*>& args,
1255 llvm::IRBuilder<>& B) const override;
1256
1257 Value call(const Arguments& args, llvm::IRBuilder<>&) const override;
1258
1259#if LLVM_VERSION_MAJOR <= 15
1260 // @note This is deprecated! Omitting the warning as it invokes the
1261 // parent function which is also deprecated
1262 llvm::Value*
1263 call(const std::vector<llvm::Value*>& args,
1264 llvm::IRBuilder<>& B,
1265 const bool cast) const override;
1266#endif
1267
1268 protected:
1269
1270 // @todo This should ideally live in FunctionGroup::execute, but the return
1271 // type is allowed to differ for sret C bindings.
1272 inline void
1273 verifyResultType(const llvm::Type* result, const llvm::Type* expected) const
1274 {
1275 if (result == expected) return;
1276 std::string source, target;
1277 if (result) llvmTypeToString(result, source);
1278 llvmTypeToString(expected, target);
1279 OPENVDB_THROW(AXCodeGenError, "Function \"" + std::string(this->symbol()) +
1280 "\" has been invoked with a mismatching return type. Expected: \"" +
1281 target + "\", got \"" + source + "\".");
1282 }
1283 IRFunctionBase(const std::string& symbol,
1284 const GeneratorCb& gen,
1285 const size_t size)
1286 : Function(size, symbol)
1287 , mGen([this, gen](const Arguments& args, llvm::IRBuilder<>& B) {
1288 llvm::Value* result = gen(args.AsLLVMValues(), B);
1289 if (!result) return Value::Invalid();
1290 // For older callbacks, we have to figure out the type from the
1291 // function signature if the return type is a ptr (from LLVM 16
1292 // onwards)
1293 if (result->getType()->isPointerTy())
1294 {
1295#if LLVM_VERSION_MAJOR <= 15
1296 return Value(result, result->getType()->getPointerElementType());
1297#else
1298 ArgInfoVector unused;
1299 ArgInfo r = this->types(unused, result->getContext());
1300 return Value(result, r.GetUnderlyingType());
1301#endif
1302 }
1303 else {
1304 // otherwise, can we introspec the type directly
1305 return Value(result, result->getType());
1306 }
1307 })
1308 , mEmbedIR(false) {}
1309 IRFunctionBase(const std::string& symbol,
1310 const GeneratorNativeCb& gen,
1311 const size_t size)
1312 : Function(size, symbol)
1313 , mGen([gen](const Arguments& args, llvm::IRBuilder<>& B) {
1314 OPENVDB_ASSERT(args.AreNativeValues());
1315 return gen(args.AsNativeValues(), B);
1316 })
1317 , mEmbedIR(false) {}
1318 IRFunctionBase(const std::string& symbol,
1319 const GeneratorArgumentsCb& gen,
1320 const size_t size)
1321 : Function(size, symbol)
1322 , mGen(gen)
1323 , mEmbedIR(false) {}
1324 ~IRFunctionBase() override = default;
1325
1326 const GeneratorArgumentsCb mGen;
1327 bool mEmbedIR;
1328};
1329
1330/// @brief Represents a concrete IR function.
1331 template <typename SignatureT>
1332 struct IRFunction : public IRFunctionBase
1333{
1334 using Traits = FunctionTraits<SignatureT>;
1335 using Ptr = std::shared_ptr<IRFunction>;
1336
1337 IRFunction(const std::string& symbol, const GeneratorCb& gen)
1338 : IRFunctionBase(symbol, gen, Traits::N_ARGS) {}
1339 IRFunction(const std::string& symbol, const GeneratorNativeCb& gen)
1340 : IRFunctionBase(symbol, gen, Traits::N_ARGS) {}
1341 IRFunction(const std::string& symbol, const GeneratorArgumentsCb& gen)
1342 : IRFunctionBase(symbol, gen, Traits::N_ARGS) {}
1343
1344 inline ArgInfo types(ArgInfoVector& types, llvm::LLVMContext& C) const override
1345 {
1346 return llvmArgTypesFromSignature<SignatureT>(C, &types);
1347 }
1348
1349#if LLVM_VERSION_MAJOR <= 15
1350 inline llvm::Type*
1351 types(std::vector<llvm::Type*>& types, llvm::LLVMContext& C) const override
1352 {
1353 return llvmTypesFromSignature<SignatureT>(C, &types);
1354 }
1355#endif
1356};
1357
1358/// @brief Represents a concrete C function binding with the first argument as
1359/// its return type.
1360 template <typename SignatureT>
1361 struct CFunctionSRet : public SRetFunction<SignatureT, CFunction<SignatureT>>
1362{
1363 using BaseT = SRetFunction<SignatureT, CFunction<SignatureT>>;
1364 CFunctionSRet(const std::string& symbol, const SignatureT function)
1365 : BaseT(symbol, function) {}
1366 ~CFunctionSRet() override = default;
1367};
1368
1369/// @brief Represents a concrete IR function with the first argument as
1370/// its return type.
1371 template <typename SignatureT>
1372 struct IRFunctionSRet : public SRetFunction<SignatureT, IRFunction<SignatureT>>
1373{
1374 using BaseT = SRetFunction<SignatureT, IRFunction<SignatureT>>;
1375 IRFunctionSRet(const std::string& symbol,
1376 const IRFunctionBase::GeneratorCb& gen)
1377 : BaseT(symbol, gen) {}
1378 IRFunctionSRet(const std::string& symbol,
1379 const IRFunctionBase::GeneratorNativeCb& gen)
1380 : BaseT(symbol, gen) {}
1381 IRFunctionSRet(const std::string& symbol,
1382 const IRFunctionBase::GeneratorArgumentsCb& gen)
1383 : BaseT(symbol, gen) {}
1384
1385 ~IRFunctionSRet() override = default;
1386};
1387
1388/// @brief A group of functions which all have the same name but different
1389/// signatures. For example:
1390/// float abs(float)
1391/// double abs(double)
1392/// As well as serving as a way of grouping common functions, this class
1393/// provides an API for selecting the best possible function signature,
1394/// should a match exist, against a provided set of argument types.
1395 struct OPENVDB_AX_API FunctionGroup
1396{
1397 using Ptr = std::shared_ptr<FunctionGroup>;
1398 using UniquePtr = std::unique_ptr<FunctionGroup>;
1399 using FunctionList = std::vector<Function::Ptr>;
1400
1401 FunctionGroup(const char* name,
1402 const char* doc,
1403 const FunctionList& list)
1404 : mName(name)
1405 , mDoc(doc)
1406 , mFunctionList(list) {}
1407 ~FunctionGroup() = default;
1408
1409 /// @brief Verify the function signatures in this group.
1410 bool HasUniqueTypeSignatures(llvm::LLVMContext& C) const;
1411
1412 /// @brief Given a vector of llvm types, automatically returns the best
1413 /// possible function declaration from the stored function list. The
1414 /// 'best' declaration is determined by the provided types
1415 /// compatibility to each functions signature.
1416 /// @note Returns a nullptr if no compatible match was found or if the
1417 /// function list is empty. A compatible match is defined as an
1418 /// Explicit, Implicit or Ambiguous match (where the latter returns
1419 /// the first matched implicit function where other implicit
1420 /// matches exist).
1421 ///
1422 /// @note If multiple implicit matches are found, the first match is
1423 /// returned and 'type' is set to Ambiguous (if provided).
1424 /// @warning All funcions in this group must implement the types(ArgInfo)
1425 /// virtual function, which is optional in LLVM 15 but required from
1426 /// LLVM 16.
1427 ///
1428 /// @param types A vector of types representing the function argument types
1429 /// @param C The llvm context
1430 /// @param type If provided, type is set to the type of match that occurred
1431 std::pair<const Function*, Function::SignatureMatch>
1432 match(const ArgInfoVector& args, llvm::LLVMContext& C) const;
1433
1434 /// @brief Given a set of Arguments, find an EXPLICIT signature match,
1435 /// generate and execute the function body. If no explicit match
1436 /// exists, Value::Invalid() is returned.
1437 /// @note To ensure something is matched/executed, consider calling
1438 /// match() and Function::call instead. This method should only be
1439 /// used by internal methods that can assert an explicit match
1440 /// exists.
1441 ///
1442 /// @param args Function arguments
1443 /// @param B The current llvm IRBuilder
1444 Value execute(const Arguments& args, llvm::IRBuilder<>& B) const;
1445
1446 /// @brief Given a set of NativeArguments, find the best possible function
1447 /// signature, generate and execute the function body. Returns the
1448 /// return value of the function or Value::Invalid() if no Explicit
1449 /// or Implicit match is found.
1450 /// @note This function will throw if no valid return is provided by the
1451 /// matched declaration implementation.
1452 ///
1453 /// @param args Natively supported function arguments
1454 /// @param B The current llvm IRBuilder
1455 Value execute(const NativeArguments& args, llvm::IRBuilder<>& B) const;
1456
1457 /// @brief Accessor to the underlying function signature list
1458 inline const FunctionList& list() const { return mFunctionList; }
1459 const char* name() const { return mName; }
1460 const char* doc() const { return mDoc; }
1461
1462#if LLVM_VERSION_MAJOR <= 15
1463 /// @warning Does not support detecting Ambiguous functions (returns Implicit
1464 /// in these cases).
1465 OPENVDB_DEPRECATED_MESSAGE("Switch to AX's internal ArgInfo types for LLVM 16 onwards")
1466 const Function*
1467 match(const std::vector<llvm::Type*>& types,
1468 llvm::LLVMContext& C,
1469 Function::SignatureMatch* type = nullptr) const;
1470
1471 OPENVDB_DEPRECATED_MESSAGE("FunctionGroup::execute which takes llvm::Value's and "
1472 "supports argument matching/casting is incompatible with LLVM 16+ and will be "
1473 "removed.")
1474 llvm::Value*
1475 execute(const std::vector<llvm::Value*>& args,
1476 llvm::IRBuilder<>& B) const;
1477
1478 /// @brief Given a vector of llvm values, find the best possible function
1479 /// signature, generate and execute the function body. Returns the
1480 /// Function that was selected and executed or a nullptr if no
1481 /// valid match was found. Sets the result variable to the return
1482 /// value of the function (nullptr if void). If no match is found,
1483 /// the result variable if left unset.
1484 /// @note This function will throw if no valid return is provided by the
1485 /// matched declaration implementation.
1486 ///
1487 /// @param args A vector of values representing the function arguments
1488 /// @param B The current llvm IRBuilder
1489 /// @param result The result to set. nullptr on void return.
1490 /// @return The matched function. nullptr if no match was found
1491 OPENVDB_DEPRECATED_MESSAGE("FunctionGroup::execute which takes llvm::Value's and "
1492 "supports argument matching/casting is incompatible with LLVM 16+ and will be "
1493 "removed.")
1494 const Function*
1495 execute(const std::vector<llvm::Value*>& args,
1496 llvm::IRBuilder<>& B,
1497 llvm::Value*& result) const;
1498#endif
1499
1500 private:
1501 const char* mName;
1502 const char* mDoc;
1503 const FunctionList mFunctionList;
1504};
1505
1506/// @brief The FunctionBuilder class provides a builder pattern framework to
1507/// allow easy and valid construction of AX functions. There are a
1508/// number of complex tasks which may need to be performed during
1509/// construction of C or IR function which are delegated to this
1510/// builder, whilst ensuring that the constructed functions are
1511/// guaranteed to be valid.
1512/// @details Use the FunctionBuilder::addSignature methods to append function
1513/// signatures. Finalize the group of functions with
1514/// FunctionBuilder::get.
1515 struct FunctionBuilder
1516{
1517 enum DeclPreferrence {
1518 C, IR, Any
1519 };
1520
1521 struct Settings
1522 {
1523 using Ptr = std::shared_ptr<Settings>;
1524
1525 inline bool isDefault() const
1526 {
1527 if (mNames) return false;
1528 if (mType != Function::Type::kNormal) return false;
1529 if (!mDeps.empty()) return false;
1530 if (mConstantFold || mEmbedIR || mReadOnly) return false;
1531 if (!mFnAttrs.empty()) return false;
1532 if (!mRetAttrs.empty()) return false;
1533 if (!mParamAttrs.empty()) return false;
1534 return true;
1535 }
1536
1537 std::unique_ptr<SmallArgumentVector<const char*>> mNames = nullptr;
1538 SmallArgumentVector<const char*> mDeps = {};
1539 bool mConstantFold = false;
1540 bool mEmbedIR = false;
1541 bool mReadOnly = false;
1542 Function::Type mType = Function::Type::kNormal;
1543 SmallArgumentVector<llvm::Attribute::AttrKind> mFnAttrs = {};
1544 SmallArgumentVector<llvm::Attribute::AttrKind> mRetAttrs = {};
1545 std::map<size_t, SmallArgumentVector<llvm::Attribute::AttrKind>> mParamAttrs = {};
1546 };
1547
1548 FunctionBuilder(const char* name)
1549 : mName(name)
1550 , mCurrentSettings(std::make_shared<Settings>()) {}
1551
1552 // C-Binding
1553 template <typename Signature, bool SRet = false>
1554 inline FunctionBuilder&
1555 addSignature(const Signature* ptr, const char* symbol = nullptr)
1556 {
1557 using CFType = typename std::conditional
1558 <!SRet, CFunction<Signature>, CFunctionSRet<Signature>>::type;
1559 const std::string s = symbol ? symbol : this->genSymbol<Signature>();
1560 this->addSignatureImpl<CFType>(s, ptr);
1561 return *this;
1562 }
1563
1564 // Non native Binding
1565 template <typename Signature, bool SRet = false>
1566 inline FunctionBuilder&
1567 addSignature(const IRFunctionBase::GeneratorCb& cb,
1568 const char* symbol = nullptr)
1569 {
1570 using IRFType = typename std::conditional
1571 <!SRet, IRFunction<Signature>, IRFunctionSRet<Signature>>::type;
1572 OPENVDB_ASSERT(!(SRet && mCurrentSettings->mReadOnly));
1573 const std::string s = symbol ? symbol : this->genSymbol<Signature>();
1574 this->addSignatureImpl<IRFType>(s, cb);
1575 return *this;
1576 }
1577
1578 // Non native Binding
1579 template <typename Signature, bool SRet = false>
1580 inline FunctionBuilder&
1581 addSignature(const IRFunctionBase::GeneratorCb& cb, const Signature* ptr, const char* symbol = nullptr)
1582 {
1583 this->addSignature<Signature, SRet>(cb, symbol);
1584 this->addSignature<Signature, SRet>(ptr, symbol);
1585 return *this;
1586 }
1587
1588 // Native Binding
1589 template <typename Signature, bool SRet = false>
1590 inline FunctionBuilder&
1591 addSignature(const IRFunctionBase::GeneratorNativeCb& cb, const char* symbol = nullptr)
1592 {
1593 static_assert(ArgumentIterator<Signature>::IsNativeSignature);
1594 using IRFType = typename std::conditional
1595 <!SRet, IRFunction<Signature>, IRFunctionSRet<Signature>>::type;
1596 OPENVDB_ASSERT(!(SRet && mCurrentSettings->mReadOnly));
1597 const std::string s = symbol ? symbol : this->genSymbol<Signature>();
1598 this->addSignatureImpl<IRFType>(s, cb);
1599 return *this;
1600 }
1601
1602 // Native Binding
1603 template <typename Signature, bool SRet = false>
1604 inline FunctionBuilder&
1605 addSignature(const IRFunctionBase::GeneratorNativeCb& cb, const Signature* ptr, const char* symbol = nullptr)
1606 {
1607 static_assert(ArgumentIterator<Signature>::IsNativeSignature);
1608 this->addSignature<Signature, SRet>(cb, symbol);
1609 this->addSignature<Signature, SRet>(ptr, symbol);
1610 return *this;
1611 }
1612
1613 // Native Binding
1614 template <typename Signature, bool SRet = false>
1615 inline FunctionBuilder&
1616 addSignature(const IRFunctionBase::GeneratorArgumentsCb& cb,
1617 const char* symbol = nullptr)
1618 {
1619 using IRFType = typename std::conditional
1620 <!SRet, IRFunction<Signature>, IRFunctionSRet<Signature>>::type;
1621 OPENVDB_ASSERT(!(SRet && mCurrentSettings->mReadOnly));
1622 const std::string s = symbol ? symbol : this->genSymbol<Signature>();
1623 this->addSignatureImpl<IRFType>(s, cb);
1624 return *this;
1625 }
1626
1627 // Native Binding
1628 template <typename Signature, bool SRet = false>
1629 inline FunctionBuilder&
1630 addSignature(const IRFunctionBase::GeneratorArgumentsCb& cb, const Signature* ptr, const char* symbol = nullptr)
1631 {
1632 this->addSignature<Signature, SRet>(cb, symbol);
1633 this->addSignature<Signature, SRet>(ptr, symbol);
1634 return *this;
1635 }
1636
1637 inline FunctionBuilder& addDependency(const char* name)
1638 {
1639 mCurrentSettings->mDeps.emplace_back(name); return *this;
1640 }
1641
1642 inline FunctionBuilder& setEmbedIR(bool on) { mCurrentSettings->mEmbedIR = on; return *this; }
1643 inline FunctionBuilder& setConstantFold(bool on) { mCurrentSettings->mConstantFold = on; return *this; }
1644 inline FunctionBuilder& setArgumentNames(const std::vector<const char*>& names)
1645 {
1646 mCurrentSettings->mNames = std::make_unique<SmallArgumentVector<const char*>>();
1647 mCurrentSettings->mNames->assign(names.begin(), names.end());
1648 return *this;
1649 }
1650
1651 /// @brief Parameter and Function Attributes. When designing a C binding,
1652 /// llvm will be unable to assign parameter markings to the return
1653 /// type, function body or parameter attributes due to there not
1654 /// being any visibility on the function itself during codegen.
1655 /// The best way to ensure performant C bindings is to ensure
1656 /// that the function is marked with the required llvm parameters.
1657 /// @note Some of the most common are shown in FunctionBuilder::setBuiltin,
1658 /// but also consider FunctionBuilder::setReadOnly
1659 inline FunctionBuilder&
1660 addParameterAttribute(const size_t idx, const llvm::Attribute::AttrKind attr)
1661 {
1662 mCurrentSettings->mParamAttrs[idx].emplace_back(attr);
1663 return *this;
1664 }
1665
1666 inline FunctionBuilder&
1667 addReturnAttribute(const llvm::Attribute::AttrKind attr)
1668 {
1669 mCurrentSettings->mRetAttrs.emplace_back(attr);
1670 return *this;
1671 }
1672
1673 inline FunctionBuilder&
1674 addFunctionAttribute(const llvm::Attribute::AttrKind attr)
1675 {
1676 mCurrentSettings->mFnAttrs.emplace_back(attr);
1677 return *this;
1678 }
1679
1680 /// @brief Mark functions currently sharing settings with as "readonly".
1681 /// This enables the strictest possible memory effects for this function
1682 /// in llvm and implies that the function does not write to any memory
1683 /// (i.e. CreateStore) and only reads memory directly from its function
1684 /// arguments (i.e. nothing external to the function). Functions marked
1685 /// as "readonly" but do not adhere to the above will cause UB.
1686 /// @note Obviously invalid for SRET functions!
1687 inline FunctionBuilder&
1688 setReadOnly(const bool on)
1689 {
1690 mCurrentSettings->mReadOnly = on;
1691 return *this;
1692 }
1693
1694 /// @brief Mark functions currently sharing settings as builtin AX methods.
1695 /// At compile time, this causes the IR function body, arguments and
1696 /// return value to be marked with a set of default attributes that
1697 /// apply to all builtin methods, as they are expected to only be called
1698 /// by AX programs. Currently this results in:
1699 ///
1700 /// Function Attributes:
1701 /// llvm::Attribute::NoFree
1702 /// llvm::Attribute::WillReturn
1703 /// llvm::Attribute::NoRecurse
1704 /// llvm::Attribute::NoUnwind
1705 /// llvm::Attribute::AlwaysInline
1706 /// Return Attributes: -
1707 /// Parameter Attributes (Ptrs):
1708 /// llvm::Attribute::NonNull
1709 /// llvm::Attribute::NoUndef
1710 /// llvm::Attribute::NoFree
1711 /// llvm::Attribute::NoCapture / (llvm::CaptureInfo::none() from LLVM 21)
1712 ///
1713 /// @warning Attributes in this method may be extended - as such, you
1714 /// should mark external function with individual attributes instead of
1715 /// calling this.
1716 inline FunctionBuilder&
1717 setBuiltin()
1718 {
1719 // note that we have to defer the attribute setting to compile time as
1720 // various attributes need to know the function types. Would be nice if
1721 // we could do it all in the builder.
1722 mCurrentSettings->mType = Function::Type::kBuiltin;
1723 return *this;
1724 }
1725
1726 /// @brief Mark this function as an external kernel entry point. Should
1727 /// only be used by the ComputeGenerators. Results in a number of function
1728 /// attributes/parameters being set.
1729 inline FunctionBuilder&
1730 setExternalKernel()
1731 {
1732 mCurrentSettings->mType = Function::Type::kKernel;
1733 return *this;
1734 }
1735
1736 inline FunctionBuilder& setDocumentation(const char* doc)
1737 {
1738 mDoc = doc;
1739 return *this;
1740 }
1741
1742 inline FunctionBuilder& setPreferredImpl(DeclPreferrence pref)
1743 {
1744 mDeclPref = pref;
1745 return *this;
1746 }
1747
1748 inline FunctionGroup::UniquePtr get() const
1749 {
1750 for (auto& decl : mCFunctions)
1751 {
1752 const auto& s = mSettings.at(decl.get());
1753 if (s->mNames) decl->mNames = *s->mNames;
1754 decl->mDeps = s->mDeps;
1755 decl->setConstantFold(s->mConstantFold);
1756 if (!s->mFnAttrs.empty()) decl->attrs().mFnAttrs = s->mFnAttrs;
1757 if (!s->mRetAttrs.empty()) decl->attrs().mRetAttrs = s->mRetAttrs;
1758 if (!s->mParamAttrs.empty()) {
1759 for (auto& idxAttrs : s->mParamAttrs) {
1760 if (idxAttrs.first > decl->size()) continue;
1761 decl->attrs().mParamAttrs[idxAttrs.first] = idxAttrs.second;
1762 }
1763 }
1764 if (s->mReadOnly) decl->attrs().mReadOnly = true;
1765 if (s->mType != Function::Type::kNormal) {
1766 decl->attrs().mType = s->mType;
1767 }
1768 }
1769
1770 for (auto& decl : mIRFunctions)
1771 {
1772 const auto& s = mSettings.at(decl.get());
1773 if (s->mNames) decl->mNames = *s->mNames;
1774 decl->mDeps = s->mDeps;
1775 decl->setEmbedIR(s->mEmbedIR);
1776 if (!s->mFnAttrs.empty()) decl->attrs().mFnAttrs = s->mFnAttrs;
1777 if (!s->mRetAttrs.empty()) decl->attrs().mRetAttrs = s->mRetAttrs;
1778 if (!s->mParamAttrs.empty()) {
1779 for (auto& idxAttrs : s->mParamAttrs) {
1780 if (idxAttrs.first > decl->size()) continue;
1781 decl->attrs().mParamAttrs[idxAttrs.first] = idxAttrs.second;
1782 }
1783 }
1784 if (s->mReadOnly) decl->attrs().mReadOnly = true;
1785 if (s->mType != Function::Type::kNormal) {
1786 decl->attrs().mType = s->mType;
1787 }
1788 }
1789
1790 FunctionGroup::FunctionList functions;
1791
1792 if (mDeclPref == DeclPreferrence::IR) {
1793 functions.insert(functions.end(), mIRFunctions.begin(), mIRFunctions.end());
1794 }
1795 if (mDeclPref == DeclPreferrence::C) {
1796 functions.insert(functions.end(), mCFunctions.begin(), mCFunctions.end());
1797 }
1798 if (functions.empty()) {
1799 functions.insert(functions.end(), mIRFunctions.begin(), mIRFunctions.end());
1800 functions.insert(functions.end(), mCFunctions.begin(), mCFunctions.end());
1801 }
1802
1803 return std::make_unique<FunctionGroup>(mName, mDoc, std::move(functions));
1804 }
1805
1806 private:
1807 template <typename FunctionT, typename...Args>
1808 inline FunctionBuilder& addSignatureImpl(Args&& ...args)
1809 {
1810 Settings::Ptr settings = mCurrentSettings;
1811 if (!mCurrentSettings->isDefault()) {
1812 settings = std::make_shared<Settings>();
1813 }
1814 auto ptr = std::make_shared<FunctionT>(std::move(args)...);
1815 if constexpr (std::is_base_of_v<IRFunctionBase, FunctionT>) {
1816 mIRFunctions.emplace_back(ptr);
1817 }
1818 else {
1819 static_assert(std::is_base_of_v<CFunctionBase, FunctionT>);
1820 mCFunctions.emplace_back(ptr);
1821 }
1822 mSettings[ptr.get()] = settings;
1823 mCurrentSettings = settings;
1824 return *this;
1825 }
1826
1827 template <typename Signature>
1828 std::string genSymbol() const
1829 {
1830 using Traits = FunctionTraits<Signature>;
1831
1832 std::string args;
1833 auto callback = [&args](auto type) {
1834 using Type = decltype(type);
1835 args += TypeToSymbol<Type>::s();
1836 };
1837
1838 ArgumentIterator<Signature>::apply(callback, /*forwards*/true);
1839 /// @note important to prefix all symbols with "ax." so that
1840 /// they will never conflict with internal llvm symbol
1841 /// names (such as standard library methods e.g, cos, cosh
1842
1843 // assemble the symbol
1844 return "ax." + std::string(this->mName) + "." +
1845 TypeToSymbol<typename Traits::ReturnType>::s() + args;
1846 }
1847
1848 private:
1849 const char* mName = "";
1850 const char* mDoc = "";
1851 DeclPreferrence mDeclPref = IR;
1852 std::vector<CFunctionBase::Ptr> mCFunctions = {};
1853 std::vector<IRFunctionBase::Ptr> mIRFunctions = {};
1854 std::map<const Function*, Settings::Ptr> mSettings = {};
1855 Settings::Ptr mCurrentSettings = nullptr;
1856};
1857
1858} // namespace codegen
1859} // namespace ax
1860} // namespace OPENVDB_VERSION_NAME
1861} // namespace openvdb
1862
1863#endif // OPENVDB_AX_CODEGEN_FUNCTION_TYPES_HAS_BEEN_INCLUDED
1864
Assert.h
OPENVDB_ASSERT_MESSAGE
#define OPENVDB_ASSERT_MESSAGE(X, MSG)
Definition Assert.h:42
OPENVDB_ASSERT
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
ConstantFolding.h
Constant folding for C++ bindings.
OPENVDB_AX_API
#define OPENVDB_AX_API
Definition Platform.h:312
OPENVDB_DEPRECATED
#define OPENVDB_DEPRECATED
Definition Platform.h:170
OPENVDB_DEPRECATED_MESSAGE
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition Platform.h:171
Value.h
Intermediate representation of supported AX values.
Types.h
Consolidated llvm types for most supported types.
openvdb::v13_0::AXCodeGenError
Definition Exceptions.h:38
openvdb::v13_0::ax::codegen::Value
Intermediate representation wrapper for supported value types in AX as immutable instances.
Definition Value.h:63
openvdb::v13_0::ax::codegen::Value::Alloc
static Value Alloc(llvm::IRBuilder<> &B, llvm::Type *type, llvm::Value *size=nullptr)
Emit IR inserting an allocation at the front of the BasicBlock pointed to by the provided IRBuilder....
Definition Value.h:124
openvdb::v13_0::ax::codegen::Value::GetValue
llvm::Value * GetValue() const
Access the underlying llvm Value.
Definition Value.h:673
openvdb::v13_0::ax::codegen::Value::Invalid
static Value Invalid()
Return an invalid Value. This is used to represent various fail cases. Note that the operator bool(Va...
Definition Value.h:88
openvdb::v13_0::ax::codegen::Value::Supports
static bool Supports(llvm::Type *utype)
Return true if the underlying type held by utype is supported via the interface of this Value class.
Definition Value.h:109
llvm
Definition FunctionRegistry.h:23
openvdb::v13_0::ax::codegen
Definition Codecs.h:18
openvdb::v13_0::ax::codegen::M4F
ArgType< float, 16 > M4F
Definition FunctionTypes.h:139
openvdb::v13_0::ax::codegen::llvmTypesFromSignature
llvm::Type * llvmTypesFromSignature(llvm::LLVMContext &C, std::vector< llvm::Type * > *types=nullptr)
Populate a vector of llvm types from a function signature declaration.
Definition FunctionTypes.h:479
openvdb::v13_0::ax::codegen::V2D
ArgType< double, 2 > V2D
Definition FunctionTypes.h:127
openvdb::v13_0::ax::codegen::V4I
ArgType< int32_t, 4 > V4I
Definition FunctionTypes.h:135
openvdb::v13_0::ax::codegen::llvmArgTypesFromSignature
ArgInfo llvmArgTypesFromSignature(llvm::LLVMContext &C, ArgInfoVector *types=nullptr)
Populate a vector of ArgInfos from a function signature declaration.
Definition FunctionTypes.h:506
openvdb::v13_0::ax::codegen::V3F
ArgType< float, 3 > V3F
Definition FunctionTypes.h:131
openvdb::v13_0::ax::codegen::insertStaticAlloca
llvm::Value * insertStaticAlloca(llvm::IRBuilder<> &B, llvm::Type *type, llvm::Value *size=nullptr)
Insert a stack allocation at the beginning of the current function of the provided type and size....
Definition Utils.h:117
openvdb::v13_0::ax::codegen::llvmTypeToString
void llvmTypeToString(const llvm::Type *const type, std::string &str)
Prints an llvm type to a std string.
Definition Utils.h:80
openvdb::v13_0::ax::codegen::M3D
ArgType< double, 9 > M3D
Definition FunctionTypes.h:136
openvdb::v13_0::ax::codegen::M4D
ArgType< double, 16 > M4D
Definition FunctionTypes.h:138
openvdb::v13_0::ax::codegen::V4F
ArgType< float, 4 > V4F
Definition FunctionTypes.h:134
openvdb::v13_0::ax::codegen::V3I
ArgType< int32_t, 3 > V3I
Definition FunctionTypes.h:132
openvdb::v13_0::ax::codegen::llvmFunctionTypeFromSignature
llvm::FunctionType * llvmFunctionTypeFromSignature(llvm::LLVMContext &C)
Generate an LLVM FunctionType from a function signature.
Definition FunctionTypes.h:554
openvdb::v13_0::ax::codegen::V4D
ArgType< double, 4 > V4D
Definition FunctionTypes.h:133
openvdb::v13_0::ax::codegen::printSignature
OPENVDB_AX_API void printSignature(std::ostream &os, const ArgInfoVector &types, const ArgInfo &returnType, const char *name=nullptr, const llvm::ArrayRef< const char * > &names={}, const bool axTypes=false)
Print a function signature to the provided ostream.
openvdb::v13_0::ax::codegen::M3F
ArgType< float, 9 > M3F
Definition FunctionTypes.h:137
openvdb::v13_0::ax::codegen::V2I
ArgType< int32_t, 2 > V2I
Definition FunctionTypes.h:129
openvdb::v13_0::ax::codegen::SmallArgumentVector
llvm::SmallVector< T, 3 > SmallArgumentVector
Typedef a stack allocated array with malloc grow support for anything which is relatively small and b...
Definition FunctionTypes.h:110
openvdb::v13_0::ax::codegen::V2F
ArgType< float, 2 > V2F
Definition FunctionTypes.h:128
openvdb::v13_0::ax::codegen::V3D
ArgType< double, 3 > V3D
Definition FunctionTypes.h:130
openvdb::v13_0::ax::math
Definition OpenSimplexNoise.h:31
openvdb
Definition Exceptions.h:13
std
Definition Coord.h:590
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Utils.h
Utility code generation methods for performing various llvm operations.
openvdb::v13_0::ax::codegen::AliasTypeMap
Alias mapping between two types, a frontend type T1 and a backend type T2. This class is the intended...
Definition Types.h:269
openvdb::v13_0::ax::codegen::ArgInfo
Metadata associated with a function argument or return value.
Definition FunctionTypes.h:225
openvdb::v13_0::ax::codegen::ArgInfo::operator=
ArgInfo & operator=(ArgInfo &&)=default
openvdb::v13_0::ax::codegen::ArgInfo::IsPtr
bool IsPtr() const
Definition FunctionTypes.h:254
openvdb::v13_0::ax::codegen::ArgInfo::ArgInfo
ArgInfo(llvm::Type *utype)
Definition FunctionTypes.h:228
openvdb::v13_0::ax::codegen::ArgInfo::IsVoid
bool IsVoid() const
Definition FunctionTypes.h:257
openvdb::v13_0::ax::codegen::ArgInfo::ArgInfo
ArgInfo(const Value &val)
Definition FunctionTypes.h:226
openvdb::v13_0::ax::codegen::ArgInfo::IsNative
bool IsNative() const
Definition FunctionTypes.h:256
openvdb::v13_0::ax::codegen::ArgInfo::ArgInfo
ArgInfo(const ArgInfo &)=default
openvdb::v13_0::ax::codegen::ArgInfo::operator!=
bool operator!=(const ArgInfo &other) const
Definition FunctionTypes.h:247
openvdb::v13_0::ax::codegen::ArgInfo::NumPtrs
uint8_t NumPtrs() const
Definition FunctionTypes.h:255
openvdb::v13_0::ax::codegen::ArgInfo::IsReturn
bool IsReturn() const
Definition FunctionTypes.h:258
openvdb::v13_0::ax::codegen::ArgInfo::operator=
ArgInfo & operator=(const ArgInfo &)=default
openvdb::v13_0::ax::codegen::ArgInfo::operator==
bool operator==(const ArgInfo &other) const
Definition FunctionTypes.h:240
openvdb::v13_0::ax::codegen::ArgInfo::IsMatchingType
bool IsMatchingType(const ArgInfo &other) const
Definition FunctionTypes.h:248
openvdb::v13_0::ax::codegen::ArgInfo::GetUnderlyingType
llvm::Type * GetUnderlyingType() const
Definition FunctionTypes.h:259
openvdb::v13_0::ax::codegen::ArgInfo::ArgInfo
ArgInfo(llvm::Type *utype, uint8_t ptrs, bool ret=false)
Definition FunctionTypes.h:229
openvdb::v13_0::ax::codegen::ArgInfo::ArgInfo
ArgInfo(ArgInfo &&)=default
openvdb::v13_0::ax::codegen::ArgInfo::SetIsReturn
void SetIsReturn()
Definition FunctionTypes.h:268
openvdb::v13_0::ax::codegen::ArgInfo::GetType
llvm::Type * GetType() const
Definition FunctionTypes.h:260
openvdb::v13_0::ax::codegen::ArgInfoVector
Container of ArgInfos. This class makes up part of the Function API for querying signature informatio...
Definition FunctionTypes.h:280
openvdb::v13_0::ax::codegen::ArgInfoVector::size
auto size() const
Definition FunctionTypes.h:309
openvdb::v13_0::ax::codegen::ArgInfoVector::operator!=
bool operator!=(const ArgInfoVector &other) const
Definition FunctionTypes.h:293
openvdb::v13_0::ax::codegen::ArgInfoVector::AsLLVMTypes
SmallArgumentVector< llvm::Type * > AsLLVMTypes() const
Definition FunctionTypes.h:327
openvdb::v13_0::ax::codegen::ArgInfoVector::operator=
ArgInfoVector & operator=(const ArgInfoVector &)=default
openvdb::v13_0::ax::codegen::ArgInfoVector::ArgInfoVector
ArgInfoVector(const ArgInfoVector &)=default
openvdb::v13_0::ax::codegen::ArgInfoVector::clear
auto clear()
Definition FunctionTypes.h:308
openvdb::v13_0::ax::codegen::ArgInfoVector::rend
auto rend() const
Definition FunctionTypes.h:302
openvdb::v13_0::ax::codegen::ArgInfoVector::reserve
void reserve(size_t i)
Definition FunctionTypes.h:313
openvdb::v13_0::ax::codegen::ArgInfoVector::rend
auto rend()
Definition FunctionTypes.h:300
openvdb::v13_0::ax::codegen::ArgInfoVector::erase
auto erase(ContainerT::const_iterator iter)
Definition FunctionTypes.h:311
openvdb::v13_0::ax::codegen::ArgInfoVector::back
auto & back()
Definition FunctionTypes.h:305
openvdb::v13_0::ax::codegen::ArgInfoVector::ContainerT
SmallArgumentVector< ArgInfo > ContainerT
Definition FunctionTypes.h:282
openvdb::v13_0::ax::codegen::ArgInfoVector::front
auto & front()
Definition FunctionTypes.h:303
openvdb::v13_0::ax::codegen::ArgInfoVector::end
auto end()
Definition FunctionTypes.h:296
openvdb::v13_0::ax::codegen::ArgInfoVector::ArgInfoVector
ArgInfoVector()=default
openvdb::v13_0::ax::codegen::ArgInfoVector::operator[]
ArgInfo & operator[](size_t pos)
Definition FunctionTypes.h:316
openvdb::v13_0::ax::codegen::ArgInfoVector::operator[]
const ArgInfo & operator[](size_t pos) const
Definition FunctionTypes.h:321
openvdb::v13_0::ax::codegen::ArgInfoVector::empty
auto empty() const
Definition FunctionTypes.h:310
openvdb::v13_0::ax::codegen::ArgInfoVector::pop_back
auto pop_back()
Definition FunctionTypes.h:307
openvdb::v13_0::ax::codegen::ArgInfoVector::front
auto & front() const
Definition FunctionTypes.h:304
openvdb::v13_0::ax::codegen::ArgInfoVector::emplace_back
void emplace_back(Args &&...args)
Definition FunctionTypes.h:315
openvdb::v13_0::ax::codegen::ArgInfoVector::rbegin
auto rbegin()
Definition FunctionTypes.h:299
openvdb::v13_0::ax::codegen::ArgInfoVector::ArgInfoVector
ArgInfoVector(ArgInfoVector &&)=default
openvdb::v13_0::ax::codegen::ArgInfoVector::back
auto & back() const
Definition FunctionTypes.h:306
openvdb::v13_0::ax::codegen::ArgInfoVector::operator=
ArgInfoVector & operator=(ArgInfoVector &&)=default
openvdb::v13_0::ax::codegen::ArgInfoVector::rbegin
auto rbegin() const
Definition FunctionTypes.h:301
openvdb::v13_0::ax::codegen::ArgInfoVector::begin
auto begin() const
Definition FunctionTypes.h:297
openvdb::v13_0::ax::codegen::ArgInfoVector::begin
auto begin()
Definition FunctionTypes.h:295
openvdb::v13_0::ax::codegen::ArgInfoVector::end
auto end() const
Definition FunctionTypes.h:298
openvdb::v13_0::ax::codegen::ArgInfoVector::ArgInfoVector
ArgInfoVector(const std::initializer_list< ArgInfo > &info)
Definition FunctionTypes.h:285
openvdb::v13_0::ax::codegen::ArgInfoVector::operator==
bool operator==(const ArgInfoVector &other) const
Definition FunctionTypes.h:292
openvdb::v13_0::ax::codegen::ArgType
Object to array conversion methods to allow functions to return vector types. These containers provid...
Definition FunctionTypes.h:117
openvdb::v13_0::ax::codegen::ArgType::Type
T Type
Definition FunctionTypes.h:118
openvdb::v13_0::ax::codegen::ArgType< double, 2 >::SIZE
static const size_t SIZE
Definition FunctionTypes.h:119
openvdb::v13_0::ax::codegen::ArgType< double, 2 >::mmArgs
ArrayType mmArgs
Definition FunctionTypes.h:121
openvdb::v13_0::ax::codegen::ArgType::ArrayType
Type[SIZE] ArrayType
Definition FunctionTypes.h:120
openvdb::v13_0::ax::codegen::ArgumentIterator< SignatureT, 0 >::IsNativeSignature
static const bool IsNativeSignature
Definition FunctionTypes.h:215
openvdb::v13_0::ax::codegen::ArgumentIterator< SignatureT, 0 >::apply
static void apply(const OpT &, const bool)
Definition FunctionTypes.h:217
openvdb::v13_0::ax::codegen::ArgumentIterator
Templated argument iterator which implements various small functions per argument type,...
Definition FunctionTypes.h:189
openvdb::v13_0::ax::codegen::ArgumentIterator::IsNativeSignature
static const bool IsNativeSignature
Whether this signature contains types that are representable in AX's Value type.
Definition FunctionTypes.h:195
openvdb::v13_0::ax::codegen::ArgumentIterator::apply
static void apply(const OpT &op, const bool forwards)
Definition FunctionTypes.h:200
openvdb::v13_0::ax::codegen::ArgumentIterator::ArgT
typename FunctionTraits< SignatureT >::template Arg< I-1 > ArgT
Definition FunctionTypes.h:190
openvdb::v13_0::ax::codegen::ArgumentIterator::ArgumentValueType
typename ArgT::Type ArgumentValueType
Definition FunctionTypes.h:191
openvdb::v13_0::ax::codegen::Arguments
Arbitrary, potentially "non-native" arguments. This wrapper struct can be used when generating functi...
Definition FunctionTypes.h:382
openvdb::v13_0::ax::codegen::Arguments::GetArgInfo
const ArgInfo & GetArgInfo(size_t pos) const
Definition FunctionTypes.h:427
openvdb::v13_0::ax::codegen::Arguments::AsNativeValue
Value AsNativeValue(const size_t i) const
Definition FunctionTypes.h:410
openvdb::v13_0::ax::codegen::Arguments::AsLLVMValues
const llvm::ArrayRef< llvm::Value * > AsLLVMValues() const
Definition FunctionTypes.h:426
openvdb::v13_0::ax::codegen::Arguments::size
size_t size() const
Definition FunctionTypes.h:400
openvdb::v13_0::ax::codegen::Arguments::AddArg
void AddArg(const Value &val)
Definition FunctionTypes.h:448
openvdb::v13_0::ax::codegen::Arguments::AsNativeValues
NativeArguments AsNativeValues() const
Definition FunctionTypes.h:416
openvdb::v13_0::ax::codegen::Arguments::Arguments
Arguments(const Arguments &)=default
openvdb::v13_0::ax::codegen::Arguments::Arguments
Arguments(Arguments &&)=default
openvdb::v13_0::ax::codegen::Arguments::operator=
Arguments & operator=(const Arguments &)=default
openvdb::v13_0::ax::codegen::Arguments::Arguments
Arguments(const NativeArguments &args)
Definition FunctionTypes.h:387
openvdb::v13_0::ax::codegen::Arguments::AddArg
void AddArg(llvm::Value *val, const ArgInfo &type)
Definition FunctionTypes.h:436
openvdb::v13_0::ax::codegen::Arguments::operator=
Arguments & operator=(Arguments &&)=default
openvdb::v13_0::ax::codegen::Arguments::AreNativeValues
bool AreNativeValues() const
Definition FunctionTypes.h:402
openvdb::v13_0::ax::codegen::Arguments::PrependArg
void PrependArg(const Value &val)
Definition FunctionTypes.h:454
openvdb::v13_0::ax::codegen::Arguments::operator[]
llvm::Value * operator[](size_t pos) const
Definition FunctionTypes.h:430
openvdb::v13_0::ax::codegen::Arguments::Arguments
Arguments()=default
openvdb::v13_0::ax::codegen::Arguments::GetArgInfo
const ArgInfoVector & GetArgInfo() const
Definition FunctionTypes.h:428
openvdb::v13_0::ax::codegen::CFunctionBase::hasConstantFold
bool hasConstantFold() const
Definition FunctionTypes.h:1081
openvdb::v13_0::ax::codegen::CFunctionBase::setConstantFold
void setConstantFold(bool on)
Definition FunctionTypes.h:1080
openvdb::v13_0::ax::codegen::CFunctionBase::fold
virtual llvm::Value * fold(const std::vector< llvm::Value * > &, llvm::LLVMContext &) const
Definition FunctionTypes.h:1085
openvdb::v13_0::ax::codegen::CFunctionBase::address
virtual uint64_t address() const =0
Returns the global address of this function.
openvdb::v13_0::ax::codegen::CFunctionBase::CFunctionBase
CFunctionBase(const size_t size, const std::string &symbol)
Definition FunctionTypes.h:1101
openvdb::v13_0::ax::codegen::CFunctionBase::~CFunctionBase
~CFunctionBase() override=default
openvdb::v13_0::ax::codegen::CFunctionBase::Ptr
std::shared_ptr< CFunctionBase > Ptr
Definition FunctionTypes.h:1072
openvdb::v13_0::ax::codegen::CFunction
Represents a concrete C function binding.
Definition FunctionTypes.h:1117
openvdb::v13_0::ax::codegen::CFunction::Ptr
std::shared_ptr< CFunctionT > Ptr
Definition FunctionTypes.h:1119
openvdb::v13_0::ax::codegen::CFunction::call
Value call(const Arguments &args, llvm::IRBuilder<> &B) const override
Definition FunctionTypes.h:1155
openvdb::v13_0::ax::codegen::CFunction::address
uint64_t address() const override final
Returns the global address of this function.
Definition FunctionTypes.h:1141
openvdb::v13_0::ax::codegen::CFunction::Traits
FunctionTraits< SignatureT > Traits
Definition FunctionTypes.h:1120
openvdb::v13_0::ax::codegen::CFunction::call
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B, const bool cast) const override
Definition FunctionTypes.h:1188
openvdb::v13_0::ax::codegen::CFunction::types
llvm::Type * types(std::vector< llvm::Type * > &types, llvm::LLVMContext &C) const override
Definition FunctionTypes.h:1179
openvdb::v13_0::ax::codegen::CFunction::types
ArgInfo types(ArgInfoVector &types, llvm::LLVMContext &C) const override
Populate a vector of ArgInfos which describe this function signature. This method is used by Function...
Definition FunctionTypes.h:1136
openvdb::v13_0::ax::codegen::CFunction::~CFunction
~CFunction() override=default
openvdb::v13_0::ax::codegen::CFunction::call
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B) const override
Definition FunctionTypes.h:1147
openvdb::v13_0::ax::codegen::CFunction::fold
llvm::Constant * fold(const std::vector< llvm::Value * > &args, llvm::LLVMContext &C) const override final
Definition FunctionTypes.h:1163
openvdb::v13_0::ax::codegen::CFunction::CFunction
CFunction(const std::string &symbol, SignatureT *function)
Definition FunctionTypes.h:1130
openvdb::v13_0::ax::codegen::CFunction::CFunctionT
CFunction< SignatureT > CFunctionT
Definition FunctionTypes.h:1118
openvdb::v13_0::ax::codegen::CFunctionSRet
Represents a concrete C function binding with the first argument as its return type.
Definition FunctionTypes.h:1362
openvdb::v13_0::ax::codegen::CFunctionSRet::CFunctionSRet
CFunctionSRet(const std::string &symbol, const SignatureT function)
Definition FunctionTypes.h:1364
openvdb::v13_0::ax::codegen::CFunctionSRet::BaseT
SRetFunction< SignatureT, CFunction< SignatureT > > BaseT
Definition FunctionTypes.h:1363
openvdb::v13_0::ax::codegen::CFunctionSRet::~CFunctionSRet
~CFunctionSRet() override=default
openvdb::v13_0::ax::codegen::ConstantFolder::fold
static llvm::Constant * fold(const llvm::ArrayRef< llvm::Constant * > &args, const SignatureT &function, llvm::LLVMContext &C, Tys &&... ts)
Definition ConstantFolding.h:56
openvdb::v13_0::ax::codegen::CountNPtrs
Definition Types.h:50
openvdb::v13_0::ax::codegen::CountNPtrs::value
static constexpr uint8_t value
Definition Types.h:50
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings
Definition FunctionTypes.h:1522
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mNames
std::unique_ptr< SmallArgumentVector< const char * > > mNames
Definition FunctionTypes.h:1537
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mReadOnly
bool mReadOnly
Definition FunctionTypes.h:1541
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::Ptr
std::shared_ptr< Settings > Ptr
Definition FunctionTypes.h:1523
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mDeps
SmallArgumentVector< const char * > mDeps
Definition FunctionTypes.h:1538
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::isDefault
bool isDefault() const
Definition FunctionTypes.h:1525
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mType
Function::Type mType
Definition FunctionTypes.h:1542
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mEmbedIR
bool mEmbedIR
Definition FunctionTypes.h:1540
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mFnAttrs
SmallArgumentVector< llvm::Attribute::AttrKind > mFnAttrs
Definition FunctionTypes.h:1543
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mParamAttrs
std::map< size_t, SmallArgumentVector< llvm::Attribute::AttrKind > > mParamAttrs
Definition FunctionTypes.h:1545
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mConstantFold
bool mConstantFold
Definition FunctionTypes.h:1539
openvdb::v13_0::ax::codegen::FunctionBuilder::Settings::mRetAttrs
SmallArgumentVector< llvm::Attribute::AttrKind > mRetAttrs
Definition FunctionTypes.h:1544
openvdb::v13_0::ax::codegen::FunctionBuilder
The FunctionBuilder class provides a builder pattern framework to allow easy and valid construction o...
Definition FunctionTypes.h:1516
openvdb::v13_0::ax::codegen::FunctionBuilder::get
FunctionGroup::UniquePtr get() const
Definition FunctionTypes.h:1748
openvdb::v13_0::ax::codegen::FunctionBuilder::addFunctionAttribute
FunctionBuilder & addFunctionAttribute(const llvm::Attribute::AttrKind attr)
Definition FunctionTypes.h:1674
openvdb::v13_0::ax::codegen::FunctionBuilder::addSignature
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorCb &cb, const Signature *ptr, const char *symbol=nullptr)
Definition FunctionTypes.h:1581
openvdb::v13_0::ax::codegen::FunctionBuilder::addSignature
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorCb &cb, const char *symbol=nullptr)
Definition FunctionTypes.h:1567
openvdb::v13_0::ax::codegen::FunctionBuilder::addParameterAttribute
FunctionBuilder & addParameterAttribute(const size_t idx, const llvm::Attribute::AttrKind attr)
Parameter and Function Attributes. When designing a C binding, llvm will be unable to assign paramete...
Definition FunctionTypes.h:1660
openvdb::v13_0::ax::codegen::FunctionBuilder::setPreferredImpl
FunctionBuilder & setPreferredImpl(DeclPreferrence pref)
Definition FunctionTypes.h:1742
openvdb::v13_0::ax::codegen::FunctionBuilder::addSignature
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorArgumentsCb &cb, const Signature *ptr, const char *symbol=nullptr)
Definition FunctionTypes.h:1630
openvdb::v13_0::ax::codegen::FunctionBuilder::DeclPreferrence
DeclPreferrence
Definition FunctionTypes.h:1517
openvdb::v13_0::ax::codegen::FunctionBuilder::IR
@ IR
Definition FunctionTypes.h:1518
openvdb::v13_0::ax::codegen::FunctionBuilder::C
@ C
Definition FunctionTypes.h:1518
openvdb::v13_0::ax::codegen::FunctionBuilder::Any
@ Any
Definition FunctionTypes.h:1518
openvdb::v13_0::ax::codegen::FunctionBuilder::addDependency
FunctionBuilder & addDependency(const char *name)
Definition FunctionTypes.h:1637
openvdb::v13_0::ax::codegen::FunctionBuilder::setConstantFold
FunctionBuilder & setConstantFold(bool on)
Definition FunctionTypes.h:1643
openvdb::v13_0::ax::codegen::FunctionBuilder::addSignature
FunctionBuilder & addSignature(const Signature *ptr, const char *symbol=nullptr)
Definition FunctionTypes.h:1555
openvdb::v13_0::ax::codegen::FunctionBuilder::addSignature
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorNativeCb &cb, const Signature *ptr, const char *symbol=nullptr)
Definition FunctionTypes.h:1605
openvdb::v13_0::ax::codegen::FunctionBuilder::FunctionBuilder
FunctionBuilder(const char *name)
Definition FunctionTypes.h:1548
openvdb::v13_0::ax::codegen::FunctionBuilder::addReturnAttribute
FunctionBuilder & addReturnAttribute(const llvm::Attribute::AttrKind attr)
Definition FunctionTypes.h:1667
openvdb::v13_0::ax::codegen::FunctionBuilder::setArgumentNames
FunctionBuilder & setArgumentNames(const std::vector< const char * > &names)
Definition FunctionTypes.h:1644
openvdb::v13_0::ax::codegen::FunctionBuilder::addSignature
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorNativeCb &cb, const char *symbol=nullptr)
Definition FunctionTypes.h:1591
openvdb::v13_0::ax::codegen::FunctionBuilder::setReadOnly
FunctionBuilder & setReadOnly(const bool on)
Mark functions currently sharing settings with as "readonly". This enables the strictest possible mem...
Definition FunctionTypes.h:1688
openvdb::v13_0::ax::codegen::FunctionBuilder::setExternalKernel
FunctionBuilder & setExternalKernel()
Mark this function as an external kernel entry point. Should only be used by the ComputeGenerators....
Definition FunctionTypes.h:1730
openvdb::v13_0::ax::codegen::FunctionBuilder::setDocumentation
FunctionBuilder & setDocumentation(const char *doc)
Definition FunctionTypes.h:1736
openvdb::v13_0::ax::codegen::FunctionBuilder::setBuiltin
FunctionBuilder & setBuiltin()
Mark functions currently sharing settings as builtin AX methods. At compile time, this causes the IR ...
Definition FunctionTypes.h:1717
openvdb::v13_0::ax::codegen::FunctionBuilder::addSignature
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorArgumentsCb &cb, const char *symbol=nullptr)
Definition FunctionTypes.h:1616
openvdb::v13_0::ax::codegen::FunctionBuilder::setEmbedIR
FunctionBuilder & setEmbedIR(bool on)
Definition FunctionTypes.h:1642
openvdb::v13_0::ax::codegen::FunctionGroup::HasUniqueTypeSignatures
bool HasUniqueTypeSignatures(llvm::LLVMContext &C) const
Verify the function signatures in this group.
openvdb::v13_0::ax::codegen::FunctionGroup::execute
Value execute(const NativeArguments &args, llvm::IRBuilder<> &B) const
Given a set of NativeArguments, find the best possible function signature, generate and execute the f...
openvdb::v13_0::ax::codegen::FunctionGroup::FunctionList
std::vector< Function::Ptr > FunctionList
Definition FunctionTypes.h:1399
openvdb::v13_0::ax::codegen::FunctionGroup::execute
Value execute(const Arguments &args, llvm::IRBuilder<> &B) const
Given a set of Arguments, find an EXPLICIT signature match, generate and execute the function body....
openvdb::v13_0::ax::codegen::FunctionGroup::match
std::pair< const Function *, Function::SignatureMatch > match(const ArgInfoVector &args, llvm::LLVMContext &C) const
Given a vector of llvm types, automatically returns the best possible function declaration from the s...
openvdb::v13_0::ax::codegen::FunctionGroup::Ptr
std::shared_ptr< FunctionGroup > Ptr
Definition FunctionTypes.h:1397
openvdb::v13_0::ax::codegen::FunctionGroup::UniquePtr
std::unique_ptr< FunctionGroup > UniquePtr
Definition FunctionTypes.h:1398
openvdb::v13_0::ax::codegen::FunctionGroup::name
const char * name() const
Definition FunctionTypes.h:1459
openvdb::v13_0::ax::codegen::FunctionGroup::doc
const char * doc() const
Definition FunctionTypes.h:1460
openvdb::v13_0::ax::codegen::FunctionGroup::list
const FunctionList & list() const
Accessor to the underlying function signature list.
Definition FunctionTypes.h:1458
openvdb::v13_0::ax::codegen::FunctionGroup::~FunctionGroup
~FunctionGroup()=default
openvdb::v13_0::ax::codegen::FunctionGroup::FunctionGroup
FunctionGroup(const char *name, const char *doc, const FunctionList &list)
Definition FunctionTypes.h:1401
openvdb::v13_0::ax::codegen::Function
The base/abstract representation of an AX function. Derived classes must implement the Function::type...
Definition FunctionTypes.h:603
openvdb::v13_0::ax::codegen::Function::match
virtual SignatureMatch match(const ArgInfoVector &inputs, llvm::LLVMContext &C) const
The base implementation for determining how a vector of llvm arguments translates to this functions s...
openvdb::v13_0::ax::codegen::Function::call
Value call(const NativeArguments &args, llvm::IRBuilder<> &B) const
Definition FunctionTypes.h:716
openvdb::v13_0::ax::codegen::Function::argName
const char * argName(const size_t idx) const
Returns the descriptive name of the given argument index.
Definition FunctionTypes.h:773
openvdb::v13_0::ax::codegen::Function::print
virtual void print(llvm::LLVMContext &C, std::ostream &os, const char *name=nullptr, const bool axTypes=true) const
Print this function's signature to the provided ostream.
openvdb::v13_0::ax::codegen::Function::setDependencies
void setDependencies(std::vector< const char * > deps)
Definition FunctionTypes.h:819
openvdb::v13_0::ax::codegen::Function::size
size_t size() const
The number of arguments that this function has.
Definition FunctionTypes.h:762
openvdb::v13_0::ax::codegen::Function::create
virtual llvm::Function * create(llvm::LLVMContext &C, llvm::Module *M=nullptr) const
Converts and creates this AX function into a llvm Function.
openvdb::v13_0::ax::codegen::Function::setParamAttributes
void setParamAttributes(const size_t i, const std::vector< llvm::Attribute::AttrKind > &in)
Definition FunctionTypes.h:837
openvdb::v13_0::ax::codegen::Function::cast
static void cast(std::vector< llvm::Value * > &args, const std::vector< llvm::Type * > &types, llvm::IRBuilder<> &B)
Cast the provided arguments to the given type as supported by implicit casting of function types....
openvdb::v13_0::ax::codegen::Function::call
virtual llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B) const
openvdb::v13_0::ax::codegen::Function::Function
Function(const size_t size, const std::string &symbol)
Definition FunctionTypes.h:606
openvdb::v13_0::ax::codegen::Function::setRetAttributes
void setRetAttributes(const std::vector< llvm::Attribute::AttrKind > &in)
Definition FunctionTypes.h:831
openvdb::v13_0::ax::codegen::Function::dependencies
const SmallArgumentVector< const char * > & dependencies() const
Definition FunctionTypes.h:794
openvdb::v13_0::ax::codegen::Function::create
llvm::Function * create(llvm::Module &M) const
Convenience method which always uses the provided module to find the function or insert it if necessa...
Definition FunctionTypes.h:667
openvdb::v13_0::ax::codegen::Function::setFnAttributes
void setFnAttributes(const std::vector< llvm::Attribute::AttrKind > &in)
Definition FunctionTypes.h:825
openvdb::v13_0::ax::codegen::Function::Ptr
std::shared_ptr< Function > Ptr
Definition FunctionTypes.h:604
openvdb::v13_0::ax::codegen::Function::call
virtual llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B, const bool cast) const
Uses the IRBuilder to create a call to this function with the given arguments, creating the function ...
openvdb::v13_0::ax::codegen::Function::hasParamAttribute
bool hasParamAttribute(const size_t i, const llvm::Attribute::AttrKind &kind) const
Deprecated builder methods, no longer public.
Definition FunctionTypes.h:802
openvdb::v13_0::ax::codegen::Function::symbol
const char * symbol() const
The function symbol name.
Definition FunctionTypes.h:766
openvdb::v13_0::ax::codegen::Function::types
virtual ArgInfo types(ArgInfoVector &, llvm::LLVMContext &) const
Populate a vector of ArgInfos which describe this function signature. This method is used by Function...
Definition FunctionTypes.h:625
openvdb::v13_0::ax::codegen::Function::~Function
virtual ~Function()=default
openvdb::v13_0::ax::codegen::Function::get
llvm::Function * get(const llvm::Module &M) const
Convenience method for calling M.getFunction(symbol). Returns a nullptr if the function has not yet b...
openvdb::v13_0::ax::codegen::Function::SignatureMatch
SignatureMatch
The result type from calls to Function::match.
Definition FunctionTypes.h:725
openvdb::v13_0::ax::codegen::Function::Implicit
@ Implicit
Definition FunctionTypes.h:728
openvdb::v13_0::ax::codegen::Function::Ambiguous
@ Ambiguous
Definition FunctionTypes.h:729
openvdb::v13_0::ax::codegen::Function::None
@ None
Definition FunctionTypes.h:726
openvdb::v13_0::ax::codegen::Function::Explicit
@ Explicit
Definition FunctionTypes.h:730
openvdb::v13_0::ax::codegen::Function::Size
@ Size
Definition FunctionTypes.h:727
openvdb::v13_0::ax::codegen::Function::setArgumentNames
void setArgumentNames(std::vector< const char * > names)
Definition FunctionTypes.h:813
openvdb::v13_0::ax::codegen::Function::call
virtual Value call(const Arguments &args, llvm::IRBuilder<> &B) const
openvdb::v13_0::ax::codegen::FunctionTraits
Templated function traits which provides compile-time index access to the types of the function signa...
Definition Types.h:311
openvdb::v13_0::ax::codegen::IRFunctionBase::IRFunctionBase
IRFunctionBase(const std::string &symbol, const GeneratorNativeCb &gen, const size_t size)
Definition FunctionTypes.h:1309
openvdb::v13_0::ax::codegen::IRFunctionBase::hasEmbedIR
bool hasEmbedIR() const
Definition FunctionTypes.h:1232
openvdb::v13_0::ax::codegen::IRFunctionBase::setEmbedIR
void setEmbedIR(bool on)
Enable or disable the embedding of IR. Embedded IR is currently required for function which use paren...
Definition FunctionTypes.h:1231
openvdb::v13_0::ax::codegen::IRFunctionBase::call
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B, const bool cast) const override
Uses the IRBuilder to create a call to this function with the given arguments, creating the function ...
openvdb::v13_0::ax::codegen::IRFunctionBase::Ptr
std::shared_ptr< IRFunctionBase > Ptr
Definition FunctionTypes.h:1205
openvdb::v13_0::ax::codegen::IRFunctionBase::mGen
const GeneratorArgumentsCb mGen
Definition FunctionTypes.h:1326
openvdb::v13_0::ax::codegen::IRFunctionBase::create
llvm::Function * create(llvm::LLVMContext &C, llvm::Module *M) const override
Override for the creation of an IR function. This ensures that the body and prototype of the function...
openvdb::v13_0::ax::codegen::IRFunctionBase::GeneratorCb
std::function< llvm::Value *(const std::vector< llvm::Value * > &, llvm::IRBuilder<> &)> GeneratorCb
Legacy callback, will eventually be deprecated in favour of using the GeneratorArgumentsCb.
Definition FunctionTypes.h:1225
openvdb::v13_0::ax::codegen::IRFunctionBase::call
Value call(const Arguments &args, llvm::IRBuilder<> &) const override
openvdb::v13_0::ax::codegen::IRFunctionBase::mEmbedIR
bool mEmbedIR
Definition FunctionTypes.h:1327
openvdb::v13_0::ax::codegen::IRFunctionBase::call
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B) const override
Override for call, which is only necessary if mEmbedIR is true, as the IR generation for embedded fun...
openvdb::v13_0::ax::codegen::IRFunctionBase::IRFunctionBase
IRFunctionBase(const std::string &symbol, const GeneratorCb &gen, const size_t size)
Definition FunctionTypes.h:1283
openvdb::v13_0::ax::codegen::IRFunctionBase::verifyResultType
void verifyResultType(const llvm::Type *result, const llvm::Type *expected) const
Definition FunctionTypes.h:1273
openvdb::v13_0::ax::codegen::IRFunctionBase::GeneratorNativeCb
std::function< Value(const NativeArguments &, llvm::IRBuilder<> &)> GeneratorNativeCb
The IR callback function which will write the LLVM IR for this function's body.
Definition FunctionTypes.h:1217
openvdb::v13_0::ax::codegen::IRFunctionBase::GeneratorArgumentsCb
std::function< Value(const Arguments &, llvm::IRBuilder<> &)> GeneratorArgumentsCb
Definition FunctionTypes.h:1220
openvdb::v13_0::ax::codegen::IRFunctionBase::IRFunctionBase
IRFunctionBase(const std::string &symbol, const GeneratorArgumentsCb &gen, const size_t size)
Definition FunctionTypes.h:1318
openvdb::v13_0::ax::codegen::IRFunctionBase::~IRFunctionBase
~IRFunctionBase() override=default
openvdb::v13_0::ax::codegen::IRFunction
Represents a concrete IR function.
Definition FunctionTypes.h:1333
openvdb::v13_0::ax::codegen::IRFunction::IRFunction
IRFunction(const std::string &symbol, const GeneratorArgumentsCb &gen)
Definition FunctionTypes.h:1341
openvdb::v13_0::ax::codegen::IRFunction::Traits
FunctionTraits< SignatureT > Traits
Definition FunctionTypes.h:1334
openvdb::v13_0::ax::codegen::IRFunction::types
llvm::Type * types(std::vector< llvm::Type * > &types, llvm::LLVMContext &C) const override
Definition FunctionTypes.h:1351
openvdb::v13_0::ax::codegen::IRFunction::types
ArgInfo types(ArgInfoVector &types, llvm::LLVMContext &C) const override
Populate a vector of ArgInfos which describe this function signature. This method is used by Function...
Definition FunctionTypes.h:1344
openvdb::v13_0::ax::codegen::IRFunction::IRFunction
IRFunction(const std::string &symbol, const GeneratorCb &gen)
Definition FunctionTypes.h:1337
openvdb::v13_0::ax::codegen::IRFunction::IRFunction
IRFunction(const std::string &symbol, const GeneratorNativeCb &gen)
Definition FunctionTypes.h:1339
openvdb::v13_0::ax::codegen::IRFunction::Ptr
std::shared_ptr< IRFunction > Ptr
Definition FunctionTypes.h:1335
openvdb::v13_0::ax::codegen::IRFunctionSRet
Represents a concrete IR function with the first argument as its return type.
Definition FunctionTypes.h:1373
openvdb::v13_0::ax::codegen::IRFunctionSRet::IRFunctionSRet
IRFunctionSRet(const std::string &symbol, const IRFunctionBase::GeneratorCb &gen)
Definition FunctionTypes.h:1375
openvdb::v13_0::ax::codegen::IRFunctionSRet::IRFunctionSRet
IRFunctionSRet(const std::string &symbol, const IRFunctionBase::GeneratorArgumentsCb &gen)
Definition FunctionTypes.h:1381
openvdb::v13_0::ax::codegen::IRFunctionSRet::IRFunctionSRet
IRFunctionSRet(const std::string &symbol, const IRFunctionBase::GeneratorNativeCb &gen)
Definition FunctionTypes.h:1378
openvdb::v13_0::ax::codegen::IRFunctionSRet::BaseT
SRetFunction< SignatureT, IRFunction< SignatureT > > BaseT
Definition FunctionTypes.h:1374
openvdb::v13_0::ax::codegen::IRFunctionSRet::~IRFunctionSRet
~IRFunctionSRet() override=default
openvdb::v13_0::ax::codegen::LLVMType
LLVM type mapping from pod types.
Definition Types.h:68
openvdb::v13_0::ax::codegen::LLVMType::CXXUTypeIsNativeType
static const bool CXXUTypeIsNativeType
Definition Types.h:76
openvdb::v13_0::ax::codegen::LLVMType::get
static llvm::Type * get(llvm::LLVMContext &C)
Return an LLVM type which represents T.
Definition Types.h:81
openvdb::v13_0::ax::codegen::NativeArguments
Wrapper struct to represent "native" function arguments; that is, the set of Value type that the AX g...
Definition FunctionTypes.h:349
openvdb::v13_0::ax::codegen::NativeArguments::size
size_t size() const
Definition FunctionTypes.h:359
openvdb::v13_0::ax::codegen::NativeArguments::operator=
NativeArguments & operator=(const NativeArguments &)=default
openvdb::v13_0::ax::codegen::NativeArguments::AddArg
void AddArg(const Value &val)
Definition FunctionTypes.h:370
openvdb::v13_0::ax::codegen::NativeArguments::NativeArguments
NativeArguments()=default
openvdb::v13_0::ax::codegen::NativeArguments::NativeArguments
NativeArguments(const std::initializer_list< Value > &args)
Definition FunctionTypes.h:351
openvdb::v13_0::ax::codegen::NativeArguments::Cast
OPENVDB_AX_API NativeArguments Cast(const Function &F, llvm::IRBuilder<> &B) const
Cast these arguments to match the given function's signature.
openvdb::v13_0::ax::codegen::NativeArguments::NativeArguments
NativeArguments(const std::vector< Value > &args)
Definition FunctionTypes.h:353
openvdb::v13_0::ax::codegen::NativeArguments::operator[]
Value & operator[](size_t pos)
Definition FunctionTypes.h:360
openvdb::v13_0::ax::codegen::NativeArguments::operator=
NativeArguments & operator=(NativeArguments &&)=default
openvdb::v13_0::ax::codegen::NativeArguments::operator[]
const Value & operator[](size_t pos) const
Definition FunctionTypes.h:365
openvdb::v13_0::ax::codegen::NativeArguments::NativeArguments
NativeArguments(NativeArguments &&)=default
openvdb::v13_0::ax::codegen::NativeArguments::NativeArguments
NativeArguments(const NativeArguments &)=default
openvdb::v13_0::ax::codegen::RemoveAllPtrTypes
Definition Types.h:44
openvdb::v13_0::ax::codegen::SRetFunction::print
void print(llvm::LLVMContext &C, std::ostream &os, const char *name=nullptr, const bool axTypes=true) const override
Override of print to avoid printing out the SRET type.
Definition FunctionTypes.h:1008
openvdb::v13_0::ax::codegen::SRetFunction::call
Value call(const Arguments &args, llvm::IRBuilder<> &B) const override
Definition FunctionTypes.h:997
openvdb::v13_0::ax::codegen::SRetFunction::Ptr
std::shared_ptr< SRetFunction< SignatureT, DerivedFunction > > Ptr
Definition FunctionTypes.h:921
openvdb::v13_0::ax::codegen::SRetFunction::Traits
FunctionTraits< SignatureT > Traits
Definition FunctionTypes.h:922
openvdb::v13_0::ax::codegen::SRetFunction::call
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B, const bool cast) const override
Definition FunctionTypes.h:1049
openvdb::v13_0::ax::codegen::SRetFunction::match
Function::SignatureMatch match(const ArgInfoVector &args, llvm::LLVMContext &C) const override
Override of match which inserts the SRET type such that the base class methods ignore it.
Definition FunctionTypes.h:963
openvdb::v13_0::ax::codegen::SRetFunction::SRetFunction
SRetFunction(Args &&... ts)
Forward all arguments to the derived class.
Definition FunctionTypes.h:1066
openvdb::v13_0::ax::codegen::SRetFunction::match
Function::SignatureMatch match(const std::vector< llvm::Type * > &args, llvm::LLVMContext &C) const override
Definition FunctionTypes.h:1035
openvdb::v13_0::ax::codegen::SRetFunction::call
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B) const override
Override of call which allocates the required SRET llvm::Value for this function.
Definition FunctionTypes.h:985
openvdb::v13_0::ax::codegen::SRetFunction::types
ArgInfo types(ArgInfoVector &args, llvm::LLVMContext &C) const override
Overide the ArgInfo type method. This does NOT change the arg order, it simply marks the first argume...
Definition FunctionTypes.h:950
openvdb::v13_0::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::v13_0::ax::codegen::TypeToSymbol< T * >::s
static std::string s()
Definition FunctionTypes.h:164
openvdb::v13_0::ax::codegen::TypeToSymbol< T[S]>::s
static std::string s()
Definition FunctionTypes.h:169
openvdb::v13_0::ax::codegen::TypeToSymbol< char >::s
static std::string s()
Definition FunctionTypes.h:149
openvdb::v13_0::ax::codegen::TypeToSymbol< codegen::String >::s
static std::string s()
Definition FunctionTypes.h:160
openvdb::v13_0::ax::codegen::TypeToSymbol< double >::s
static std::string s()
Definition FunctionTypes.h:159
openvdb::v13_0::ax::codegen::TypeToSymbol< float >::s
static std::string s()
Definition FunctionTypes.h:158
openvdb::v13_0::ax::codegen::TypeToSymbol< int16_t >::s
static std::string s()
Definition FunctionTypes.h:155
openvdb::v13_0::ax::codegen::TypeToSymbol< int32_t >::s
static std::string s()
Definition FunctionTypes.h:156
openvdb::v13_0::ax::codegen::TypeToSymbol< int64_t >::s
static std::string s()
Definition FunctionTypes.h:157
openvdb::v13_0::ax::codegen::TypeToSymbol< int8_t >::s
static std::string s()
Definition FunctionTypes.h:154
openvdb::v13_0::ax::codegen::TypeToSymbol< uint16_t >::s
static std::string s()
Definition FunctionTypes.h:151
openvdb::v13_0::ax::codegen::TypeToSymbol< uint32_t >::s
static std::string s()
Definition FunctionTypes.h:152
openvdb::v13_0::ax::codegen::TypeToSymbol< uint64_t >::s
static std::string s()
Definition FunctionTypes.h:153
openvdb::v13_0::ax::codegen::TypeToSymbol< uint8_t >::s
static std::string s()
Definition FunctionTypes.h:150
openvdb::v13_0::ax::codegen::TypeToSymbol< void >::s
static std::string s()
Definition FunctionTypes.h:148
openvdb::v13_0::ax::codegen::TypeToSymbol
Type to symbol conversions - these characters are used to build each functions unique signature....
Definition FunctionTypes.h:147
openvdb::v13_0::ax::codegen::TypeToSymbol::s
static std::string s()
Definition FunctionTypes.h:147
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218