GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/codegen/VolumeComputeGenerator.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 198 212 93.4%
Functions: 12 15 80.0%
Branches: 181 384 47.1%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 /// @file codegen/VolumeComputeGenerator.cc
5
6 #include "VolumeComputeGenerator.h"
7 #include "FunctionRegistry.h"
8 #include "FunctionTypes.h"
9 #include "Types.h"
10 #include "Utils.h"
11
12 #include "../Exceptions.h"
13 #include "../ast/Scanners.h"
14
15 namespace openvdb {
16 OPENVDB_USE_VERSION_NAMESPACE
17 namespace OPENVDB_VERSION_NAME {
18
19 namespace ax {
20 namespace codegen {
21
22 const std::array<std::string, VolumeKernelValue::N_ARGS>&
23 763 VolumeKernelValue::argumentKeys()
24 {
25 static const std::array<std::string, VolumeKernelValue::N_ARGS> arguments = {{
26 "custom_data",
27 "origin",
28 "value",
29 "active",
30 "offset",
31 "accessors",
32 "transforms",
33 "write_index"
34
11/20
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 762 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
763 }};
35
36 763 return arguments;
37 }
38
39 763 const char* VolumeKernelValue::getDefaultName() { return "ax.compute.voxel.k1"; }
40
41 //
42
43 const std::array<std::string, VolumeKernelBuffer::N_ARGS>&
44 VolumeKernelBuffer::argumentKeys()
45 {
46 static const std::array<std::string, VolumeKernelBuffer::N_ARGS> arguments = {{
47 "custom_data",
48 "origin",
49 "value_buffer",
50 "active_buffer",
51 "buffer_size",
52 "mode",
53 "accessors",
54 "transforms",
55 "write_index"
56 }};
57
58 return arguments;
59 }
60
61 3007 const char* VolumeKernelBuffer::getDefaultName() { return "ax.compute.voxel.k2"; }
62
63 //
64
65 const std::array<std::string, VolumeKernelNode::N_ARGS>&
66 VolumeKernelNode::argumentKeys()
67 {
68 static const std::array<std::string, VolumeKernelNode::N_ARGS> arguments = {{
69 "custom_data",
70 "coord_is",
71 "accessors",
72 "transforms",
73 "write_index",
74 "write_acccessor"
75 }};
76
77 return arguments;
78 }
79
80 3007 const char* VolumeKernelNode::getDefaultName() { return "ax.compute.voxel.k3"; }
81
82
83 ///////////////////////////////////////////////////////////////////////////
84 ///////////////////////////////////////////////////////////////////////////
85
86 namespace codegen_internal {
87
88 751 inline void VolumeComputeGenerator::computek2(llvm::Function* compute, const AttributeRegistry&)
89 {
90 auto generate =
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 [&](const std::vector<llvm::Value*>& args,
92 llvm::IRBuilder<>& B) -> llvm::Value*
93 {
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 assert(args.size() == 9);
95 751 llvm::Value* vbuff = args[2]; //extractArgument(rangeFunction, "value_buffer");
96 751 llvm::Value* abuff = args[3]; //extractArgument(rangeFunction, "active_buffer");
97 751 llvm::Value* buffSize = args[4]; //extractArgument(rangeFunction, "buffer_size");
98 751 llvm::Value* mode = args[5]; //extractArgument(rangeFunction, "mode");
99
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 assert(buffSize);
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 assert(vbuff);
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 assert(abuff);
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 assert(mode);
103
104 llvm::Function* base = B.GetInsertBlock()->getParent();
105 llvm::LLVMContext& C = B.getContext();
106
107 751 llvm::BasicBlock* conditionBlock = llvm::BasicBlock::Create(C, "k2.condition", base);
108 751 llvm::BasicBlock* bodyBlock = llvm::BasicBlock::Create(C, "k2.body", base);
109 751 llvm::BasicBlock* iterBlock = llvm::BasicBlock::Create(C, "k2.iter", base);
110
111 // init var - loops from 0 -> buffSize
112 751 llvm::Value* incr = insertStaticAlloca(B, LLVMType<int64_t>::get(C));
113 751 B.CreateStore(B.getInt64(0), incr);
114 751 B.CreateBr(conditionBlock);
115
116 // increment
117 B.SetInsertPoint(iterBlock);
118 751 llvm::Value* new_incr = B.CreateAdd(B.CreateLoad(incr), B.getInt64(1));
119 751 B.CreateStore(new_incr, incr);
120 751 B.CreateBr(conditionBlock);
121
122 // generate loop body
123 B.SetInsertPoint(bodyBlock);
124 751 llvm::Value* lincr = B.CreateLoad(incr);
125
126 // Extract mask bit from array of words
127 // NodeMask::isOn() = (0 != (mWords[n >> 6] & (Word(1) << (n & 63))));
128
3/6
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 751 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 751 times.
✗ Branch 8 not taken.
751 llvm::Value* mask = binaryOperator(B.getInt64(1),
129 1502 binaryOperator(lincr, B.getInt64(63), ast::tokens::BITAND, B),
130
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 ast::tokens::SHIFTLEFT, B);
131 751 llvm::Value* word_idx = binaryOperator(lincr, B.getInt64(6), ast::tokens::SHIFTRIGHT, B);
132 751 llvm::Value* word = B.CreateGEP(abuff, word_idx);
133 751 word = B.CreateLoad(word);
134 751 word = binaryOperator(word, mask, ast::tokens::BITAND, B);
135 751 llvm::Value* ison = B.CreateICmpNE(word, B.getInt64(0));
136
137 // Check if we should run the kernel depending on the mode.
138 // mode == 0, inactive values
139 // mode == 1, active values
140 // mode == 2, all values
141 751 llvm::Value* matches_mode = B.CreateICmpEQ(B.CreateZExt(ison, mode->getType()), mode);
142 751 llvm::Value* mode_is_all = B.CreateICmpEQ(mode, B.getInt64(2));
143 751 llvm::Value* process = binaryOperator(matches_mode, mode_is_all, ast::tokens::OR, B);
144 751 llvm::BasicBlock* then = llvm::BasicBlock::Create(C, "k2.invoke_k1", base);
145
146 751 B.CreateCondBr(process, then, iterBlock);
147 B.SetInsertPoint(then);
148 {
149 // invoke the volume kernel for this value
150 const std::array<llvm::Value*, 8> input {
151 args[0], // ax::CustomData
152 args[1], // index space coordinate
153 vbuff, // value buffer
154 ison, // active/inactive
155 751 B.CreateLoad(incr), // offset in the value buffer
156 args[6], // read accessors
157 args[7], // transforms
158 args[8] // write index
159 1502 };
160 751 B.CreateCall(compute, input);
161 751 B.CreateBr(iterBlock);
162 }
163
164 B.SetInsertPoint(conditionBlock);
165 751 llvm::Value* endCondition = B.CreateICmpULT(B.CreateLoad(incr), buffSize);
166
167 751 llvm::BasicBlock* postBlock = llvm::BasicBlock::Create(C, "k2.end", base);
168 751 B.CreateCondBr(endCondition, bodyBlock, postBlock);
169 B.SetInsertPoint(postBlock);
170 751 return B.CreateRetVoid();
171 751 };
172
173 // Use the function builder to generate the correct prototype and body for K2
174
1/2
✓ Branch 3 taken 751 times.
✗ Branch 4 not taken.
1502 auto k2 = FunctionBuilder(VolumeKernelBuffer::getDefaultName())
175
2/4
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 751 times.
✗ Branch 6 not taken.
1502 .addSignature<VolumeKernelBuffer::Signature>(generate, VolumeKernelBuffer::getDefaultName())
176 .setConstantFold(false)
177 .setEmbedIR(false)
178
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
179
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(0, llvm::Attribute::NoCapture)
180
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(0, llvm::Attribute::NoAlias)
181
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
182
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(1, llvm::Attribute::NoCapture)
183
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(1, llvm::Attribute::NoAlias)
184
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(2, llvm::Attribute::NoCapture)
185
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(2, llvm::Attribute::NoAlias)
186
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(3, llvm::Attribute::NoCapture)
187
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(3, llvm::Attribute::NoAlias)
188
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(6, llvm::Attribute::NoCapture)
189
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(6, llvm::Attribute::NoAlias)
190
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(7, llvm::Attribute::NoCapture)
191
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(7, llvm::Attribute::NoAlias)
192 751 .addFunctionAttribute(llvm::Attribute::NoRecurse)
193
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
1502 .get();
194
195
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 k2->list()[0]->create(mContext, &mModule);
196 751 }
197
198 751 inline void VolumeComputeGenerator::computek3(llvm::Function* compute, const AttributeRegistry& reg)
199 {
200 751 const SymbolTable& localTable = *(this->mSymbolTables.get(1));
201
202 auto generate =
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 [&, this](const std::vector<llvm::Value*>& args,
204 15511 llvm::IRBuilder<>& B) -> llvm::Value*
205 {
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 assert(args.size() == 6);
207 751 llvm::Value* isc = args[1]; // index space coord
208 751 llvm::Value* wi = args[4]; // write index
209 751 llvm::Value* wa = args[5]; // write_accessor
210
211 llvm::Function* base = B.GetInsertBlock()->getParent();
212 llvm::LLVMContext& C = B.getContext();
213
214
2/2
✓ Branch 0 taken 5060 times.
✓ Branch 1 taken 751 times.
5811 for (const AttributeRegistry::AccessData& access : reg.data()) {
215
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 4920 times.
5060 if (!access.writes()) continue;
216
217 const std::string token = access.tokenname();
218 4920 llvm::Type* type = localTable.get(token)->getType();
219 type = type->getPointerElementType();
220
221
1/2
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
4920 llvm::Value* registeredIndex = this->mModule.getGlobalVariable(token);
222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4920 times.
4920 assert(registeredIndex);
223
1/2
✓ Branch 2 taken 4920 times.
✗ Branch 3 not taken.
4920 registeredIndex = B.CreateLoad(registeredIndex);
224 4920 llvm::Value* result = B.CreateICmpEQ(wi, registeredIndex);
225
226
2/4
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4920 times.
✗ Branch 6 not taken.
4920 llvm::BasicBlock* thenBlock = llvm::BasicBlock::Create(C, "k3.invoke_k1_" + token, base);
227
1/2
✓ Branch 2 taken 4920 times.
✗ Branch 3 not taken.
4920 llvm::BasicBlock* continueBlock = llvm::BasicBlock::Create(C, "k3.next", base);
228
229
1/2
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
4920 B.CreateCondBr(result, thenBlock, continueBlock);
230
1/2
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
4920 B.SetInsertPoint(thenBlock);
231
232
1/2
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
4920 llvm::Value* location = insertStaticAlloca(B, type);
233
1/2
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
4920 llvm::Value* ison = insertStaticAlloca(B, B.getInt1Ty());
234
235
2/4
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4920 times.
✗ Branch 5 not taken.
4920 const FunctionGroup* const F = this->getFunction("probevalue", true);
236
2/4
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4920 times.
✗ Branch 5 not taken.
4920 F->execute({wa, isc, ison, location}, B);
237
1/2
✓ Branch 2 taken 4920 times.
✗ Branch 3 not taken.
4920 ison = B.CreateLoad(ison);
238
239
3/6
✓ Branch 2 taken 4920 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4920 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4920 times.
✗ Branch 9 not taken.
4920 llvm::Value* vptr = B.CreatePointerCast(location, LLVMType<void*>::get(C));
240
241 const std::array<llvm::Value*, 8> input {
242 args[0], // ax::CustomData
243 args[1], // index space coordinate
244 vptr, // value buffer (in this case, a pointer to a single value)
245 ison, // active/inactive
246 4920 B.getInt64(0), // offset in the value buffer, always zero
247 args[2], // read accessors
248 args[3], // transforms
249 wi // write index
250
1/2
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
4920 };
251
3/4
✓ Branch 2 taken 4920 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3234 times.
✓ Branch 5 taken 1686 times.
4920 B.CreateCall(compute, input);
252
253 // set the voxel - load the result (if its a scalar)
254
2/2
✓ Branch 0 taken 3234 times.
✓ Branch 1 taken 1686 times.
4920 if (type->isIntegerTy() || type->isFloatingPointTy()) {
255
1/2
✓ Branch 2 taken 3030 times.
✗ Branch 3 not taken.
3030 location = B.CreateLoad(location);
256 }
257
258
2/4
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4920 times.
✗ Branch 5 not taken.
4920 const FunctionGroup* const function = this->getFunction("setvoxel", true);
259
3/6
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4920 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4920 times.
✗ Branch 8 not taken.
4920 function->execute({wa, isc, /*level=unknown*/B.getInt32(-1), ison, location}, B);
260
261
1/2
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
4920 B.CreateBr(continueBlock);
262 B.SetInsertPoint(continueBlock);
263 }
264
265 751 llvm::Value* ret = B.CreateRetVoid();
266 // insert string frees for k3 which can allocate them
267 751 this->createFreeSymbolStrings(B);
268 751 return ret;
269 751 };
270
271
1/2
✓ Branch 3 taken 751 times.
✗ Branch 4 not taken.
1502 auto k3 = FunctionBuilder(VolumeKernelNode::getDefaultName())
272
3/6
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 751 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 751 times.
✗ Branch 8 not taken.
1502 .addSignature<VolumeKernelNode::Signature>(generate, VolumeKernelNode::getDefaultName())
273 .setConstantFold(false)
274 .setEmbedIR(false)
275
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
276
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(0, llvm::Attribute::NoCapture)
277
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(0, llvm::Attribute::NoAlias)
278
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
279
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(1, llvm::Attribute::NoCapture)
280
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(1, llvm::Attribute::NoAlias)
281
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(2, llvm::Attribute::NoCapture)
282
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(2, llvm::Attribute::NoAlias)
283
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(3, llvm::Attribute::NoCapture)
284
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(3, llvm::Attribute::NoAlias)
285
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(5, llvm::Attribute::NoCapture)
286
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 .addParameterAttribute(5, llvm::Attribute::NoAlias)
287 751 .addFunctionAttribute(llvm::Attribute::NoRecurse)
288
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
1502 .get();
289
290
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 k3->list()[0]->create(mContext, &mModule);
291 751 }
292
293 763 VolumeComputeGenerator::VolumeComputeGenerator(llvm::Module& module,
294 const FunctionOptions& options,
295 FunctionRegistry& functionRegistry,
296 763 Logger& logger)
297 763 : ComputeGenerator(module, options, functionRegistry, logger) {}
298
299 763 AttributeRegistry::Ptr VolumeComputeGenerator::generate(const ast::Tree& tree)
300 {
301 llvm::FunctionType* type =
302 763 llvmFunctionTypeFromSignature<VolumeKernelValue::Signature>(mContext);
303
304
1/2
✓ Branch 2 taken 763 times.
✗ Branch 3 not taken.
763 mFunction = llvm::Function::Create(type,
305 llvm::Function::ExternalLinkage,
306 VolumeKernelValue::getDefaultName(),
307 763 &mModule);
308
309 // Set up arguments for initial entry
310
311 llvm::Function::arg_iterator argIter = mFunction->arg_begin();
312 763 const auto arguments = VolumeKernelValue::argumentKeys();
313 auto keyIter = arguments.cbegin();
314
315
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6867 times.
✓ Branch 2 taken 6104 times.
✓ Branch 3 taken 763 times.
6867 for (; argIter != mFunction->arg_end(); ++argIter, ++keyIter) {
316
1/2
✓ Branch 2 taken 6104 times.
✗ Branch 3 not taken.
6104 argIter->setName(*keyIter);
317 }
318
319
4/6
✓ Branch 2 taken 763 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 763 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 4 times.
799 llvm::BasicBlock* entry = llvm::BasicBlock::Create(mContext, "k1.entry", mFunction);
320 mBuilder.SetInsertPoint(entry);
321
322 // build the attribute registry
323
324
1/2
✓ Branch 1 taken 763 times.
✗ Branch 2 not taken.
763 AttributeRegistry::Ptr registry = AttributeRegistry::create(tree);
325
326 // Visit all attributes and allocate them in local IR memory - assumes attributes
327 // have been verified by the ax compiler
328 // @note Call all attribute allocs at the start of this block so that llvm folds
329 // them into the function prologue (as a static allocation)
330
331 763 SymbolTable* localTable = this->mSymbolTables.getOrInsert(1);
332
333 // run allocations and update the symbol table
334
335
2/2
✓ Branch 0 taken 5062 times.
✓ Branch 1 taken 763 times.
5825 for (const AttributeRegistry::AccessData& data : registry->data()) {
336
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 llvm::Type* type = llvmTypeFromToken(data.type(), mContext);
337 {
338
3/6
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5062 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 5062 times.
✗ Branch 9 not taken.
5062 llvm::Value* vptr = mBuilder.CreateAlloca(type->getPointerTo(0));
339
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
10124 localTable->insert(data.tokenname() + "_vptr", vptr);
340
2/4
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5062 times.
5062 assert(llvm::cast<llvm::AllocaInst>(vptr)->isStaticAlloca());
341 }
342
343 // @warning This method will insert the alloc before the above alloc.
344 // This is fine, but is worth noting
345
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 llvm::Value* value = insertStaticAlloca(mBuilder, type);
346
2/4
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5062 times.
5062 assert(llvm::cast<llvm::AllocaInst>(value)->isStaticAlloca());
347
348 // @note this technically doesn't need to live in the local table
349 // (only the pointer to this value (_vptr) needs to) but it's
350 // re-accessed by the subsequent loop. could remove this.
351
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
10128 localTable->insert(data.tokenname(), value);
352 }
353
354 // insert getters for read variables
355
356
2/2
✓ Branch 0 taken 5062 times.
✓ Branch 1 taken 763 times.
5825 for (const AttributeRegistry::AccessData& data : registry->data()) {
357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5062 times.
5062 if (!data.reads()) continue;
358 const std::string token = data.tokenname();
359
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 this->getAccessorValue(token, localTable->get(token));
360 }
361
362 // full code generation
363 // errors can stop traversal, but dont always, so check the log
364
365
2/2
✓ Branch 1 taken 759 times.
✓ Branch 2 taken 4 times.
763 const size_t err = mLog.errors();
366
3/4
✓ Branch 0 taken 759 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 751 times.
759 if (!this->traverse(&tree) || (mLog.errors() > err)) return nullptr;
367
368 // insert free calls for any strings
369
370
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 this->createFreeSymbolStrings(mBuilder);
371
372
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 this->computek2(mFunction, *registry);
373
1/2
✓ Branch 1 taken 751 times.
✗ Branch 2 not taken.
751 this->computek3(mFunction, *registry);
374
375 return registry;
376 }
377
378 6009 bool VolumeComputeGenerator::visit(const ast::Attribute* node)
379 {
380 6009 SymbolTable* localTable = this->mSymbolTables.getOrInsert(1);
381 const std::string globalName = node->tokenname();
382 llvm::Value* value;
383
1/2
✓ Branch 1 taken 6009 times.
✗ Branch 2 not taken.
6009 value = localTable->get(globalName + "_vptr");
384
1/2
✓ Branch 2 taken 6009 times.
✗ Branch 3 not taken.
6009 value = mBuilder.CreateLoad(value);
385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6009 times.
6009 assert(value);
386 mValues.push(value);
387 6009 return true;
388 }
389
390
391 ///////////////////////////////////////////////////////////////////////////
392 ///////////////////////////////////////////////////////////////////////////
393
394
395
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 void VolumeComputeGenerator::getAccessorValue(const std::string& globalName, llvm::Value* location)
396 {
397 std::string name, type;
398
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 ast::Attribute::nametypeFromToken(globalName, &name, &type);
399
400 llvm::Value* registeredIndex = llvm::cast<llvm::GlobalVariable>
401
3/6
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 5062 times.
✗ Branch 9 not taken.
5062 (mModule.getOrInsertGlobal(globalName, LLVMType<int64_t>::get(mContext)));
402
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 this->globals().insert(globalName, registeredIndex);
403
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 registeredIndex = mBuilder.CreateLoad(registeredIndex);
404
405 // first see if pre cached node exists.
406
407
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
5062 llvm::Value* accessIndex = extractArgument(mFunction, "write_index");
408 5062 llvm::Value* result = mBuilder.CreateICmpEQ(accessIndex, registeredIndex);
409
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 result = boolComparison(result, mBuilder);
410
411
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 llvm::BasicBlock* then = llvm::BasicBlock::Create(mContext, "then", mFunction);
412
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 llvm::BasicBlock* els = llvm::BasicBlock::Create(mContext, "else", mFunction);
413
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 llvm::BasicBlock* post = llvm::BasicBlock::Create(mContext, "post", mFunction);
414
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 mBuilder.CreateCondBr(result, then, els);
415
416 mBuilder.SetInsertPoint(then);
417 {
418
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
5062 llvm::Value* valueptr = extractArgument(mFunction, "value");
419
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
5062 llvm::Value* offset = extractArgument(mFunction, "offset");
420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5062 times.
5062 assert(valueptr);
421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5062 times.
5062 assert(offset);
422
423 llvm::Type* type = location->getType(); // ValueType*
424
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 valueptr = mBuilder.CreatePointerCast(valueptr, type);
425 10124 llvm::Value* value = mBuilder.CreateGEP(valueptr, offset);
426
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5062 times.
✗ Branch 6 not taken.
5062 mBuilder.CreateStore(value, this->mSymbolTables.get(1)->get(globalName + "_vptr"));
427
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 mBuilder.CreateBr(post);
428 }
429
430 mBuilder.SetInsertPoint(els);
431 {
432 // If no node, index into the void* array of handles and load the value
433 // through an accessor
434
435
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
5062 llvm::Value* accessorPtr = extractArgument(mFunction, "accessors");
436
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
5062 llvm::Value* transformPtr = extractArgument(mFunction, "transforms");
437
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
5062 llvm::Value* origin = extractArgument(mFunction, "origin");
438
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
5062 llvm::Value* offset = extractArgument(mFunction, "offset");
439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5062 times.
5062 assert(accessorPtr);
440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5062 times.
5062 assert(transformPtr);
441
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5062 times.
5062 assert(origin);
442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5062 times.
5062 assert(offset);
443
444 5062 accessorPtr = mBuilder.CreateGEP(accessorPtr, registeredIndex);
445 5062 llvm::Value* targetTransform = mBuilder.CreateGEP(transformPtr, registeredIndex);
446 5062 llvm::Value* sourceTransform = mBuilder.CreateGEP(transformPtr, accessIndex);
447
448
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 llvm::Value* accessor = mBuilder.CreateLoad(accessorPtr);
449
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 targetTransform = mBuilder.CreateLoad(targetTransform);
450
1/2
✓ Branch 2 taken 5062 times.
✗ Branch 3 not taken.
5062 sourceTransform = mBuilder.CreateLoad(sourceTransform);
451
452
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
5062 const FunctionGroup* const F = this->getFunction("getvoxel", true);
453
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5062 times.
✗ Branch 5 not taken.
10124 F->execute({accessor, sourceTransform, targetTransform, origin, offset, location}, mBuilder);
454
2/4
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5062 times.
✗ Branch 6 not taken.
5062 mBuilder.CreateStore(location, this->mSymbolTables.get(1)->get(globalName + "_vptr"));
455
1/2
✓ Branch 1 taken 5062 times.
✗ Branch 2 not taken.
5062 mBuilder.CreateBr(post);
456 }
457
458 mBuilder.SetInsertPoint(post);
459 5062 }
460
461 llvm::Value* VolumeComputeGenerator::accessorHandleFromToken(const std::string& globalName)
462 {
463 // Visiting an "attribute" - get the volume accessor out of a vector of void pointers
464 // mAttributeHandles is a void pointer to a vector of void pointers (void**)
465
466 llvm::Value* registeredIndex = llvm::cast<llvm::GlobalVariable>
467 (mModule.getOrInsertGlobal(globalName, LLVMType<int64_t>::get(mContext)));
468 this->globals().insert(globalName, registeredIndex);
469
470 registeredIndex = mBuilder.CreateLoad(registeredIndex);
471
472 // index into the void* array of handles and load the value.
473 // The result is a loaded void* value
474
475 llvm::Value* accessorPtr = extractArgument(mFunction, "accessors");
476 assert(accessorPtr);
477 accessorPtr = mBuilder.CreateGEP(accessorPtr, registeredIndex);
478
479 // return loaded void** = void*
480 return mBuilder.CreateLoad(accessorPtr);
481 }
482
483 ///////////////////////////////////////////////////////////////////////////
484 ///////////////////////////////////////////////////////////////////////////
485
486 } // namespace codegen_internal
487
488 } // namespace codegen
489 } // namespace ax
490 } // namespace OPENVDB_VERSION_NAME
491 } // namespace openvdb
492
493