66 #ifndef OPENVDB_AX_CODEGEN_FUNCTION_TYPES_HAS_BEEN_INCLUDED 67 #define OPENVDB_AX_CODEGEN_FUNCTION_TYPES_HAS_BEEN_INCLUDED 74 #include <openvdb/version.h> 77 #include <llvm/ADT/SmallVector.h> 78 #include <llvm/IR/Constants.h> 79 #include <llvm/IR/IRBuilder.h> 80 #include <llvm/IR/Module.h> 86 #include <type_traits> 109 template <
typename T>
116 template <
typename T,
size_t _SIZE = 1>
119 static const size_t SIZE = _SIZE;
124 template <
typename T,
size_t S>
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"; } };
162 template <
typename T>
167 template <
typename T,
size_t S>
187 template <typename SignatureT, size_t I = FunctionTraits<SignatureT>::N_ARGS>
195 static const bool IsNativeSignature =
199 template <
typename OpT>
200 static void apply(
const OpT&
op,
const bool forwards) {
212 template <
typename SignatureT>
215 static const bool IsNativeSignature =
true;
216 template <
typename OpT>
217 static void apply(
const OpT&,
const bool) {}
227 :
ArgInfo(val.GetUnderlyingType(), val.IsPtr() ? 1 : 0) {}
229 ArgInfo(llvm::Type* utype, uint8_t ptrs,
bool ret =
false)
230 : mUType(utype), mPtrs(ptrs), mReturn(ret) {
243 mUType == other.mUType &&
244 mPtrs == other.mPtrs &&
245 mReturn == other.mReturn;
251 mUType == other.mUType &&
252 mPtrs == other.mPtrs;
254 bool IsPtr()
const {
return mPtrs > 0; }
256 bool IsNative()
const {
return Value::Supports(mUType) && mPtrs <= 1; }
257 bool IsVoid()
const {
return mUType->isVoidTy(); }
262 llvm::Type* type = mUType;
263 for (uint8_t i = 0; i < mPtrs; ++i) {
264 type = llvm::PointerType::get(type, 0);
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(); }
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); }
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)...); }
319 return mInfoVec[pos];
324 return mInfoVec[pos];
330 types.reserve(mInfoVec.size());
331 for (
auto& info : mInfoVec) {
332 types.emplace_back(info.GetType());
354 : mArgs(args.begin(), args.end()) {}
359 size_t size()
const {
return mArgs.size(); }
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]);
400 size_t size()
const {
return mArgs.size(); }
404 for (
const auto& types : mTypes) {
405 if (!types.IsNative())
return false;
413 return Value(mArgs[i], mTypes[i].GetUnderlyingType());
420 for (
size_t i = 0; i < mArgs.size(); ++i) {
421 args.
AddArg(this->AsNativeValue(i));
426 const llvm::ArrayRef<llvm::Value*>
AsLLVMValues()
const {
return mArgs; }
438 #if LLVM_VERSION_MAJOR <= 15 439 [[maybe_unused]] llvm::Type* base = val->getType();
440 while (base->isPointerTy()) base = base->getContainedType(0);
442 "Base type of val does not match stored underlying type");
444 mArgs.emplace_back(val);
445 mTypes.emplace_back(type);
451 mTypes.emplace_back(val);
457 std::rotate(mArgs.rbegin(), mArgs.rbegin() + 1, mArgs.rend());
458 std::rotate(mTypes.rbegin(), mTypes.rbegin() + 1, mTypes.rend());
477 template <
typename SignatureT>
480 std::vector<llvm::Type*>* types =
nullptr)
483 using ArgumentIteratorT =
487 types->reserve(Traits::N_ARGS);
488 auto callback = [&types, &C](
auto type) {
489 using Type = decltype(type);
492 ArgumentIteratorT::apply(callback,
true);
494 using Type =
typename Traits::ReturnType;
504 template <
typename SignatureT>
510 using ArgumentIteratorT =
515 types->reserve(Traits::N_ARGS);
516 auto callback = [&types, &C](
auto type)
518 using UnderlyingType = std::remove_cv_t<typename RemoveAllPtrTypes<decltype(type)>::Type>;
520 static constexpr
bool IsVoid = std::is_same_v<UnderlyingType, void>;
522 static_assert(!IsVoid || NPtrs > 0);
524 using Type = std::conditional_t<IsVoid, int8_t, UnderlyingType>;
527 ArgumentIteratorT::apply(callback,
true);
530 using UnderlyingType = std::remove_cv_t<typename RemoveAllPtrTypes<typename Traits::ReturnType>::Type>;
533 if constexpr (std::is_same_v<UnderlyingType, void> && NPtrs > 0)
552 template <
typename SignatureT>
553 inline llvm::FunctionType*
558 llvmArgTypesFromSignature<SignatureT>(C, &types);
559 return llvm::FunctionType::get(returnType.
GetType(),
578 const char* name =
nullptr,
579 const llvm::ArrayRef<const char*>& names = {},
580 const bool axTypes =
false);
583 #if LLVM_VERSION_MAJOR <= 15 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);
604 using Ptr = std::shared_ptr<Function>;
606 Function(
const size_t size,
const std::string& symbol)
609 , mAttributes(nullptr)
624 #if LLVM_VERSION_MAJOR <= 15 628 std::string(
"New AX API for function arguments has been called but has not " 629 "been implemented by function: ") + this->symbol());
632 virtual llvm::Type* types(std::vector<llvm::Type*>&, llvm::LLVMContext&)
const = 0;
661 virtual llvm::Function*
662 create(llvm::LLVMContext& C, llvm::Module* M =
nullptr)
const;
667 llvm::Function*
create(llvm::Module& M)
const {
668 return this->create(M.getContext(), &M);
675 llvm::Function*
get(
const llvm::Module& M)
const;
700 #if LLVM_VERSION_MAJOR <= 15 702 "supports casting is incompatible with LLVM 16+ and will be removed.")
704 call(
const std::vector<llvm::Value*>& args,
705 llvm::IRBuilder<>& B,
706 const bool cast)
const;
711 call(
const std::vector<llvm::Value*>& args,
712 llvm::IRBuilder<>& B)
const;
714 virtual Value call(
const Arguments& args, llvm::IRBuilder<>& B)
const;
756 #if LLVM_VERSION_MAJOR <= 15 762 inline size_t size()
const {
return mSize; }
766 inline const char*
symbol()
const {
return mSymbol.c_str(); }
773 inline const char*
argName(
const size_t idx)
const 775 return idx < mNames.size() ? mNames[idx] :
"";
789 virtual void print(llvm::LLVMContext& C,
791 const char* name =
nullptr,
792 const bool axTypes =
true)
const;
799 "of the function set by the FunctionBuilder, not by the codegen. To " 800 "inspect function attributes, retrieve the created function from the " 802 inline
bool hasParamAttribute(const
size_t i,
803 const
llvm::Attribute::AttrKind& kind)
const 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();
813 inline
void setArgumentNames(
std::vector<const
char*> names)
815 mNames.assign(names.begin(), names.end());
819 inline
void setDependencies(
std::vector<const
char*> deps)
821 mDeps.assign(deps.begin(), deps.end());
825 inline
void setFnAttributes(const
std::vector<
llvm::Attribute::AttrKind>& in)
827 this->attrs().mFnAttrs.assign(in.begin(), in.end());
831 inline
void setRetAttributes(const
std::vector<
llvm::Attribute::AttrKind>& in)
833 this->attrs().mRetAttrs.assign(in.begin(), in.end());
837 inline
void setParamAttributes(const
size_t i,
838 const
std::vector<
llvm::Attribute::AttrKind>& in)
840 this->attrs().mParamAttrs[i].assign(in.begin(), in.end());
845 #if LLVM_VERSION_MAJOR <= 15 853 static void cast(std::vector<llvm::Value*>& args,
854 const std::vector<llvm::Type*>& types,
855 llvm::IRBuilder<>& B);
864 std::map<size_t, SmallArgumentVector<llvm::Attribute::AttrKind>> mParamAttrs;
865 bool mReadOnly {
false};
866 bool mBuiltin {
false};
869 inline Attributes& attrs()
871 if (!mAttributes) mAttributes.reset(
new Attributes());
876 bool IsParamReadOnly(
const size_t idx)
const 878 if (!mAttributes)
return false;
879 if (mAttributes->mReadOnly)
return true;
881 const auto iter = mAttributes->mParamAttrs.find(idx);
882 if (iter == mAttributes->mParamAttrs.end())
return false;
883 const auto& vec = iter->second;
884 return std::find(vec.begin(), vec.end(),
885 llvm::Attribute::AttrKind::ReadOnly) != vec.end();
888 llvm::AttributeList flattenAttrs(llvm::Function* F)
const;
892 const std::string mSymbol;
893 std::unique_ptr<Attributes> mAttributes;
912 template <
typename SignatureT,
typename DerivedFunction>
915 using Ptr = std::shared_ptr<SRetFunction<SignatureT, DerivedFunction>>;
919 static_assert(Traits::N_ARGS > 0,
920 "SRET Function object has been setup with the first argument as the return " 921 "value, however the provided signature is empty.");
924 static_assert(std::is_same<typename Traits::ReturnType, void>::value,
925 "SRET Function object has been setup with the first argument as the return " 926 "value and a non void return type.");
930 using FirstArgument =
typename Traits::template Arg<0>::Type;
931 static_assert(std::is_pointer<FirstArgument>::value,
932 "SRET Function object has been setup with the first argument as the return " 933 "value, but this argument it is not a pointer type.");
934 static_assert(!std::is_const_v<FirstArgument>,
935 "SRET Function object has been setup with the first argument as the return " 936 "value, but this argument is const.");
937 using SRetType =
typename std::remove_pointer<FirstArgument>::type;
946 ArgInfo ret = DerivedFunction::types(args, C);
951 args[0].SetIsReturn();
959 llvm::LLVMContext& C)
const override 967 inputs.
back().SetIsReturn();
969 return DerivedFunction::match(inputs, C);
979 call(
const std::vector<llvm::Value*>& args,
980 llvm::IRBuilder<>& B)
const override 983 std::vector<llvm::Value*> inputs(args);
986 std::rotate(inputs.rbegin(), inputs.rbegin() + 1, inputs.rend());
987 DerivedFunction::call(inputs, B);
988 return inputs.front();
997 DerivedFunction::call(inputs, B);
1004 const char* name =
nullptr,
1005 const bool axTypes =
true)
const override 1008 ArgInfo ret = this->types(current, C);
1010 std::rotate(current.
begin(), current.
begin() + 1, current.
end());
1011 ret = current.
back();
1015 names.reserve(this->size());
1016 for (
size_t i = 0; i < this->size()-1; ++i) {
1017 names.emplace_back(this->argName(i));
1022 #if LLVM_VERSION_MAJOR <= 15 1024 using Function::types;
1030 llvm::LLVMContext& C)
const override 1033 std::vector<llvm::Type*> inputs(args);
1035 std::rotate(inputs.rbegin(), inputs.rbegin() + 1, inputs.rend());
1036 return DerivedFunction::match(inputs, C);
1043 call(
const std::vector<llvm::Value*>& args,
1044 llvm::IRBuilder<>& B,
1045 const bool cast)
const override 1048 std::vector<llvm::Value*> inputs(args);
1051 std::rotate(inputs.rbegin(), inputs.rbegin() + 1, inputs.rend());
1052 DerivedFunction::call(inputs, B, cast);
1053 return inputs.front();
1059 template <
typename ...Args>
1066 using Ptr = std::shared_ptr<CFunctionBase>;
1072 virtual uint64_t address()
const = 0;
1077 #if LLVM_VERSION_MAJOR <= 15 1080 const std::vector<llvm::Value*>&,
1081 llvm::LLVMContext&)
const 1086 inline virtual llvm::Value* fold(
1087 const llvm::ArrayRef<llvm::Value*>&,
1088 llvm::LLVMContext&)
const 1096 const std::string& symbol)
1098 , mConstantFold(false) {}
1109 template <
typename SignatureT>
1113 using Ptr = std::shared_ptr<CFunctionT>;
1119 static_assert(std::is_same<typename Traits::ReturnType, void*>::value ||
1120 !std::is_pointer<typename Traits::ReturnType>::value,
1121 "CFunction object has been setup with a pointer return argument. C bindings " 1122 "cannot return memory locations to LLVM - Consider using a CFunctionSRet.");
1126 , mFunction(function) {}
1132 return llvmArgTypesFromSignature<SignatureT>(C, &types);
1137 return reinterpret_cast<uint64_t
>(mFunction);
1141 call(
const std::vector<llvm::Value*>& args,
1142 llvm::IRBuilder<>& B)
const override 1144 llvm::Value* result = this->fold(args, B.getContext());
1145 if (result)
return result;
1146 return Function::call(args, B);
1151 llvm::Constant* result = this->fold(args.
AsLLVMValues(), B.getContext());
1152 if (result)
return Value(result);
1153 return Function::call(args, B);
1156 #if LLVM_VERSION_MAJOR <= 15 1157 llvm::Constant*
fold(
const std::vector<llvm::Value*>& args, llvm::LLVMContext& C)
const override final 1159 llvm::Constant* fold(
const llvm::ArrayRef<llvm::Value*>& args, llvm::LLVMContext& C)
const override final 1162 if (!this->hasConstantFold())
return nullptr;
1164 for (
auto& value : args) {
1165 if (!llvm::isa<llvm::Constant>(value))
return nullptr;
1166 constants.emplace_back(llvm::cast<llvm::Constant>(value));
1172 #if LLVM_VERSION_MAJOR <= 15 1173 inline llvm::Type*
types(std::vector<llvm::Type*>& types, llvm::LLVMContext& C)
const override 1175 return llvmTypesFromSignature<SignatureT>(C, &types);
1182 call(
const std::vector<llvm::Value*>& args,
1183 llvm::IRBuilder<>& B,
1184 const bool cast)
const override 1186 llvm::Value* result = this->fold(args, B.getContext());
1187 if (result)
return result;
1188 return Function::call(args, B, cast);
1193 SignatureT* mFunction;
1199 using Ptr = std::shared_ptr<IRFunctionBase>;
1220 (
const std::vector<llvm::Value*>&,
1221 llvm::IRBuilder<>&)>;
1241 create(llvm::LLVMContext& C, llvm::Module* M)
const override;
1248 call(
const std::vector<llvm::Value*>& args,
1249 llvm::IRBuilder<>& B)
const override;
1251 Value call(
const Arguments& args, llvm::IRBuilder<>&)
const override;
1253 #if LLVM_VERSION_MAJOR <= 15 1257 call(
const std::vector<llvm::Value*>& args,
1258 llvm::IRBuilder<>& B,
1259 const bool cast)
const override;
1269 if (result == expected)
return;
1270 std::string source, target;
1274 "\" has been invoked with a mismatching return type. Expected: \"" +
1275 target +
"\", got \"" + source +
"\".");
1281 , mGen([this, gen](const
Arguments& args,
llvm::IRBuilder<>& B) {
1282 llvm::Value* result = gen(args.AsLLVMValues(), B);
1283 if (!result)
return Value::Invalid();
1287 if (result->getType()->isPointerTy())
1289 #if LLVM_VERSION_MAJOR <= 15 1290 return Value(result, result->getType()->getPointerElementType());
1293 ArgInfo r = this->types(unused, result->getContext());
1299 return Value(result, result->getType());
1302 , mEmbedIR(
false) {}
1309 return gen(args.AsNativeValues(), B);
1311 , mEmbedIR(
false) {}
1317 , mEmbedIR(false) {}
1325 template <
typename SignatureT>
1329 using Ptr = std::shared_ptr<IRFunction>;
1340 return llvmArgTypesFromSignature<SignatureT>(C, &types);
1343 #if LLVM_VERSION_MAJOR <= 15 1345 types(std::vector<llvm::Type*>& types, llvm::LLVMContext& C)
const override 1347 return llvmTypesFromSignature<SignatureT>(C, &types);
1354 template <
typename SignatureT>
1359 :
BaseT(symbol, function) {}
1365 template <
typename SignatureT>
1371 :
BaseT(symbol, gen) {}
1374 :
BaseT(symbol, gen) {}
1377 :
BaseT(symbol, gen) {}
1391 using Ptr = std::shared_ptr<FunctionGroup>;
1400 , mFunctionList(list) {}
1404 bool HasUniqueTypeSignatures(llvm::LLVMContext& C)
const;
1425 std::pair<const Function*, Function::SignatureMatch>
1426 match(
const ArgInfoVector& args, llvm::LLVMContext& C)
const;
1438 Value execute(
const Arguments& args, llvm::IRBuilder<>& B)
const;
1453 const char*
name()
const {
return mName; }
1454 const char*
doc()
const {
return mDoc; }
1456 #if LLVM_VERSION_MAJOR <= 15 1461 match(
const std::vector<llvm::Type*>& types,
1462 llvm::LLVMContext& C,
1466 "supports argument matching/casting is incompatible with LLVM 16+ and will be " 1469 execute(
const std::vector<llvm::Value*>& args,
1470 llvm::IRBuilder<>& B)
const;
1486 "supports argument matching/casting is incompatible with LLVM 16+ and will be " 1489 execute(
const std::vector<llvm::Value*>& args,
1490 llvm::IRBuilder<>& B,
1491 llvm::Value*& result)
const;
1517 using Ptr = std::shared_ptr<Settings>;
1521 if (mNames)
return false;
1522 if (!mDeps.empty())
return false;
1523 if (mConstantFold || mEmbedIR || mReadOnly || mBuiltin)
return false;
1524 if (!mFnAttrs.empty())
return false;
1525 if (!mRetAttrs.empty())
return false;
1526 if (!mParamAttrs.empty())
return false;
1530 std::unique_ptr<SmallArgumentVector<const char*>> mNames =
nullptr;
1532 bool mConstantFold =
false;
1533 bool mEmbedIR =
false;
1534 bool mReadOnly =
false;
1535 bool mBuiltin =
false;
1538 std::map<size_t, SmallArgumentVector<llvm::Attribute::AttrKind>> mParamAttrs = {};
1543 , mCurrentSettings(
std::make_shared<
Settings>()) {}
1546 template <
typename Signature,
bool SRet = false>
1550 using CFType =
typename std::conditional
1552 const std::string s = symbol ? symbol : this->genSymbol<Signature>();
1553 this->addSignatureImpl<CFType>(s, ptr);
1558 template <
typename Signature,
bool SRet = false>
1561 const char* symbol =
nullptr)
1563 using IRFType =
typename std::conditional
1566 const std::string s = symbol ? symbol : this->genSymbol<Signature>();
1567 this->addSignatureImpl<IRFType>(s, cb);
1572 template <
typename Signature,
bool SRet = false>
1576 this->addSignature<Signature, SRet>(cb, symbol);
1577 this->addSignature<Signature, SRet>(ptr, symbol);
1582 template <
typename Signature,
bool SRet = false>
1587 using IRFType =
typename std::conditional
1590 const std::string s = symbol ? symbol : this->genSymbol<Signature>();
1591 this->addSignatureImpl<IRFType>(s, cb);
1596 template <
typename Signature,
bool SRet = false>
1601 this->addSignature<Signature, SRet>(cb, symbol);
1602 this->addSignature<Signature, SRet>(ptr, symbol);
1607 template <
typename Signature,
bool SRet = false>
1610 const char* symbol =
nullptr)
1612 using IRFType =
typename std::conditional
1615 const std::string s = symbol ? symbol : this->genSymbol<Signature>();
1616 this->addSignatureImpl<IRFType>(s, cb);
1621 template <
typename Signature,
bool SRet = false>
1625 this->addSignature<Signature, SRet>(cb, symbol);
1626 this->addSignature<Signature, SRet>(ptr, symbol);
1632 mCurrentSettings->mDeps.emplace_back(name);
return *
this;
1639 mCurrentSettings->mNames = std::make_unique<SmallArgumentVector<const char*>>();
1640 mCurrentSettings->mNames->assign(names.begin(), names.end());
1655 mCurrentSettings->mParamAttrs[idx].emplace_back(attr);
1662 mCurrentSettings->mRetAttrs.emplace_back(attr);
1669 mCurrentSettings->mFnAttrs.emplace_back(attr);
1683 mCurrentSettings->mReadOnly = on;
1714 mCurrentSettings->mBuiltin = on;
1732 for (
auto& decl : mCFunctions)
1734 const auto& s = mSettings.at(decl.get());
1735 if (s->mNames) decl->mNames = *s->mNames;
1736 decl->mDeps = s->mDeps;
1738 if (!s->mFnAttrs.empty()) decl->attrs().mFnAttrs = s->mFnAttrs;
1739 if (!s->mRetAttrs.empty()) decl->attrs().mRetAttrs = s->mRetAttrs;
1740 if (!s->mParamAttrs.empty()) {
1741 for (
auto& idxAttrs : s->mParamAttrs) {
1742 if (idxAttrs.first > decl->size())
continue;
1743 decl->attrs().mParamAttrs[idxAttrs.first] = idxAttrs.second;
1746 if (s->mReadOnly) decl->attrs().mReadOnly =
true;
1747 if (s->mBuiltin) decl->attrs().mBuiltin =
true;
1750 for (
auto& decl : mIRFunctions)
1752 const auto& s = mSettings.at(decl.get());
1753 if (s->mNames) decl->mNames = *s->mNames;
1754 decl->mDeps = s->mDeps;
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;
1764 if (s->mReadOnly) decl->attrs().mReadOnly =
true;
1765 if (s->mBuiltin) decl->attrs().mBuiltin =
true;
1770 if (mDeclPref == DeclPreferrence::IR) {
1771 functions.insert(functions.end(), mIRFunctions.begin(), mIRFunctions.end());
1773 if (mDeclPref == DeclPreferrence::C) {
1774 functions.insert(functions.end(), mCFunctions.begin(), mCFunctions.end());
1776 if (functions.empty()) {
1777 functions.insert(functions.end(), mIRFunctions.begin(), mIRFunctions.end());
1778 functions.insert(functions.end(), mCFunctions.begin(), mCFunctions.end());
1781 return std::make_unique<FunctionGroup>(mName, mDoc, std::move(functions));
1785 template <
typename FunctionT,
typename...Args>
1789 if (!mCurrentSettings->isDefault()) {
1790 settings = std::make_shared<Settings>();
1792 auto ptr = std::make_shared<FunctionT>(std::move(args)...);
1793 if constexpr (std::is_base_of_v<IRFunctionBase, FunctionT>) {
1794 mIRFunctions.emplace_back(ptr);
1797 static_assert(std::is_base_of_v<CFunctionBase, FunctionT>);
1798 mCFunctions.emplace_back(ptr);
1800 mSettings[ptr.get()] = settings;
1801 mCurrentSettings = settings;
1805 template <
typename Signature>
1806 std::string genSymbol()
const 1811 auto callback = [&args](
auto type) {
1812 using Type = decltype(type);
1822 return "ax." + std::string(this->mName) +
"." +
1827 const char* mName =
"";
1828 const char* mDoc =
"";
1830 std::vector<CFunctionBase::Ptr> mCFunctions = {};
1831 std::vector<IRFunctionBase::Ptr> mIRFunctions = {};
1832 std::map<const Function*, Settings::Ptr> mSettings = {};
1841 #endif // OPENVDB_AX_CODEGEN_FUNCTION_TYPES_HAS_BEEN_INCLUDED Arguments(const NativeArguments &args)
Definition: FunctionTypes.h:387
auto & front()
Definition: FunctionTypes.h:303
ArgInfo(const Value &val)
Definition: FunctionTypes.h:226
Object to array conversion methods to allow functions to return vector types. These containers provid...
Definition: FunctionTypes.h:117
bool isDefault() const
Definition: FunctionTypes.h:1519
static std::string s()
Definition: FunctionTypes.h:159
Constant folding support structure.
Definition: ConstantFolding.h:35
ArgInfo & operator[](size_t pos)
Definition: FunctionTypes.h:316
FunctionBuilder & setDocumentation(const char *doc)
Definition: FunctionTypes.h:1718
static std::string s()
Definition: FunctionTypes.h:152
const ArgInfoVector & GetArgInfo() const
Definition: FunctionTypes.h:428
auto rend()
Definition: FunctionTypes.h:300
typename ArgT::Type ArgumentValueType
Definition: FunctionTypes.h:191
void emplace_back(Args &&...args)
Definition: FunctionTypes.h:315
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorNativeCb &cb, const char *symbol=nullptr)
Definition: FunctionTypes.h:1584
Represents a concrete C function binding with the first argument as its return type.
Definition: FunctionTypes.h:1355
Definition: FunctionRegistry.h:23
Value AsNativeValue(const size_t i) const
Definition: FunctionTypes.h:410
FunctionBuilder & setArgumentNames(const std::vector< const char * > &names)
Definition: FunctionTypes.h:1637
void PrependArg(const Value &val)
Definition: FunctionTypes.h:454
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
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:957
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Definition: FunctionTypes.h:1512
bool operator==(const Vec3< T0 > &v0, const Vec3< T1 > &v1)
Equality operator, does exact floating point comparisons.
Definition: Vec3.h:474
const char * symbol() const
The function symbol name.
Definition: FunctionTypes.h:766
Represents a concrete C function binding.
Definition: FunctionTypes.h:1110
auto & back()
Definition: FunctionTypes.h:305
CFunctionSRet(const std::string &symbol, const SignatureT function)
Definition: FunctionTypes.h:1358
auto erase(ContainerT::const_iterator iter)
Definition: FunctionTypes.h:311
T Type
Definition: FunctionTypes.h:118
IRFunction(const std::string &symbol, const GeneratorCb &gen)
Definition: FunctionTypes.h:1331
const char * name() const
Definition: FunctionTypes.h:1453
IRFunction(const std::string &symbol, const GeneratorNativeCb &gen)
Definition: FunctionTypes.h:1333
#define OPENVDB_ASSERT_MESSAGE(X, MSG)
Definition: Assert.h:42
The base class for all C bindings.
Definition: FunctionTypes.h:1064
Value call(const Arguments &args, llvm::IRBuilder<> &B) const override
Definition: FunctionTypes.h:991
Function::SignatureMatch match(const std::vector< llvm::Type * > &args, llvm::LLVMContext &C) const override
Definition: FunctionTypes.h:1029
ArgInfo(llvm::Type *utype)
Definition: FunctionTypes.h:228
Alias mapping between two types, a frontend type T1 and a backend type T2. This class is the intended...
Definition: Types.h:268
Definition: FunctionTypes.h:727
static std::string s()
Definition: FunctionTypes.h:148
bool operator!=(const ArgInfoVector &other) const
Definition: FunctionTypes.h:293
llvm::FunctionType * llvmFunctionTypeFromSignature(llvm::LLVMContext &C)
Generate an LLVM FunctionType from a function signature.
Definition: FunctionTypes.h:554
const llvm::ArrayRef< llvm::Value * > AsLLVMValues() const
Definition: FunctionTypes.h:426
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorNativeCb &cb, const Signature *ptr, const char *symbol=nullptr)
Definition: FunctionTypes.h:1598
auto end() const
Definition: FunctionTypes.h:298
LLVM type mapping from pod types.
Definition: Types.h:67
Type[SIZE] ArrayType
Definition: FunctionTypes.h:120
Templated interface class for SRET functions. This struct provides the interface for functions that w...
Definition: FunctionTypes.h:913
OPENVDB_AX_API void print(const ast::Node &node, const bool numberStatements=true, std::ostream &os=std::cout, const char *indent=" ")
Writes a descriptive printout of a Node hierarchy into a target stream.
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
auto size() const
Definition: FunctionTypes.h:309
Consolidated llvm types for most supported types.
OPENVDB_AX_API NativeArguments Cast(const Function &F, llvm::IRBuilder<> &B) const
Cast these arguments to match the given function's signature.
std::unique_ptr< FunctionGroup > UniquePtr
Definition: FunctionTypes.h:1392
std::vector< Function::Ptr > FunctionList
Definition: FunctionTypes.h:1393
void SetIsReturn()
Definition: FunctionTypes.h:268
The base/abstract representation of an AX function. Derived classes must implement the Function::type...
Definition: FunctionTypes.h:602
const SmallArgumentVector< const char * > & dependencies() const
Definition: FunctionTypes.h:794
uint64_t address() const override final
Returns the global address of this function.
Definition: FunctionTypes.h:1135
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B) const override
Definition: FunctionTypes.h:1141
IRFunctionSRet(const std::string &symbol, const IRFunctionBase::GeneratorArgumentsCb &gen)
Definition: FunctionTypes.h:1375
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
Function(const size_t size, const std::string &symbol)
Definition: FunctionTypes.h:606
uint8_t NumPtrs() const
Definition: FunctionTypes.h:255
static std::string s()
Definition: FunctionTypes.h:154
llvm::Type * types(std::vector< llvm::Type * > &types, llvm::LLVMContext &C) const override
Definition: FunctionTypes.h:1173
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorCb &cb, const Signature *ptr, const char *symbol=nullptr)
Definition: FunctionTypes.h:1574
bool mEmbedIR
Definition: FunctionTypes.h:1321
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:979
bool IsPtr() const
Definition: FunctionTypes.h:254
bool IsMatchingType(const ArgInfo &other) const
Definition: FunctionTypes.h:248
const FunctionList & list() const
Accessor to the underlying function signature list.
Definition: FunctionTypes.h:1452
static std::string s()
Definition: FunctionTypes.h:160
Arbitrary, potentially "non-native" arguments. This wrapper struct can be used when generating functi...
Definition: FunctionTypes.h:381
FunctionBuilder & setConstantFold(bool on)
Definition: FunctionTypes.h:1636
size_t size() const
Definition: FunctionTypes.h:400
llvm::Constant * fold(const std::vector< llvm::Value * > &args, llvm::LLVMContext &C) const override final
Definition: FunctionTypes.h:1157
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorArgumentsCb &cb, const char *symbol=nullptr)
Definition: FunctionTypes.h:1609
auto rbegin()
Definition: FunctionTypes.h:299
NativeArguments(const std::vector< Value > &args)
Definition: FunctionTypes.h:353
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:1338
static std::string s()
Definition: FunctionTypes.h:150
bool IsReturn() const
Definition: FunctionTypes.h:258
SmallArgumentVector< ArgInfo > ContainerT
Definition: FunctionTypes.h:282
FunctionBuilder & setPreferredImpl(DeclPreferrence pref)
Definition: FunctionTypes.h:1724
static void apply(const OpT &op, const bool forwards)
Definition: FunctionTypes.h:200
std::shared_ptr< FunctionGroup > Ptr
Definition: FunctionTypes.h:1391
FunctionBuilder & setBuiltin(const bool on)
Mark functions currently sharing settings as builtin AX methods. At compile time, this causes the IR ...
Definition: FunctionTypes.h:1709
Represents a concrete IR function.
Definition: FunctionTypes.h:1326
FunctionGroup(const char *name, const char *doc, const FunctionList &list)
Definition: FunctionTypes.h:1395
std::shared_ptr< Settings > Ptr
Definition: FunctionTypes.h:1517
CFunctionBase(const size_t size, const std::string &symbol)
Definition: FunctionTypes.h:1095
Value & operator[](size_t pos)
Definition: FunctionTypes.h:360
NativeArguments AsNativeValues() const
Definition: FunctionTypes.h:416
IRFunctionSRet(const std::string &symbol, const IRFunctionBase::GeneratorCb &gen)
Definition: FunctionTypes.h:1369
bool operator==(const ArgInfo &other) const
Definition: FunctionTypes.h:240
auto empty() const
Definition: FunctionTypes.h:310
ArrayType mmArgs
Definition: FunctionTypes.h:121
A group of functions which all have the same name but different signatures. For example: float abs(fl...
Definition: FunctionTypes.h:1389
void AddArg(llvm::Value *val, const ArgInfo &type)
Definition: FunctionTypes.h:436
static std::string s()
Definition: FunctionTypes.h:153
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
llvm::Value * operator[](size_t pos) const
Definition: FunctionTypes.h:430
IRFunctionSRet(const std::string &symbol, const IRFunctionBase::GeneratorNativeCb &gen)
Definition: FunctionTypes.h:1372
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B, const bool cast) const override
Definition: FunctionTypes.h:1182
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
bool IsNative() const
Definition: FunctionTypes.h:256
ArgInfo(llvm::Type *utype, uint8_t ptrs, bool ret=false)
Definition: FunctionTypes.h:229
Templated argument iterator which implements various small functions per argument type...
Definition: FunctionTypes.h:188
Definition: FunctionTypes.h:163
Definition: FunctionTypes.h:728
static std::string s()
Definition: FunctionTypes.h:147
typename FunctionTraits< SignatureT >::template Arg< I-1 > ArgT
Definition: FunctionTypes.h:190
Definition: Exceptions.h:13
DeclPreferrence
Definition: FunctionTypes.h:1511
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:944
auto rbegin() const
Definition: FunctionTypes.h:301
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:1221
void reserve(size_t i)
Definition: FunctionTypes.h:313
bool AreNativeValues() const
Definition: FunctionTypes.h:402
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:1653
static void apply(const OpT &, const bool)
Definition: FunctionTypes.h:217
size_t size() const
Definition: FunctionTypes.h:359
const GeneratorArgumentsCb mGen
Definition: FunctionTypes.h:1320
FunctionBuilder & setEmbedIR(bool on)
Definition: FunctionTypes.h:1635
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorArgumentsCb &cb, const Signature *ptr, const char *symbol=nullptr)
Definition: FunctionTypes.h:1623
bool hasConstantFold() const
Definition: FunctionTypes.h:1075
SRetFunction(Args &&...ts)
Forward all arguments to the derived class.
Definition: FunctionTypes.h:1060
static std::string s()
Definition: FunctionTypes.h:169
const Value & operator[](size_t pos) const
Definition: FunctionTypes.h:365
FunctionBuilder & addDependency(const char *name)
Definition: FunctionTypes.h:1630
Definition: Exceptions.h:38
An extremely basic but native representation of a string class with SSO support. This exists to provi...
Definition: String.h:33
Definition: FunctionTypes.h:1515
void verifyResultType(const llvm::Type *result, const llvm::Type *expected) const
Definition: FunctionTypes.h:1267
auto pop_back()
Definition: FunctionTypes.h:307
OPENVDB_AX_API void printSignature(std::ostream &os, const std::vector< llvm::Type * > &types, const llvm::Type *returnType, const char *name=nullptr, const std::vector< const char * > &names={}, const bool axTypes=false)
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:1212
auto clear()
Definition: FunctionTypes.h:308
static std::string s()
Definition: FunctionTypes.h:157
NativeArguments(const std::initializer_list< Value > &args)
Definition: FunctionTypes.h:351
Type to symbol conversions - these characters are used to build each functions unique signature...
Definition: FunctionTypes.h:147
void setEmbedIR(bool on)
Enable or disable the embedding of IR. Embedded IR is currently required for function which use paren...
Definition: FunctionTypes.h:1225
auto & back() const
Definition: FunctionTypes.h:306
static std::string s()
Definition: FunctionTypes.h:151
IRFunctionBase(const std::string &symbol, const GeneratorNativeCb &gen, const size_t size)
Definition: FunctionTypes.h:1303
Constant folding for C++ bindings.
static std::string s()
Definition: FunctionTypes.h:149
The base/abstract definition for an IR function.
Definition: FunctionTypes.h:1197
void llvmTypeToString(const llvm::Type *const type, std::string &str)
Prints an llvm type to a std string.
Definition: Utils.h:80
FunctionBuilder & addReturnAttribute(const llvm::Attribute::AttrKind attr)
Definition: FunctionTypes.h:1660
auto end()
Definition: FunctionTypes.h:296
FunctionBuilder & setReadOnly(const bool on)
Mark functions currently sharing settings with as "readonly". This enables the strictest possible mem...
Definition: FunctionTypes.h:1681
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:1002
llvm::Value * call(const std::vector< llvm::Value * > &args, llvm::IRBuilder<> &B, const bool cast) const override
Definition: FunctionTypes.h:1043
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
Intermediate representation of supported AX values.
auto begin() const
Definition: FunctionTypes.h:297
llvm::Value * GetValue() const
Access the underlying llvm Value.
Definition: Value.h:673
const char * doc() const
Definition: FunctionTypes.h:1454
void AddArg(const Value &val)
Definition: FunctionTypes.h:370
llvm::Type * GetUnderlyingType() const
Definition: FunctionTypes.h:259
SmallArgumentVector< llvm::Type * > AsLLVMTypes() const
Definition: FunctionTypes.h:327
Intermediate representation wrapper for supported value types in AX as immutable instances.
Definition: Value.h:62
ArgInfo llvmArgTypesFromSignature(llvm::LLVMContext &C, ArgInfoVector *types=nullptr)
Populate a vector of ArgInfos from a function signature declaration.
Definition: FunctionTypes.h:506
std::function< Value(const Arguments &, llvm::IRBuilder<> &)> GeneratorArgumentsCb
Definition: FunctionTypes.h:1215
Value call(const Arguments &args, llvm::IRBuilder<> &B) const override
Definition: FunctionTypes.h:1149
bool hasEmbedIR() const
Definition: FunctionTypes.h:1226
FunctionBuilder & addFunctionAttribute(const llvm::Attribute::AttrKind attr)
Definition: FunctionTypes.h:1667
IRFunctionBase(const std::string &symbol, const GeneratorArgumentsCb &gen, const size_t size)
Definition: FunctionTypes.h:1312
Value call(const NativeArguments &args, llvm::IRBuilder<> &B) const
Definition: FunctionTypes.h:716
Definition: FunctionTypes.h:729
IRFunction(const std::string &symbol, const GeneratorArgumentsCb &gen)
Definition: FunctionTypes.h:1335
Utility code generation methods for performing various llvm operations.
static std::string s()
Definition: FunctionTypes.h:158
Metadata associated with a function argument or return value.
Definition: FunctionTypes.h:224
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:1130
IRFunctionBase(const std::string &symbol, const GeneratorCb &gen, const size_t size)
Definition: FunctionTypes.h:1277
SignatureMatch
The result type from calls to Function::match.
Definition: FunctionTypes.h:724
Wrapper struct to represent "native" function arguments; that is, the set of Value type that the AX g...
Definition: FunctionTypes.h:348
ArgInfoVector(const std::initializer_list< ArgInfo > &info)
Definition: FunctionTypes.h:285
std::shared_ptr< Function > Ptr
Definition: FunctionTypes.h:604
const ArgInfo & operator[](size_t pos) const
Definition: FunctionTypes.h:321
bool operator!=(const ArgInfo &other) const
Definition: FunctionTypes.h:247
static std::string s()
Definition: FunctionTypes.h:164
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
size_t size() const
The number of arguments that this function has.
Definition: FunctionTypes.h:762
Container of ArgInfos. This class makes up part of the Function API for querying signature informatio...
Definition: FunctionTypes.h:279
FunctionBuilder & addSignature(const Signature *ptr, const char *symbol=nullptr)
Definition: FunctionTypes.h:1548
FunctionBuilder(const char *name)
Definition: FunctionTypes.h:1541
Templated function traits which provides compile-time index access to the types of the function signa...
Definition: Types.h:311
const char * argName(const size_t idx) const
Returns the descriptive name of the given argument index.
Definition: FunctionTypes.h:773
void AddArg(const Value &val)
Definition: FunctionTypes.h:448
static std::string s()
Definition: FunctionTypes.h:155
FunctionBuilder & addSignature(const IRFunctionBase::GeneratorCb &cb, const char *symbol=nullptr)
Definition: FunctionTypes.h:1560
bool IsVoid() const
Definition: FunctionTypes.h:257
The FunctionBuilder class provides a builder pattern framework to allow easy and valid construction o...
Definition: FunctionTypes.h:1509
const ArgInfo & GetArgInfo(size_t pos) const
Definition: FunctionTypes.h:427
auto & front() const
Definition: FunctionTypes.h:304
virtual llvm::Value * fold(const std::vector< llvm::Value * > &, llvm::LLVMContext &) const
Definition: FunctionTypes.h:1079
Represents a concrete IR function with the first argument as its return type.
Definition: FunctionTypes.h:1366
CFunction(const std::string &symbol, SignatureT *function)
Definition: FunctionTypes.h:1124
llvm::Type * GetType() const
Definition: FunctionTypes.h:260
static std::string s()
Definition: FunctionTypes.h:156
auto rend() const
Definition: FunctionTypes.h:302
bool operator==(const ArgInfoVector &other) const
Definition: FunctionTypes.h:292
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
void setConstantFold(bool on)
Definition: FunctionTypes.h:1074
auto begin()
Definition: FunctionTypes.h:295
llvm::Type * types(std::vector< llvm::Type * > &types, llvm::LLVMContext &C) const override
Definition: FunctionTypes.h:1345