OpenVDB 12.1.0
Loading...
Searching...
No Matches
ComputeGenerator.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/ComputeGenerator.h
5///
6/// @authors Nick Avramoussis, Matt Warner, Francisco Gochez, Richard Jones
7///
8/// @brief The core visitor framework for code generation
9///
10
11#ifndef OPENVDB_AX_COMPUTE_GENERATOR_HAS_BEEN_INCLUDED
12#define OPENVDB_AX_COMPUTE_GENERATOR_HAS_BEEN_INCLUDED
13
14#include "FunctionRegistry.h"
15#include "FunctionTypes.h"
16#include "SymbolTable.h"
17#include "Value.h"
18
19#include "../ast/AST.h"
20#include "../ast/Visitor.h"
22#include "../compiler/Logger.h"
23
24#include <openvdb/version.h>
25
26#include <llvm/Analysis/TargetLibraryInfo.h>
27#include <llvm/IR/BasicBlock.h>
28#include <llvm/IR/Function.h>
29#include <llvm/IR/IRBuilder.h>
30#include <llvm/IR/LLVMContext.h>
31#include <llvm/IR/Module.h>
32
33#include <stack>
34
35namespace openvdb {
37namespace OPENVDB_VERSION_NAME {
38
39namespace ax {
40namespace codegen {
41
42/// @brief The function definition and signature which is built by the
43/// ComputeGenerator.
44///
45/// The argument structure is as follows:
46///
47/// 1) - A void pointer to the CustomData
48///
50{
51 /// The name of the generated function
52 static const std::string Name;
53
54 /// The signature of the generated function
55 using Signature = void(const void* const);
57 static const size_t N_ARGS = FunctionTraitsT::N_ARGS;
58
59 /// The argument key names available during code generation
60 static const std::array<std::string, N_ARGS>& getArgumentKeys();
61 static std::string getDefaultName();
62};
63
64
65///////////////////////////////////////////////////////////////////////////
66///////////////////////////////////////////////////////////////////////////
67
69
70/// @brief Visitor object which will generate llvm IR for a syntax tree. This
71/// provides the majority of the code generation functionality except for
72/// attribute access. This design allows for custom geometry to define their
73/// IR implementations for these accesses by deriving and extending this
74/// generator with ast::Attribute handling (see PointComputeGenerator.h and
75/// VolumeComputeGenerator.h for examples).
76/// @note The visit/traverse methods work slightly differently to the normal
77/// Visitor to allow proper handling of errors and visitation history. Nodes
78/// that inherit from ast::Expression can return false from visit() (and so
79/// traverse()), but this will not necessarily stop traversal altogether.
80/// Instead, any ast::Statements that are not also ast::Expressions i.e.
81/// Block, ConditionalStatement, Loop, DeclareLocal, etc override their visit
82/// and traverse methods to handle custom traversal order, and the catching
83/// of failed child Expression visit/traverse calls. This allows errors in
84/// independent Statements to not halt traversal for future Statements and so
85/// allow capturing of multiple errors in an ast::Tree in a single call to
86/// ComputeGenerator::generate().
87struct OPENVDB_AX_API ComputeGenerator : public ast::Visitor<ComputeGenerator>
88{
89 ComputeGenerator(llvm::Module& module,
90 const FunctionOptions& options,
91 FunctionRegistry& functionRegistry,
92 Logger& logger);
93
95
96 bool generate(const ast::Tree&);
97
98 inline SymbolTable<llvm::Value*>& globals() { return mSymbolTables.globals(); }
99 inline const SymbolTable<llvm::Value*>& globals() const { return mSymbolTables.globals(); }
100
101 // Visitor pattern
102
103 using ast::Visitor<ComputeGenerator>::traverse;
104 using ast::Visitor<ComputeGenerator>::visit;
105
106 /// @brief Code generation always runs post order
107 inline bool postOrderNodes() const { return true; }
108
109 /// @brief Custom traversal of scoped blocks
110 /// @note This overrides the default traversal to incorporate
111 /// the scoping of variables declared in this block
112 bool traverse(const ast::Block* block)
113 {
114 if (!block) return true;
115 if (!this->visit(block)) return false;
116 return true;
117 }
118
119 /// @brief Custom traversal of comma expression
120 /// @note This overrides the default traversal to handle errors
121 /// without stopping generation of entire list
122 /// @todo Replace with a binary operator that simply returns the second value
123 bool traverse(const ast::CommaOperator* comma)
124 {
125 if (!comma) return true;
126 if (!this->visit(comma)) return false;
127 return true;
128 }
129
130
131 /// @brief Custom traversal of conditional statements
132 /// @note This overrides the default traversal to handle
133 /// branching between different code paths
135 {
136 if (!cond) return true;
137 if (!this->visit(cond)) return false;
138 return true;
139 }
140
141 /// @brief Custom traversal of binary operators
142 /// @note This overrides the default traversal to handle
143 /// short-circuiting in logical AND and OR
145 {
146 if (!bin) return true;
147 if (!this->visit(bin)) return false;
148 return true;
149 }
150
151 /// @brief Custom traversal of ternary operators
152 /// @note This overrides the default traversal to handle
153 /// branching between different code paths
155 {
156 if (!tern) return true;
157 if (!this->visit(tern)) return false;
158 return true;
159 }
160
161 /// @brief Custom traversal of loops
162 /// @note This overrides the default traversal to handle
163 /// branching between different code paths and the
164 /// scoping of variables in for-loop initialisation
165 bool traverse(const ast::Loop* loop)
166 {
167 if (!loop) return true;
168 if (!this->visit(loop)) return false;
169 return true;
170 }
171
172 /// @brief Custom traversal of declarations
173 /// @note This overrides the default traversal to
174 /// handle traversal of the local and
175 /// assignment of initialiser, if it exists
176 bool traverse(const ast::DeclareLocal* decl)
177 {
178 if (!decl) return true;
179 if (!this->visit(decl)) return false;
180 return true;
181 }
182
183 ///@{
184 /// @brief Visitor methods for all AST nodes which implement IR generation
185 virtual bool visit(const ast::CommaOperator*);
186 virtual bool visit(const ast::AssignExpression*);
187 virtual bool visit(const ast::Crement*);
188 virtual bool visit(const ast::FunctionCall*);
189 virtual bool visit(const ast::Attribute*);
190 virtual bool visit(const ast::Tree*);
191 virtual bool visit(const ast::Block*);
192 virtual bool visit(const ast::ConditionalStatement*);
193 virtual bool visit(const ast::Loop*);
194 virtual bool visit(const ast::Keyword*);
195 virtual bool visit(const ast::UnaryOperator*);
196 virtual bool visit(const ast::BinaryOperator*);
197 virtual bool visit(const ast::TernaryOperator*);
198 virtual bool visit(const ast::Cast*);
199 virtual bool visit(const ast::DeclareLocal*);
200 virtual bool visit(const ast::Local*);
201 virtual bool visit(const ast::ExternalVariable*);
202 virtual bool visit(const ast::ArrayUnpack*);
203 virtual bool visit(const ast::ArrayPack*);
204 virtual bool visit(const ast::Value<bool>*);
205 virtual bool visit(const ast::Value<int16_t>*);
206 virtual bool visit(const ast::Value<int32_t>*);
207 virtual bool visit(const ast::Value<int64_t>*);
208 virtual bool visit(const ast::Value<float>*);
209 virtual bool visit(const ast::Value<double>*);
210 virtual bool visit(const ast::Value<std::string>*);
211
212 template <typename ValueType>
213 typename std::enable_if<std::is_integral<ValueType>::value, bool>::type
215 template <typename ValueType>
216
217 typename std::enable_if<std::is_floating_point<ValueType>::value, bool>::type
219 ///@}
220
221protected:
222 const FunctionGroup* getFunction(const std::string& identifier,
223 const bool allowInternal = false);
224
225 /// @brief Clear any strings which were allocated in a given function.
226 /// This method accepts an IRBuilder which is expected to be attached to
227 /// a valid block/function. For each block in the function with a return
228 /// instruction, this function calls the appropriate memory methods to
229 /// deallocate any strings (which are alloced in the function prologue).
230 void createFreeSymbolStrings(llvm::IRBuilder<>&);
231
232 llvm::Module& mModule;
233 llvm::LLVMContext& mContext;
234 llvm::IRBuilder<> mBuilder;
235
236 // The stack of accessed values and their underlying types
237 std::stack<Value> mValues;
238
239 // The stack of blocks for keyword branching
240 std::stack<std::pair<llvm::BasicBlock*, llvm::BasicBlock*>> mBreakContinueStack;
241
242 // The current scope number used to track scoped declarations
244
245 // The map of scope number to local variable names to values
247
248 // The function used as the base code block
249 llvm::Function* mFunction;
250
252
254
255private:
256 FunctionRegistry& mFunctionRegistry;
257};
258
259} // codegen_internal
260
261} // namespace codegen
262} // namespace ax
263} // namespace OPENVDB_VERSION_NAME
264} // namespace openvdb
265
266#endif // OPENVDB_AX_COMPUTE_GENERATOR_HAS_BEEN_INCLUDED
267
Provides the definition for every abstract and concrete derived class which represent a particular ab...
OpenVDB AX Compiler Options.
Contains the global function registration definition which described all available user front end fun...
Contains frameworks for creating custom AX functions which can be registered within the FunctionRegis...
Logging system to collect errors and warnings throughout the different stages of parsing and compilat...
#define OPENVDB_AX_API
Definition Platform.h:312
Contains the symbol table which holds mappings of variables names to llvm::Values.
Intermediate representation of supported AX values.
Contains the AX AST Node Visitor, providing default and customizable traversal and visitation methods...
Logger for collecting errors and warnings that occur during AX compilation.
Definition Logger.h:58
The function registry which is used for function code generation. Each time a function is visited wit...
Definition FunctionRegistry.h:40
Definition ComputeGenerator.h:68
Definition Exceptions.h:13
Options that control how functions behave.
Definition CompilerOptions.h:25
ArrayPacks represent temporary container creations of arbitrary sizes, typically generated through th...
Definition AST.h:1786
ArrayUnpack represent indexing operations into AX container types, primarily vectors and matrices ind...
Definition AST.h:1687
AssignExpressions represents a similar object construction to a BinaryOperator. AssignExpressions can...
Definition AST.h:1199
Attributes represent any access to a primitive value, typically associated with the '@' symbol syntax...
Definition AST.h:1875
A BinaryOperator represents a single binary operation between a left hand side (LHS) and right hand s...
Definition AST.h:989
A Block node represents a scoped list of statements. It may comprise of 0 or more statements,...
Definition AST.h:477
Cast nodes represent the conversion of an underlying expression to a target type. Cast nodes are typi...
Definition AST.h:1465
ConditionalStatements represents all combinations of 'if', 'else' and 'else if' syntax and semantics....
Definition AST.h:865
A Crement node represents a single increment '++' and decrement '–' operation. As well as it's cremen...
Definition AST.h:1295
DeclareLocal AST nodes symbolize a single type declaration of a local variable. These store the local...
Definition AST.h:2140
ExternalVariable represent any access to external (custom) data, typically associated with the '$' sy...
Definition AST.h:2003
FunctionCalls represent a single call to a function and any provided arguments. The argument list can...
Definition AST.h:1542
Keywords represent keyword statements defining changes in execution. These include those that define ...
Definition AST.h:1642
Local AST nodes represent a single accesses to a local variable. The only store the name of the varia...
Definition AST.h:2113
Loops represent for, while and do-while loop constructs. These all consist of a condition - evaluated...
Definition AST.h:709
A TernaryOperator represents a ternary (conditional) expression 'a ? b : c' which evaluates to 'b' if...
Definition AST.h:1093
A Tree is the highest concrete (non-abstract) node in the entire AX AST hierarchy....
Definition AST.h:563
A UnaryOperator represents a single unary operation on an expression. The operation type is stored as...
Definition AST.h:1390
A Value (literal) AST node holds either literal text or absolute value information on all numerical,...
Definition AST.h:2254
The Visitor class uses the Curiously Recursive Template Pattern (CRTP) to provide a customizable inte...
Definition Visitor.h:96
The function definition and signature which is built by the ComputeGenerator.
Definition ComputeGenerator.h:50
codegen::FunctionTraits< Signature > FunctionTraitsT
Definition ComputeGenerator.h:56
static const size_t N_ARGS
Definition ComputeGenerator.h:57
void(const void *const) Signature
The signature of the generated function.
Definition ComputeGenerator.h:55
static const std::string Name
The name of the generated function.
Definition ComputeGenerator.h:52
static const std::array< std::string, N_ARGS > & getArgumentKeys()
The argument key names available during code generation.
A group of functions which all have the same name but different signatures. For example: float abs(fl...
Definition FunctionTypes.h:1390
Templated function traits which provides compile-time index access to the types of the function signa...
Definition Types.h:311
A map of unique ids to symbol tables which can be used to represent local variables within a program....
Definition SymbolTable.h:116
A symbol table which can be used to represent a single scoped set of a programs variables....
Definition SymbolTable.h:38
Visitor object which will generate llvm IR for a syntax tree. This provides the majority of the code ...
Definition ComputeGenerator.h:88
virtual bool visit(const ast::ExternalVariable *)
Visitor methods for all AST nodes which implement IR generation.
SymbolTableBlocks mSymbolTables
Definition ComputeGenerator.h:246
virtual bool visit(const ast::Value< std::string > *)
Visitor methods for all AST nodes which implement IR generation.
std::stack< std::pair< llvm::BasicBlock *, llvm::BasicBlock * > > mBreakContinueStack
Definition ComputeGenerator.h:240
ComputeGenerator(llvm::Module &module, const FunctionOptions &options, FunctionRegistry &functionRegistry, Logger &logger)
virtual bool visit(const ast::Tree *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::Keyword *)
Visitor methods for all AST nodes which implement IR generation.
bool traverse(const ast::BinaryOperator *bin)
Custom traversal of binary operators.
Definition ComputeGenerator.h:144
void createFreeSymbolStrings(llvm::IRBuilder<> &)
Clear any strings which were allocated in a given function. This method accepts an IRBuilder which is...
SymbolTable< llvm::Value * > & globals()
Definition ComputeGenerator.h:98
std::stack< Value > mValues
Definition ComputeGenerator.h:237
virtual bool visit(const ast::Crement *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::Cast *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::BinaryOperator *)
Visitor methods for all AST nodes which implement IR generation.
llvm::Module & mModule
Definition ComputeGenerator.h:232
virtual bool visit(const ast::Local *)
Visitor methods for all AST nodes which implement IR generation.
bool traverse(const ast::Loop *loop)
Custom traversal of loops.
Definition ComputeGenerator.h:165
const FunctionOptions mOptions
Definition ComputeGenerator.h:251
virtual bool visit(const ast::TernaryOperator *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::Value< int16_t > *)
Visitor methods for all AST nodes which implement IR generation.
bool traverse(const ast::CommaOperator *comma)
Custom traversal of comma expression.
Definition ComputeGenerator.h:123
llvm::Function * mFunction
Definition ComputeGenerator.h:249
virtual bool visit(const ast::AssignExpression *)
Visitor methods for all AST nodes which implement IR generation.
bool traverse(const ast::ConditionalStatement *cond)
Custom traversal of conditional statements.
Definition ComputeGenerator.h:134
virtual bool visit(const ast::Loop *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::Attribute *)
Visitor methods for all AST nodes which implement IR generation.
llvm::IRBuilder mBuilder
Definition ComputeGenerator.h:234
bool postOrderNodes() const
Code generation always runs post order.
Definition ComputeGenerator.h:107
virtual bool visit(const ast::ConditionalStatement *)
Visitor methods for all AST nodes which implement IR generation.
bool traverse(const ast::DeclareLocal *decl)
Custom traversal of declarations.
Definition ComputeGenerator.h:176
virtual bool visit(const ast::Value< bool > *)
Visitor methods for all AST nodes which implement IR generation.
const FunctionGroup * getFunction(const std::string &identifier, const bool allowInternal=false)
llvm::LLVMContext & mContext
Definition ComputeGenerator.h:233
virtual bool visit(const ast::Block *)
Visitor methods for all AST nodes which implement IR generation.
bool traverse(const ast::TernaryOperator *tern)
Custom traversal of ternary operators.
Definition ComputeGenerator.h:154
virtual bool visit(const ast::FunctionCall *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::DeclareLocal *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::UnaryOperator *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::ArrayPack *)
Visitor methods for all AST nodes which implement IR generation.
Logger & mLog
Definition ComputeGenerator.h:253
virtual bool visit(const ast::Value< int32_t > *)
Visitor methods for all AST nodes which implement IR generation.
bool traverse(const ast::Block *block)
Custom traversal of scoped blocks.
Definition ComputeGenerator.h:112
std::enable_if< std::is_integral< ValueType >::value, bool >::type visit(const ast::Value< ValueType > *node)
Visitor methods for all AST nodes which implement IR generation.
std::enable_if< std::is_floating_point< ValueType >::value, bool >::type visit(const ast::Value< ValueType > *node)
Visitor methods for all AST nodes which implement IR generation.
size_t mScopeIndex
Definition ComputeGenerator.h:243
virtual bool visit(const ast::Value< int64_t > *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::ArrayUnpack *)
Visitor methods for all AST nodes which implement IR generation.
const SymbolTable< llvm::Value * > & globals() const
Definition ComputeGenerator.h:99
virtual bool visit(const ast::Value< float > *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::CommaOperator *)
Visitor methods for all AST nodes which implement IR generation.
virtual bool visit(const ast::Value< double > *)
Visitor methods for all AST nodes which implement IR generation.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218