OpenVDB
13.0.0
Toggle main menu visibility
Loading...
Searching...
No Matches
ConstantFolding.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/ConstantFolding.h
5
///
6
/// @authors Nick Avramoussis
7
///
8
/// @brief Constant folding for C++ bindings.
9
///
10
11
#ifndef OPENVDB_AX_CODEGEN_CONSTANT_FOLDING_HAS_BEEN_INCLUDED
12
#define OPENVDB_AX_CODEGEN_CONSTANT_FOLDING_HAS_BEEN_INCLUDED
13
14
#include "
Types.h
"
15
16
#include <openvdb/version.h>
17
#include <
openvdb/util/Assert.h
>
18
19
#include <llvm/IR/Constants.h>
20
21
#include <type_traits>
22
#include <vector>
23
24
namespace
openvdb
{
25
OPENVDB_USE_VERSION_NAMESPACE
26
namespace
OPENVDB_VERSION_NAME
{
27
28
namespace
ax {
29
namespace
codegen {
30
31
/// @brief Constant folding support structure
32
///
33
template
<
typename
SignatureT,
34
size_t
I = FunctionTraits<SignatureT>::N_ARGS>
35
struct
ConstantFolder
36
{
37
using
ArgT
=
typename
FunctionTraits<SignatureT>::template
Arg<I-1>;
38
using
ArgumentValueType
=
typename
ArgT::Type;
39
40
// @brief Attempts evaluate a given function with a provided set of constant llvm
41
// values. If successful, the function is invoked and the result is stored
42
// and returned in an llvm::Value.
43
// @details Currently only scalar constant folding is supported due to the way
44
// vectors and matrices are alloced. Functions which return void are also
45
// not supported for constant folding.
46
// @param args The vector of llvm constants that comprise the function arguments.
47
// Note that the size of this vector is expected to match the size of
48
// the required function arguments and the templated parameter I
49
// @param function The function to invoke if all arguments have a valid mapping.
50
// @param C The llvm Context
51
// @param ts The list of evaluated C types from the provided llvm constants. This
52
// is expected to be empty (not provided) on the first call to fold and
53
// is used on subsequent recursive calls.
54
template
<
typename
...Tys>
55
static
llvm::Constant*
56
fold
(
const
llvm::ArrayRef<llvm::Constant*>& args,
57
const
SignatureT& function,
58
llvm::LLVMContext& C,
59
Tys&&... ts)
60
{
61
OPENVDB_ASSERT
(I-1 < args.size());
62
llvm::Constant* constant = args[I-1];
63
const
llvm::Type* type = constant->getType();
64
if
(type->isIntegerTy()) {
65
OPENVDB_ASSERT
(llvm::isa<llvm::ConstantInt>(constant));
66
llvm::ConstantInt* cint =
67
llvm::cast<llvm::ConstantInt>(constant);
68
const
uint64_t val = cint->getLimitedValue();
69
return
call<uint64_t, ArgumentValueType>(args, function, C, val, ts...);
70
}
71
else
if
(type->isFloatTy() || type->isDoubleTy()) {
72
OPENVDB_ASSERT
(llvm::isa<llvm::ConstantFP>(constant));
73
llvm::ConstantFP* cfp =
74
llvm::cast<llvm::ConstantFP>(constant);
75
const
llvm::APFloat& apf = cfp->getValueAPF();
76
if
(type->isFloatTy()) {
77
const
float
val = apf.convertToFloat();
78
return
call<float, ArgumentValueType>(args, function, C, val, ts...);
79
}
80
if
(type->isDoubleTy()) {
81
const
double
val = apf.convertToDouble();
82
return
call<double, ArgumentValueType>(args, function, C, val, ts...);
83
}
84
}
85
else
if
(type->isArrayTy()) {
86
// @todo currently all arrays are alloced anyway which
87
// needs to be handled or changed
88
return
nullptr
;
89
}
90
// fallback
91
return
nullptr
;
92
}
93
private
:
94
// @brief Specialization for supported implicit casting matching AX's supported
95
// scalar casting. Continues to traverse the constant argument list.
96
template
<
typename
In,
typename
Out,
typename
...Tys>
97
static
typename
std::enable_if<std::is_convertible<In, Out>::value, llvm::Constant*>::type
98
call(
const
llvm::ArrayRef<llvm::Constant*>& args,
99
const
SignatureT& function,
100
llvm::LLVMContext& C,
101
const
In& arg,
102
Tys&&... ts)
103
{
104
using
Next =
ConstantFolder
<SignatureT, I-1>;
105
return
Next::fold(args, function, C, Out(arg), ts...);
106
}
107
108
// @brief Specialization for unsupported implicit casting. Bails out with a
109
// nullptr return.
110
template
<
typename
In,
typename
Out,
typename
...Tys>
111
static
typename
std::enable_if<!std::is_convertible<In, Out>::value, llvm::Constant*>::type
112
call(
const
llvm::ArrayRef<llvm::Constant*>&,
113
const
SignatureT&,
114
llvm::LLVMContext&,
115
const
In&, Tys&&...)
116
{
117
return
nullptr
;
118
}
119
};
120
121
template
<
typename
SignatureT>
122
struct
ConstantFolder
<SignatureT, 0>
123
{
124
// @brief The final call to fold when all arguments have been evaluated (or no
125
// arguments exist).
126
template
<
typename
...Tys>
127
static
llvm::Constant*
128
fold
(
const
llvm::ArrayRef<llvm::Constant*>& args,
129
const
SignatureT& function,
130
llvm::LLVMContext& C,
131
Tys&&... ts)
132
{
133
using
ReturnT =
typename
FunctionTraits<SignatureT>::ReturnType
;
134
return
call<ReturnT>(args, function, C, ts...);
135
}
136
137
private
:
138
139
// @brief Specialization for the invoking of the provided function if the return
140
// type is not void or a pointer
141
template
<
typename
ReturnT,
typename
...Tys>
142
static
typename
std::enable_if<!std::is_pointer<ReturnT>::value &&
143
!std::is_same<ReturnT, void>::value, llvm::Constant*>::type
144
call(
const
llvm::ArrayRef<llvm::Constant*>&,
145
const
SignatureT& function,
146
llvm::LLVMContext& C,
147
Tys&&... ts)
148
{
149
const
ReturnT result = function(ts...);
150
return
LLVMType<ReturnT>::get
(C, result);
151
}
152
153
// @brief Specialization if the return type is void or a pointer. No folding is
154
// supported.
155
template
<
typename
ReturnT,
typename
...Tys>
156
static
typename
std::enable_if<std::is_pointer<ReturnT>::value ||
157
std::is_same<ReturnT, void>::value, llvm::Constant*>::type
158
call(
const
llvm::ArrayRef<llvm::Constant*>&,
159
const
SignatureT&,
160
llvm::LLVMContext&,
161
Tys&&...)
162
{
163
return
nullptr
;
164
}
165
};
166
167
}
// namespace codegen
168
}
// namespace ax
169
}
// namespace OPENVDB_VERSION_NAME
170
}
// namespace openvdb
171
172
#endif
// OPENVDB_AX_CODEGEN_CONSTANT_FOLDING_HAS_BEEN_INCLUDED
173
Assert.h
OPENVDB_ASSERT
#define OPENVDB_ASSERT(X)
Definition
Assert.h:41
Types.h
Consolidated llvm types for most supported types.
openvdb
Definition
Exceptions.h:13
openvdb::v13_0::ax::codegen::ConstantFolder< SignatureT, 0 >::fold
static llvm::Constant * fold(const llvm::ArrayRef< llvm::Constant * > &args, const SignatureT &function, llvm::LLVMContext &C, Tys &&... ts)
Definition
ConstantFolding.h:128
openvdb::v13_0::ax::codegen::ConstantFolder
Constant folding support structure.
Definition
ConstantFolding.h:36
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::ConstantFolder::ArgT
typename FunctionTraits< SignatureT >::template Arg< I-1 > ArgT
Definition
ConstantFolding.h:37
openvdb::v13_0::ax::codegen::ConstantFolder::ArgumentValueType
typename ArgT::Type ArgumentValueType
Definition
ConstantFolding.h:38
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::LLVMType::get
static llvm::Type * get(llvm::LLVMContext &C)
Return an LLVM type which represents T.
Definition
Types.h:81
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
openvdb_ax
codegen
ConstantFolding.h
Generated by
1.18.0