| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright Contributors to the OpenVDB Project | ||
| 2 | // SPDX-License-Identifier: MPL-2.0 | ||
| 3 | |||
| 4 | /// @file codegen/StandardFunctions.cc | ||
| 5 | /// | ||
| 6 | /// @authors Nick Avramoussis, Richard Jones, Francisco Gochez | ||
| 7 | /// | ||
| 8 | /// @brief Definitions for all standard functions supported by AX. A | ||
| 9 | /// standard function is one that is supported no matter the input | ||
| 10 | /// primitive type and rely either solely on AX types or core AX | ||
| 11 | /// intrinsics. | ||
| 12 | |||
| 13 | #include "Functions.h" | ||
| 14 | #include "FunctionTypes.h" | ||
| 15 | #include "Types.h" | ||
| 16 | #include "Utils.h" | ||
| 17 | |||
| 18 | #include "../Exceptions.h" | ||
| 19 | #include "../math/OpenSimplexNoise.h" | ||
| 20 | #include "../compiler/CompilerOptions.h" | ||
| 21 | #include "../compiler/CustomData.h" | ||
| 22 | |||
| 23 | #include <tbb/enumerable_thread_specific.h> | ||
| 24 | |||
| 25 | #include <llvm/IR/Intrinsics.h> | ||
| 26 | #include <llvm/IR/Instructions.h> | ||
| 27 | |||
| 28 | #include <unordered_map> | ||
| 29 | #include <functional> | ||
| 30 | #include <random> | ||
| 31 | #include <cmath> | ||
| 32 | #include <cstdlib> | ||
| 33 | #include <numeric> // std::iota | ||
| 34 | #include <stddef.h> | ||
| 35 | #include <stdint.h> | ||
| 36 | |||
| 37 | namespace openvdb { | ||
| 38 | OPENVDB_USE_VERSION_NAMESPACE | ||
| 39 | namespace OPENVDB_VERSION_NAME { | ||
| 40 | |||
| 41 | namespace ax { | ||
| 42 | namespace codegen { | ||
| 43 | |||
| 44 | namespace | ||
| 45 | { | ||
| 46 | |||
| 47 | // Reduce a size_t hash down into an unsigned int, taking all bits in the | ||
| 48 | // size_t into account. We achieve this by repeatedly XORing as many bytes | ||
| 49 | // that fit into an unsigned int, and then shift those bytes out of the | ||
| 50 | // hash. We repeat until we have no bits left in the hash. | ||
| 51 | template <typename SeedType> | ||
| 52 | inline SeedType hashToSeed(size_t hash) { | ||
| 53 | SeedType seed = 0; | ||
| 54 | 378 | do { | |
| 55 |
2/2✓ Branch 0 taken 189 times.
✓ Branch 1 taken 189 times.
|
378 | seed ^= (SeedType) hash; |
| 56 | } while (hash >>= sizeof(SeedType) * 8); | ||
| 57 | return seed; | ||
| 58 | } | ||
| 59 | |||
| 60 | struct SimplexNoise | ||
| 61 | { | ||
| 62 | // Open simplex noise - Visually axis-decorrelated coherent noise algorithm | ||
| 63 | // based on the simplectic honeycomb. | ||
| 64 | // See https://gist.github.com/KdotJPG/b1270127455a94ac5d19 | ||
| 65 | 1188 | inline static double noise(double x, double y, double z) | |
| 66 | { | ||
| 67 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1187 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1188 | static const OSN::OSNoise noiseGenerator = OSN::OSNoise(); |
| 68 | 1188 | const double result = noiseGenerator.eval<double>(x, y, z); | |
| 69 | // adjust result so that it lies between 0 and 1, since | ||
| 70 | // Noise::eval returns a number between -1 and 1 | ||
| 71 | 1188 | return (result + 1.0) * 0.5; | |
| 72 | } | ||
| 73 | }; | ||
| 74 | |||
| 75 | } | ||
| 76 | |||
| 77 | /////////////////////////////////////////////////////////////////////////// | ||
| 78 | /////////////////////////////////////////////////////////////////////////// | ||
| 79 | |||
| 80 | #define DEFINE_LLVM_FP_INTRINSIC(Identifier, Doc, UseIR) \ | ||
| 81 | inline FunctionGroup::UniquePtr llvm_##Identifier(const FunctionOptions& op) \ | ||
| 82 | { \ | ||
| 83 | static auto generate = \ | ||
| 84 | [](const std::vector<llvm::Value*>& args, \ | ||
| 85 | llvm::IRBuilder<>& B) -> llvm::Value* \ | ||
| 86 | { \ | ||
| 87 | llvm::Module* M = B.GetInsertBlock()->getParent()->getParent(); \ | ||
| 88 | llvm::Function* function = \ | ||
| 89 | llvm::Intrinsic::getDeclaration(M, \ | ||
| 90 | llvm::Intrinsic::Identifier, args[0]->getType()); \ | ||
| 91 | assert(function); \ | ||
| 92 | return B.CreateCall(function, args); \ | ||
| 93 | }; \ | ||
| 94 | \ | ||
| 95 | return FunctionBuilder(#Identifier) \ | ||
| 96 | .addSignature<double(double)>(generate, (double(*)(double))(std::Identifier)) \ | ||
| 97 | .addSignature<float(float)>(generate, (float(*)(float))(std::Identifier)) \ | ||
| 98 | .setArgumentNames({"n"}) \ | ||
| 99 | .addFunctionAttribute(llvm::Attribute::ReadOnly) \ | ||
| 100 | .addFunctionAttribute(llvm::Attribute::NoRecurse) \ | ||
| 101 | .addFunctionAttribute(llvm::Attribute::NoUnwind) \ | ||
| 102 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) \ | ||
| 103 | .setConstantFold(op.mConstantFoldCBindings) \ | ||
| 104 | .setPreferredImpl((UseIR && op.mPrioritiseIR) ? \ | ||
| 105 | FunctionBuilder::IR : FunctionBuilder::C) \ | ||
| 106 | .setDocumentation(Doc) \ | ||
| 107 | .get(); \ | ||
| 108 | } \ | ||
| 109 | |||
| 110 | #define DEFINE_AX_C_FP_BINDING(Identifier, Doc) \ | ||
| 111 | inline FunctionGroup::UniquePtr ax##Identifier(const FunctionOptions& op) \ | ||
| 112 | { \ | ||
| 113 | return FunctionBuilder(#Identifier) \ | ||
| 114 | .addSignature<double(double)>((double(*)(double))(std::Identifier)) \ | ||
| 115 | .addSignature<float(float)>((float(*)(float))(std::Identifier)) \ | ||
| 116 | .setArgumentNames({"arg"}) \ | ||
| 117 | .addFunctionAttribute(llvm::Attribute::ReadOnly) \ | ||
| 118 | .addFunctionAttribute(llvm::Attribute::NoRecurse) \ | ||
| 119 | .addFunctionAttribute(llvm::Attribute::NoUnwind) \ | ||
| 120 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) \ | ||
| 121 | .setConstantFold(op.mConstantFoldCBindings) \ | ||
| 122 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) \ | ||
| 123 | .setDocumentation(Doc) \ | ||
| 124 | .get(); \ | ||
| 125 | } | ||
| 126 | |||
| 127 | /////////////////////////////////////////////////////////////////////////// | ||
| 128 | /////////////////////////////////////////////////////////////////////////// | ||
| 129 | |||
| 130 | // Memory | ||
| 131 | |||
| 132 | 1 | inline FunctionGroup::UniquePtr axmalloc(const FunctionOptions& op) | |
| 133 | { | ||
| 134 | static auto generate = | ||
| 135 | ✗ | [](const std::vector<llvm::Value*>& args, | |
| 136 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 137 | { | ||
| 138 | llvm::BasicBlock* BB = B.GetInsertBlock(); | ||
| 139 | /// @note The return type is i8* as the void* type is aliased to | ||
| 140 | /// i8* in Types.h. | ||
| 141 | /// @todo should probably remove this alias and use i8* explicitly | ||
| 142 | llvm::Instruction* inst = | ||
| 143 | ✗ | llvm::CallInst::CreateMalloc(BB, // location | |
| 144 | B.getInt64Ty(), // int ptr type | ||
| 145 | B.getInt8Ty(), // return type | ||
| 146 | args[0], // size | ||
| 147 | nullptr, | ||
| 148 | nullptr); | ||
| 149 | ✗ | assert(inst); | |
| 150 | ✗ | B.Insert(inst); | |
| 151 | ✗ | return inst; | |
| 152 | }; | ||
| 153 | |||
| 154 | 1 | return FunctionBuilder("axmalloc") | |
| 155 | 2 | .addSignature<void*(size_t)>(generate, std::malloc, "malloc") // symbol is malloc, not ax.malloc | |
| 156 |
3/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
2 | .setArgumentNames({"size"}) |
| 157 | .setEmbedIR(true) // Embed the call to CreateMalloc, otherwise we gen a function "malloc" which calls "malloc"! | ||
| 158 | .setConstantFold(false) | ||
| 159 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 160 | .setDocumentation("Allocate memory.") | ||
| 161 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | .get(); |
| 162 | } | ||
| 163 | |||
| 164 | 1 | inline FunctionGroup::UniquePtr axfree(const FunctionOptions& op) | |
| 165 | { | ||
| 166 | static auto generate = | ||
| 167 | ✗ | [](const std::vector<llvm::Value*>& args, | |
| 168 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 169 | { | ||
| 170 | llvm::BasicBlock* BB = B.GetInsertBlock(); | ||
| 171 | ✗ | llvm::Instruction* inst = llvm::CallInst::CreateFree(args[0], BB); | |
| 172 | ✗ | assert(inst); | |
| 173 | ✗ | B.Insert(inst); | |
| 174 | ✗ | return nullptr; | |
| 175 | }; | ||
| 176 | |||
| 177 | 1 | return FunctionBuilder("axfree") | |
| 178 | 2 | .addSignature<void(void*)>(generate, std::free, "free") // symbol is free, not ax.free | |
| 179 |
3/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
2 | .setArgumentNames({"ptr"}) |
| 180 | .setEmbedIR(true) // Embed the call to CreateFree, otherwise we gen a function "free" which calls "free"! | ||
| 181 | .setConstantFold(false) | ||
| 182 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 183 | .setDocumentation("Free memory.") | ||
| 184 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | .get(); |
| 185 | } | ||
| 186 | |||
| 187 | 1 | inline FunctionGroup::UniquePtr axrealloc(const FunctionOptions&) | |
| 188 | { | ||
| 189 | 1 | return FunctionBuilder("axrealloc") | |
| 190 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | .addSignature<void*(void*,size_t)>(std::realloc, "realloc") |
| 191 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | .setArgumentNames({"ptr", "size"}) |
| 192 | .setConstantFold(false) | ||
| 193 | .setPreferredImpl(FunctionBuilder::C) | ||
| 194 | .setDocumentation("Reallocate memory.") | ||
| 195 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | .get(); |
| 196 | } | ||
| 197 | |||
| 198 | // Intrinsics | ||
| 199 | |||
| 200 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
✓ Branch 4 taken 125 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 125 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 125 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 125 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 125 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 32 times.
✓ Branch 19 taken 93 times.
✓ Branch 21 taken 125 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 125 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 125 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
1894 | DEFINE_LLVM_FP_INTRINSIC(sqrt, "Computes the square root of arg.", true) |
| 201 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(sin, "Computes the sine of arg (measured in radians).", true) |
| 202 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(cos, "Computes the cosine of arg (measured in radians).", true) |
| 203 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(log, "Computes the natural (base e) logarithm of arg.", true) |
| 204 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(log10, "Computes the common (base-10) logarithm of arg.", true) |
| 205 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(exp, "Computes e (Euler's number, 2.7182818...) raised to the given power arg.", true) |
| 206 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 4 taken 617 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 617 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 617 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 617 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 617 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 32 times.
✓ Branch 19 taken 585 times.
✓ Branch 21 taken 617 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 617 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 617 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
8766 | DEFINE_LLVM_FP_INTRINSIC(fabs, "Computes the absolute value of a floating point value arg.", true) |
| 207 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 49 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 49 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 49 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 49 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 24 times.
✓ Branch 19 taken 25 times.
✓ Branch 21 taken 49 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 49 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 49 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
782 | DEFINE_LLVM_FP_INTRINSIC(floor, "Computes the largest integer value not greater than arg.", true) |
| 208 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(ceil, "Computes the smallest integer value not less than arg.", true) |
| 209 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(round, "Computes the nearest integer value to arg (in floating-point format)," |
| 210 | " rounding halfway cases away from zero.", true) | ||
| 211 | |||
| 212 | // On Windows (or using the Win CRT) log2 and exp2 intrinsics seem to cause a | ||
| 213 | // crash. Still yet to track this down. For now use the C bindings. | ||
| 214 | #ifdef _MSC_VER | ||
| 215 | DEFINE_LLVM_FP_INTRINSIC(log2, "Computes the binary (base-2) logarithm of arg.", false) | ||
| 216 | DEFINE_LLVM_FP_INTRINSIC(exp2, "Computes 2 raised to the given power arg.", false) | ||
| 217 | #else | ||
| 218 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(log2, "Computes the binary (base-2) logarithm of arg.", true) |
| 219 |
11/24✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
|
214 | DEFINE_LLVM_FP_INTRINSIC(exp2, "Computes 2 raised to the given power arg.", true) |
| 220 | #endif | ||
| 221 | |||
| 222 | // pow created explicitly as it takes two arguments and performs slightly different | ||
| 223 | // calls for integer exponents | ||
| 224 | |||
| 225 | 13 | inline FunctionGroup::UniquePtr llvm_pow(const FunctionOptions& op) | |
| 226 | { | ||
| 227 | static auto generate = | ||
| 228 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 229 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 230 | { | ||
| 231 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | llvm::Type* overloadType = args[0]->getType(); |
| 232 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | llvm::Type* expType = args[1]->getType(); |
| 233 | const llvm::Intrinsic::ID id = | ||
| 234 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | expType->isIntegerTy() ? llvm::Intrinsic::powi : llvm::Intrinsic::pow; |
| 235 | llvm::Module* M = B.GetInsertBlock()->getParent()->getParent(); | ||
| 236 | 8 | llvm::Function* function = llvm::Intrinsic::getDeclaration(M, id, overloadType); | |
| 237 | 8 | return B.CreateCall(function, args); | |
| 238 | }; | ||
| 239 | |||
| 240 | 13 | return FunctionBuilder("pow") | |
| 241 | 26 | .addSignature<double(double,double)>(generate, (double(*)(double,double))(std::pow)) | |
| 242 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<float(float,float)>(generate, (float(*)(float,float))(std::pow)) |
| 243 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<double(double,int32_t)>(generate, (double(*)(double,int32_t))(std::pow)) |
| 244 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"base", "exp"}) |
| 245 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 246 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 247 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 248 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) |
| 249 | .setConstantFold(false) // decl's differ | ||
| 250 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 251 | .setDocumentation("Computes the value of the first argument raised to the power of the second argument.") | ||
| 252 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 253 | } | ||
| 254 | |||
| 255 | /////////////////////////////////////////////////////////////////////////// | ||
| 256 | /////////////////////////////////////////////////////////////////////////// | ||
| 257 | |||
| 258 | // Math | ||
| 259 | |||
| 260 |
10/18✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
|
47 | DEFINE_AX_C_FP_BINDING(cbrt, "Computes the cubic root of the input.") |
| 261 | |||
| 262 | 13 | inline FunctionGroup::UniquePtr axabs(const FunctionOptions& op) | |
| 263 | { | ||
| 264 | auto generate = | ||
| 265 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | [op](const std::vector<llvm::Value*>& args, |
| 266 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 267 | { | ||
| 268 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | llvm::Value* value = args.front(); |
| 269 | llvm::Type* type = value->getType(); | ||
| 270 | |||
| 271 | if (type->isFloatingPointTy()) { | ||
| 272 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | return llvm_fabs(op)->execute(args, B); |
| 273 | } | ||
| 274 | |||
| 275 | // if negative flip all the bits and add 1 (xor with -1 and sub 1) | ||
| 276 | llvm::Value* shift = type == LLVMType<int32_t>::get(B.getContext()) ? | ||
| 277 | 4 | LLVMType<int32_t>::get(B.getContext(), 31) : | |
| 278 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | LLVMType<int64_t>::get(B.getContext(), 63); |
| 279 | |||
| 280 | // arithmetic shift right | ||
| 281 | 8 | llvm::Value* mask = B.CreateAShr(value, shift); | |
| 282 | 8 | llvm::Value* xorResult = binaryOperator(value, mask, ast::tokens::BITXOR, B); | |
| 283 | 8 | return binaryOperator(xorResult, mask, ast::tokens::MINUS, B); | |
| 284 | 13 | }; | |
| 285 | |||
| 286 | // @note We also support fabs through the ax abs function | ||
| 287 | 13 | return FunctionBuilder("abs") | |
| 288 | 26 | .addSignature<int64_t(int64_t)>(generate, (int64_t(*)(int64_t))(std::abs)) | |
| 289 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<int32_t(int32_t)>(generate, (int32_t(*)(int32_t))(std::abs)) |
| 290 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<double(double)>(generate, (double(*)(double))(std::abs)) |
| 291 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<float(float)>(generate, (float(*)(float))(std::abs)) |
| 292 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"n"}) |
| 293 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("fabs") |
| 294 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 295 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 296 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 297 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 298 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 299 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 300 | .setDocumentation("Computes the absolute value of an integer number.") | ||
| 301 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 302 | } | ||
| 303 | |||
| 304 | 13 | inline FunctionGroup::UniquePtr axdot(const FunctionOptions& op) | |
| 305 | { | ||
| 306 | static auto generate = | ||
| 307 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 308 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 309 | { | ||
| 310 | std::vector<llvm::Value*> v1, v2; | ||
| 311 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[0], v1, B, /*load*/true); |
| 312 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[1], v2, B, /*load*/true); |
| 313 | |||
| 314 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | v1[0] = binaryOperator(v1[0], v2[0], ast::tokens::MULTIPLY, B); |
| 315 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | v1[1] = binaryOperator(v1[1], v2[1], ast::tokens::MULTIPLY, B); |
| 316 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | v1[2] = binaryOperator(v1[2], v2[2], ast::tokens::MULTIPLY, B); |
| 317 | |||
| 318 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* result = binaryOperator(v1[0], v1[1], ast::tokens::PLUS, B); |
| 319 |
2/6✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
8 | result = binaryOperator(result, v1[2], ast::tokens::PLUS, B); |
| 320 | 8 | return result; | |
| 321 | }; | ||
| 322 | |||
| 323 | static auto dot = [](auto a, auto b) { | ||
| 324 | return a->dot(*b); | ||
| 325 | }; | ||
| 326 | |||
| 327 | using DotD = double(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*); | ||
| 328 | using DotF = float(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*); | ||
| 329 | using DotI = int32_t(openvdb::math::Vec3<int32_t>*,openvdb::math::Vec3<int32_t>*); | ||
| 330 | |||
| 331 | 13 | return FunctionBuilder("dot") | |
| 332 | 26 | .addSignature<DotD>(generate, (DotD*)(dot)) | |
| 333 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DotF>(generate, (DotF*)(dot)) |
| 334 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DotI>(generate, (DotI*)(dot)) |
| 335 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"a", "b"}) |
| 336 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 337 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 338 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 339 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 340 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 341 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 342 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 343 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 344 | .setDocumentation("Computes the dot product of two vectors.") | ||
| 345 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 346 | } | ||
| 347 | |||
| 348 | 13 | inline FunctionGroup::UniquePtr axcross(const FunctionOptions& op) | |
| 349 | { | ||
| 350 | static auto generate = | ||
| 351 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 352 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 353 | { | ||
| 354 | std::vector<llvm::Value*> ptrs, left, right; | ||
| 355 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[0], ptrs, B, /*load*/false); |
| 356 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[1], left, B, /*load*/true); |
| 357 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[2], right, B, /*load*/true); |
| 358 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(ptrs.size() == 3); |
| 359 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(left.size() == 3); |
| 360 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(right.size() == 3); |
| 361 | |||
| 362 |
1/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
8 | std::vector<llvm::Value*> results(3); |
| 363 | |||
| 364 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* tmp1 = binaryOperator(left[1], right[2], ast::tokens::MULTIPLY, B); |
| 365 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* tmp2 = binaryOperator(left[2], right[1], ast::tokens::MULTIPLY, B); |
| 366 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | results[0] = binaryOperator(tmp1, tmp2, ast::tokens::MINUS, B); |
| 367 | |||
| 368 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | tmp1 = binaryOperator(left[2], right[0], ast::tokens::MULTIPLY, B); |
| 369 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | tmp2 = binaryOperator(left[0], right[2], ast::tokens::MULTIPLY, B); |
| 370 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | results[1] = binaryOperator(tmp1, tmp2, ast::tokens::MINUS, B); |
| 371 | |||
| 372 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | tmp1 = binaryOperator(left[0], right[1], ast::tokens::MULTIPLY, B); |
| 373 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | tmp2 = binaryOperator(left[1], right[0], ast::tokens::MULTIPLY, B); |
| 374 |
2/6✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
8 | results[2] = binaryOperator(tmp1, tmp2, ast::tokens::MINUS, B); |
| 375 | |||
| 376 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | B.CreateStore(results[0], ptrs[0]); |
| 377 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | B.CreateStore(results[1], ptrs[1]); |
| 378 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | B.CreateStore(results[2], ptrs[2]); |
| 379 | |||
| 380 | 8 | return nullptr; | |
| 381 | }; | ||
| 382 | |||
| 383 | 136 | static auto cross = [](auto out, auto a, auto b) -> auto { | |
| 384 | 136 | *out = a->cross(*b); | |
| 385 | 136 | }; | |
| 386 | |||
| 387 | using CrossD = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*); | ||
| 388 | using CrossF = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*); | ||
| 389 | using CrossI = void(openvdb::math::Vec3<int32_t>*,openvdb::math::Vec3<int32_t>*,openvdb::math::Vec3<int32_t>*); | ||
| 390 | |||
| 391 | 13 | return FunctionBuilder("cross") | |
| 392 | 26 | .addSignature<CrossD, true>(generate, (CrossD*)(cross)) | |
| 393 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<CrossF, true>(generate, (CrossF*)(cross)) |
| 394 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<CrossI, true>(generate, (CrossI*)(cross)) |
| 395 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"a", "b"}) |
| 396 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 397 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 398 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 399 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(2, llvm::Attribute::ReadOnly) |
| 400 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 401 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 402 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 403 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 404 | .setDocumentation("Returns the length of the given vector") | ||
| 405 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 406 | } | ||
| 407 | |||
| 408 | 113 | inline FunctionGroup::UniquePtr axlengthsq(const FunctionOptions& op) | |
| 409 | { | ||
| 410 | static auto generate = | ||
| 411 |
1/2✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
|
104 | [](const std::vector<llvm::Value*>& args, |
| 412 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 413 | { | ||
| 414 | std::vector<llvm::Value*> elements; | ||
| 415 |
1/2✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
|
104 | arrayUnpack(args[0], elements, B, /*load*/true); |
| 416 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
|
104 | assert(elements.size() >= 2); |
| 417 | |||
| 418 |
1/2✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
|
104 | llvm::Value* v1 = binaryOperator(elements[0], elements[0], ast::tokens::MULTIPLY, B); |
| 419 |
1/2✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
|
104 | llvm::Value* v2 = binaryOperator(elements[1], elements[1], ast::tokens::MULTIPLY, B); |
| 420 |
3/4✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
✓ Branch 4 taken 24 times.
|
104 | llvm::Value* result = binaryOperator(v1, v2, ast::tokens::PLUS, B); |
| 421 | |||
| 422 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 24 times.
|
104 | if (elements.size() > 2) { |
| 423 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | llvm::Value* v3 = binaryOperator(elements[2], elements[2], ast::tokens::MULTIPLY, B); |
| 424 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | result = binaryOperator(result, v3, ast::tokens::PLUS, B); |
| 425 | } | ||
| 426 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 68 times.
|
104 | if (elements.size() > 3) { |
| 427 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | llvm::Value* v4 = binaryOperator(elements[3], elements[3], ast::tokens::MULTIPLY, B); |
| 428 |
1/4✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
36 | result = binaryOperator(result, v4, ast::tokens::PLUS, B); |
| 429 | } | ||
| 430 | |||
| 431 | 104 | return result; | |
| 432 | }; | ||
| 433 | |||
| 434 | static auto lengthsq = [](auto in) -> auto { return in->lengthSqr(); }; | ||
| 435 | |||
| 436 | 113 | return FunctionBuilder("lengthsq") | |
| 437 | 226 | .addSignature<double(openvdb::math::Vec2<double>*)>(generate, lengthsq) | |
| 438 |
1/4✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
226 | .addSignature<float(openvdb::math::Vec2<float>*)>(generate, lengthsq) |
| 439 |
1/4✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
226 | .addSignature<int32_t(openvdb::math::Vec2<int32_t>*)>(generate, lengthsq) |
| 440 |
1/4✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
226 | .addSignature<double(openvdb::math::Vec3<double>*)>(generate, lengthsq) |
| 441 |
1/4✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
226 | .addSignature<float(openvdb::math::Vec3<float>*)>(generate, lengthsq) |
| 442 |
1/4✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
226 | .addSignature<int32_t(openvdb::math::Vec3<int32_t>*)>(generate, lengthsq) |
| 443 |
1/4✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
226 | .addSignature<double(openvdb::math::Vec4<double>*)>(generate, lengthsq) |
| 444 |
1/4✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
226 | .addSignature<float(openvdb::math::Vec4<float>*)>(generate, lengthsq) |
| 445 |
1/4✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
226 | .addSignature<int32_t(openvdb::math::Vec4<int32_t>*)>(generate, lengthsq) |
| 446 |
3/8✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 113 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 113 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
226 | .setArgumentNames({"v"}) |
| 447 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 448 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 449 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 450 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
113 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 451 | 113 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 452 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 89 times.
|
113 | .setConstantFold(op.mConstantFoldCBindings) |
| 453 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 89 times.
|
113 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 454 | .setDocumentation("Returns the squared length of the given vector") | ||
| 455 |
1/2✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
|
226 | .get(); |
| 456 | } | ||
| 457 | |||
| 458 | 61 | inline FunctionGroup::UniquePtr axlength(const FunctionOptions& op) | |
| 459 | { | ||
| 460 | auto generate = | ||
| 461 | 68 | [op](const std::vector<llvm::Value*>& args, | |
| 462 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 463 | { | ||
| 464 | 136 | auto a = axlengthsq(op); | |
| 465 |
1/2✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
|
68 | auto s = llvm_sqrt(op); |
| 466 |
1/2✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
|
68 | llvm::Value* lsq = a->execute(args, B); |
| 467 |
2/4✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 68 times.
✗ Branch 5 not taken.
|
204 | return s->execute({lsq}, B); |
| 468 | 61 | }; | |
| 469 | |||
| 470 | 492 | static auto length = [](auto in) -> auto | |
| 471 | { | ||
| 472 | using VecType = typename std::remove_pointer<decltype(in)>::type; | ||
| 473 | using ElementT = typename openvdb::VecTraits<VecType>::ElementType; | ||
| 474 | using RetT = typename std::conditional | ||
| 475 | <std::is_floating_point<ElementT>::value, ElementT, double>::type; | ||
| 476 | 492 | return std::sqrt(RetT(in->lengthSqr())); | |
| 477 | }; | ||
| 478 | |||
| 479 | 61 | return FunctionBuilder("length") | |
| 480 | 122 | .addSignature<double(openvdb::math::Vec2<double>*)>(generate, length) | |
| 481 |
1/4✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
122 | .addSignature<float(openvdb::math::Vec2<float>*)>(generate, length) |
| 482 |
1/4✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
122 | .addSignature<double(openvdb::math::Vec2<int32_t>*)>(generate, length) |
| 483 |
1/4✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
122 | .addSignature<double(openvdb::math::Vec3<double>*)>(generate, length) |
| 484 |
1/4✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
122 | .addSignature<float(openvdb::math::Vec3<float>*)>(generate, length) |
| 485 |
1/4✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
122 | .addSignature<double(openvdb::math::Vec3<int32_t>*)>(generate, length) |
| 486 |
1/4✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
122 | .addSignature<double(openvdb::math::Vec4<double>*)>(generate, length) |
| 487 |
1/4✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
122 | .addSignature<float(openvdb::math::Vec4<float>*)>(generate, length) |
| 488 |
1/4✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
122 | .addSignature<double(openvdb::math::Vec4<int32_t>*)>(generate, length) |
| 489 |
1/2✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
|
61 | .addDependency("lengthsq") |
| 490 | 61 | .addDependency("sqrt") | |
| 491 |
3/8✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 61 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 61 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
122 | .setArgumentNames({"v"}) |
| 492 |
1/2✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
|
61 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 493 |
1/2✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
|
61 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 494 |
1/2✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
|
61 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 495 |
1/2✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
|
61 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 496 | 61 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 497 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 45 times.
|
61 | .setConstantFold(op.mConstantFoldCBindings) |
| 498 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 45 times.
|
61 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 499 | .setDocumentation("Returns the length of the given vector") | ||
| 500 |
1/2✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
|
122 | .get(); |
| 501 | } | ||
| 502 | |||
| 503 | 17 | inline FunctionGroup::UniquePtr axnormalize(const FunctionOptions& op) | |
| 504 | { | ||
| 505 | auto generate = | ||
| 506 | 28 | [op](const std::vector<llvm::Value*>& args, | |
| 507 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 508 | { | ||
| 509 | 56 | auto a = axlength(op); | |
| 510 |
3/6✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
|
56 | llvm::Value* len = a->execute({args[1]}, B); |
| 511 | |||
| 512 | std::vector<llvm::Value*> ptrs, elements; | ||
| 513 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | arrayUnpack(args[0], ptrs, B, /*load*/false); |
| 514 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | arrayUnpack(args[1], elements, B, /*load*/true); |
| 515 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
28 | assert(ptrs.size() == 3 || ptrs.size() == 4); |
| 516 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
28 | assert(elements.size() == 3 || elements.size() == 4); |
| 517 | |||
| 518 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 20 times.
|
28 | if (elements[0]->getType()->isIntegerTy()) { |
| 519 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arithmeticConversion(elements, LLVMType<double>::get(B.getContext()), B); |
| 520 | } | ||
| 521 | |||
| 522 | // the following is always done at fp precision | ||
| 523 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | llvm::Value* one = llvm::ConstantFP::get(len->getType(), 1.0); |
| 524 |
1/2✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
|
28 | llvm::Value* oneDividedByLength = B.CreateFDiv(one, len); |
| 525 | |||
| 526 |
1/2✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
|
28 | elements[0] = B.CreateFMul(elements[0], oneDividedByLength); |
| 527 |
1/2✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
|
28 | elements[1] = B.CreateFMul(elements[1], oneDividedByLength); |
| 528 |
3/4✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 16 times.
|
28 | elements[2] = B.CreateFMul(elements[2], oneDividedByLength); |
| 529 |
3/6✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
28 | if (elements.size() == 4) elements[3] = B.CreateFMul(elements[3], oneDividedByLength); |
| 530 | |||
| 531 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | B.CreateStore(elements[0], ptrs[0]); |
| 532 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | B.CreateStore(elements[1], ptrs[1]); |
| 533 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | B.CreateStore(elements[2], ptrs[2]); |
| 534 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
28 | if (elements.size() == 4) B.CreateStore(elements[3], ptrs[3]); |
| 535 | |||
| 536 | 28 | return nullptr; | |
| 537 | 17 | }; | |
| 538 | |||
| 539 | static auto norm = [](auto out, auto in) { | ||
| 540 | using VecType = typename std::remove_pointer<decltype(out)>::type; | ||
| 541 | using ElementT = typename openvdb::VecTraits<VecType>::ElementType; | ||
| 542 | *out = *in; // copy | ||
| 543 | out->normalize(ElementT(0.0)); | ||
| 544 | }; | ||
| 545 | |||
| 546 | using Normalize3D = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*); | ||
| 547 | using Normalize3F = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*); | ||
| 548 | using Normalize3I = void(openvdb::math::Vec3<double>*, openvdb::math::Vec3<int32_t>*); | ||
| 549 | using Normalize4D = void(openvdb::math::Vec4<double>*,openvdb::math::Vec4<double>*); | ||
| 550 | using Normalize4F = void(openvdb::math::Vec4<float>*,openvdb::math::Vec4<float>*); | ||
| 551 | using Normalize4I = void(openvdb::math::Vec4<double>*, openvdb::math::Vec4<int32_t>*); | ||
| 552 | |||
| 553 | 17 | return FunctionBuilder("normalize") | |
| 554 | 34 | .addSignature<Normalize3D, true>(generate, (Normalize3D*)(norm)) | |
| 555 |
1/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
34 | .addSignature<Normalize3F, true>(generate, (Normalize3F*)(norm)) |
| 556 |
1/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
34 | .addSignature<Normalize3I, true>(generate, (Normalize3I*)(norm)) |
| 557 |
1/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
34 | .addSignature<Normalize4D, true>(generate, (Normalize4D*)(norm)) |
| 558 |
1/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
34 | .addSignature<Normalize4F, true>(generate, (Normalize4F*)(norm)) |
| 559 |
1/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
34 | .addSignature<Normalize4I, true>(generate, (Normalize4I*)(norm)) |
| 560 | 17 | .addDependency("length") | |
| 561 |
3/8✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
34 | .setArgumentNames({"v"}) |
| 562 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 563 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 564 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 565 | 17 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 566 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 9 times.
|
17 | .setConstantFold(op.mConstantFoldCBindings) |
| 567 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 9 times.
|
17 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 568 | .setDocumentation("Returns the normalized result of the given vector.") | ||
| 569 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
34 | .get(); |
| 570 | } | ||
| 571 | |||
| 572 | 13 | inline FunctionGroup::UniquePtr axlerp(const FunctionOptions& op) | |
| 573 | { | ||
| 574 | static auto generate = | ||
| 575 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 576 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 577 | { | ||
| 578 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(args.size() == 3); |
| 579 | 8 | llvm::Value* a = args[0], *b = args[1], *t = args[2]; | |
| 580 | 8 | llvm::Value* zero = llvm::ConstantFP::get(a->getType(), 0.0); | |
| 581 | 8 | llvm::Value* one = llvm::ConstantFP::get(a->getType(), 1.0); | |
| 582 | llvm::Function* base = B.GetInsertBlock()->getParent(); | ||
| 583 | |||
| 584 | // @todo short-circuit? | ||
| 585 | 8 | llvm::Value* a1 = binaryOperator(a, zero, ast::tokens::LESSTHANOREQUAL, B); | |
| 586 | 8 | llvm::Value* b1 = binaryOperator(b, zero, ast::tokens::MORETHANOREQUAL, B); | |
| 587 | 8 | llvm::Value* a2 = binaryOperator(a, zero, ast::tokens::MORETHANOREQUAL, B); | |
| 588 | 8 | llvm::Value* b2 = binaryOperator(b, zero, ast::tokens::LESSTHANOREQUAL, B); | |
| 589 | 8 | a1 = binaryOperator(a1, b1, ast::tokens::AND, B); | |
| 590 | 8 | a2 = binaryOperator(a2, b2, ast::tokens::AND, B); | |
| 591 | 8 | a1 = binaryOperator(a1, a2, ast::tokens::OR, B); | |
| 592 | |||
| 593 | 8 | llvm::BasicBlock* then = llvm::BasicBlock::Create(B.getContext(), "then", base); | |
| 594 | 8 | llvm::BasicBlock* post = llvm::BasicBlock::Create(B.getContext(), "post", base); | |
| 595 | 8 | B.CreateCondBr(a1, then, post); | |
| 596 | |||
| 597 | B.SetInsertPoint(then); | ||
| 598 | 8 | llvm::Value* r = binaryOperator(one, t, ast::tokens::MINUS, B); | |
| 599 | 8 | r = binaryOperator(r, a, ast::tokens::MULTIPLY, B); | |
| 600 | 8 | llvm::Value* right = binaryOperator(t, b, ast::tokens::MULTIPLY, B); | |
| 601 | 8 | r = binaryOperator(r, right, ast::tokens::PLUS, B); | |
| 602 | 8 | B.CreateRet(r); | |
| 603 | |||
| 604 | B.SetInsertPoint(post); | ||
| 605 | |||
| 606 | 8 | llvm::Value* tisone = binaryOperator(t, one, ast::tokens::EQUALSEQUALS, B); | |
| 607 | |||
| 608 | 8 | then = llvm::BasicBlock::Create(B.getContext(), "then", base); | |
| 609 | 8 | post = llvm::BasicBlock::Create(B.getContext(), "post", base); | |
| 610 | 8 | B.CreateCondBr(tisone, then, post); | |
| 611 | |||
| 612 | B.SetInsertPoint(then); | ||
| 613 | 8 | B.CreateRet(b); | |
| 614 | |||
| 615 | B.SetInsertPoint(post); | ||
| 616 | |||
| 617 | // if nlerp | ||
| 618 | 8 | llvm::Value* x = binaryOperator(b, a, ast::tokens::MINUS, B); | |
| 619 | 8 | x = binaryOperator(t, x, ast::tokens::MULTIPLY, B); | |
| 620 | 8 | x = binaryOperator(a, x, ast::tokens::PLUS, B); | |
| 621 | |||
| 622 | 8 | then = llvm::BasicBlock::Create(B.getContext(), "then", base); | |
| 623 | 8 | post = llvm::BasicBlock::Create(B.getContext(), "post", base); | |
| 624 | |||
| 625 | 8 | a1 = binaryOperator(t, one, ast::tokens::MORETHAN, B); | |
| 626 | 8 | a2 = binaryOperator(b, a, ast::tokens::MORETHAN, B); | |
| 627 | 8 | a1 = binaryOperator(a1, a2, ast::tokens::EQUALSEQUALS, B); | |
| 628 | 8 | B.CreateCondBr(a1, then, post); | |
| 629 | |||
| 630 | B.SetInsertPoint(then); | ||
| 631 | 8 | b1 = binaryOperator(b, x, ast::tokens::LESSTHAN, B); | |
| 632 | 8 | B.CreateRet(B.CreateSelect(b1, x, b)); | |
| 633 | |||
| 634 | B.SetInsertPoint(post); | ||
| 635 | 8 | b1 = binaryOperator(x, b, ast::tokens::LESSTHAN, B); | |
| 636 | 8 | return B.CreateRet(B.CreateSelect(b1, x, b)); | |
| 637 | }; | ||
| 638 | |||
| 639 | // This lerp implementation is taken from clang and matches the C++20 standard | ||
| 640 | 980 | static auto lerp = [](auto a, auto b, auto t) -> auto | |
| 641 | { | ||
| 642 | using ValueT = decltype(a); | ||
| 643 | // If there is a zero crossing with a,b do the more precise | ||
| 644 | // linear interpolation. This is only monotonic if there is | ||
| 645 | // a zero crossing | ||
| 646 | // Exact, monotonic, bounded, determinate, and (for a=b=0) | ||
| 647 | // consistent | ||
| 648 |
7/8✓ Branch 0 taken 196 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 98 times.
✓ Branch 3 taken 98 times.
✓ Branch 4 taken 294 times.
✓ Branch 5 taken 98 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 294 times.
|
980 | if ((a <= 0 && b >= 0) || (a >= 0 && b <= 0)) { |
| 649 | 196 | return t * b + (ValueT(1.0) - t) * a; | |
| 650 | } | ||
| 651 | // If t is exactly 1, return b (as the second impl doesn't | ||
| 652 | // guarantee this due to fp arithmetic) | ||
| 653 |
2/2✓ Branch 0 taken 294 times.
✓ Branch 1 taken 98 times.
|
784 | if (t == ValueT(1.0)) return b; |
| 654 | // less precise interpolation when there is no crossing | ||
| 655 | // Exact at t=0, monotonic except near t=1, bounded, | ||
| 656 | // determinate, and consistent | ||
| 657 | 588 | const auto x = a + t * (b - a); | |
| 658 | // Ensure b is preferred to another equal value (i.e. -0. vs. +0.), | ||
| 659 | // which avoids returning -0 for t==1 but +0 for other nearby | ||
| 660 | // values of t. This branching also stops nans being returns from | ||
| 661 | // inf inputs | ||
| 662 | // monotonic near t=1 | ||
| 663 |
3/4✓ Branch 0 taken 49 times.
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
|
588 | if ((t > ValueT(1.0)) == (b > a)) return b < x ? x : b; |
| 664 |
2/2✓ Branch 0 taken 98 times.
✓ Branch 1 taken 147 times.
|
686 | else return x < b ? x : b; |
| 665 | }; | ||
| 666 | |||
| 667 | 13 | return FunctionBuilder("lerp") | |
| 668 | 26 | .addSignature<double(double,double,double)>(generate, (double(*)(double,double,double))(lerp)) | |
| 669 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<float(float,float,float)>(generate, (float(*)(float,float,float))(lerp)) |
| 670 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"a", "b", "amount"}) |
| 671 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 672 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 673 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 674 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 675 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 676 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 677 | .setDocumentation("Performs bilinear interpolation between the values. If the " | ||
| 678 | "amount is outside the range 0 to 1, the values will be extrapolated linearly. " | ||
| 679 | "If amount is 0, the first value is returned. If it is 1, the second value " | ||
| 680 | "is returned. This implementation is guaranteed to be monotonic.") | ||
| 681 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 682 | } | ||
| 683 | |||
| 684 | 105 | inline FunctionGroup::UniquePtr axmin(const FunctionOptions& op) | |
| 685 | { | ||
| 686 | static auto generate = | ||
| 687 | 36 | [](const std::vector<llvm::Value*>& args, | |
| 688 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 689 | { | ||
| 690 | llvm::Value* result = | ||
| 691 | 36 | binaryOperator(args[0], args[1], ast::tokens::MORETHAN, B); | |
| 692 | 36 | return B.CreateSelect(result, args[1], args[0]); | |
| 693 | }; | ||
| 694 | |||
| 695 | static auto min = [](auto a, auto b) -> auto { | ||
| 696 | return std::min(a, b); | ||
| 697 | }; | ||
| 698 | |||
| 699 | 105 | return FunctionBuilder("min") | |
| 700 | 210 | .addSignature<double(double,double)>(generate, (double(*)(double,double))(min)) | |
| 701 |
1/4✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
210 | .addSignature<float(float,float)>(generate, (float(*)(float,float))(min)) |
| 702 |
1/4✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
210 | .addSignature<int64_t(int64_t,int64_t)>(generate, (int64_t(*)(int64_t,int64_t))(min)) |
| 703 |
1/4✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
210 | .addSignature<int32_t(int32_t,int32_t)>(generate, (int32_t(*)(int32_t,int32_t))(min)) |
| 704 |
3/8✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 105 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 105 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
210 | .setArgumentNames({"a", "b"}) |
| 705 |
1/2✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
|
105 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 706 |
1/2✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
|
105 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 707 |
1/2✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
|
105 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 708 | 105 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 709 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 49 times.
|
105 | .setConstantFold(op.mConstantFoldCBindings) |
| 710 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 49 times.
|
105 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 711 | .setDocumentation("Returns the smaller of the given values.") | ||
| 712 |
1/2✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
|
210 | .get(); |
| 713 | } | ||
| 714 | |||
| 715 | 105 | inline FunctionGroup::UniquePtr axmax(const FunctionOptions& op) | |
| 716 | { | ||
| 717 | static auto generate = | ||
| 718 | 36 | [](const std::vector<llvm::Value*>& args, | |
| 719 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 720 | { | ||
| 721 | llvm::Value* result = | ||
| 722 | 36 | binaryOperator(args[0], args[1], ast::tokens::MORETHAN, B); | |
| 723 | 36 | return B.CreateSelect(result, args[0], args[1]); | |
| 724 | }; | ||
| 725 | |||
| 726 | static auto max = [](auto a, auto b) -> auto { | ||
| 727 | return std::max(a, b); | ||
| 728 | }; | ||
| 729 | |||
| 730 | 105 | return FunctionBuilder("max") | |
| 731 | 210 | .addSignature<double(double,double)>(generate, (double(*)(double,double))(max)) | |
| 732 |
1/4✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
210 | .addSignature<float(float,float)>(generate, (float(*)(float,float))(max)) |
| 733 |
1/4✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
210 | .addSignature<int64_t(int64_t,int64_t)>(generate, (int64_t(*)(int64_t,int64_t))(max)) |
| 734 |
1/4✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
210 | .addSignature<int32_t(int32_t,int32_t)>(generate, (int32_t(*)(int32_t,int32_t))(max)) |
| 735 |
3/8✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 105 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 105 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
210 | .setArgumentNames({"a", "b"}) |
| 736 |
1/2✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
|
105 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 737 |
1/2✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
|
105 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 738 |
1/2✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
|
105 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 739 | 105 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 740 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 49 times.
|
105 | .setConstantFold(op.mConstantFoldCBindings) |
| 741 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 49 times.
|
105 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 742 | .setDocumentation("Returns the larger of the given values.") | ||
| 743 |
1/2✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
|
210 | .get(); |
| 744 | } | ||
| 745 | |||
| 746 | 85 | inline FunctionGroup::UniquePtr axclamp(const FunctionOptions& op) | |
| 747 | { | ||
| 748 | auto generate = | ||
| 749 | 20 | [op](const std::vector<llvm::Value*>& args, | |
| 750 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 751 | { | ||
| 752 |
2/4✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
|
40 | llvm::Value* min = axmax(op)->execute({args[0], args[1]}, B); |
| 753 |
2/4✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
|
40 | llvm::Value* result = axmin(op)->execute({min, args[2]}, B); |
| 754 | 20 | return result; | |
| 755 | 85 | }; | |
| 756 | |||
| 757 | using ClampD = double(double, double, double); | ||
| 758 | using ClampF = float(float, float, float); | ||
| 759 | using ClampI = int32_t(int32_t, int32_t, int32_t); | ||
| 760 | using ClampL = int64_t(int64_t, int64_t, int64_t); | ||
| 761 | |||
| 762 | 85 | return FunctionBuilder("clamp") | |
| 763 | 170 | .addSignature<ClampD>(generate, &openvdb::math::Clamp<double>) | |
| 764 |
1/4✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
170 | .addSignature<ClampF>(generate, &openvdb::math::Clamp<float>) |
| 765 |
1/4✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
170 | .addSignature<ClampL>(generate, &openvdb::math::Clamp<int64_t>) |
| 766 |
1/4✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
170 | .addSignature<ClampI>(generate, &openvdb::math::Clamp<int32_t>) |
| 767 |
1/2✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
|
85 | .addDependency("min") |
| 768 |
1/2✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
|
85 | .addDependency("max") |
| 769 |
1/2✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
|
85 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 770 |
1/2✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
|
85 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 771 |
1/2✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
|
85 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 772 | 85 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 773 |
3/8✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 85 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 85 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
170 | .setArgumentNames({"in", "min", "max"}) |
| 774 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 29 times.
|
85 | .setConstantFold(op.mConstantFoldCBindings) |
| 775 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 29 times.
|
85 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 776 | .setDocumentation("Clamps the first argument to the minimum second argument " | ||
| 777 | "value and maximum third argument value") | ||
| 778 |
1/2✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
|
170 | .get(); |
| 779 | } | ||
| 780 | |||
| 781 | 13 | inline FunctionGroup::UniquePtr axfit(const FunctionOptions& op) | |
| 782 | { | ||
| 783 | auto generate = | ||
| 784 | 36 | [op](const std::vector<llvm::Value*>& args, | |
| 785 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 786 | { | ||
| 787 | // (outMax - outMin)(x - inMin) | ||
| 788 | // f(x) = ---------------------------- + outMin | ||
| 789 | // inMax - inMin | ||
| 790 | // if inMax == inMin, f(x) = (outMax + outMin) / 2.0 | ||
| 791 | |||
| 792 | // NOTE: this also performs a clamp on the ordered input range | ||
| 793 | // @TODO revisit. If this is the best thing to do, should add conditional | ||
| 794 | // branching so that the clamping math is never executed when the value | ||
| 795 | // is inside | ||
| 796 | |||
| 797 | 36 | std::vector<llvm::Value*> argcopy(args); | |
| 798 | |||
| 799 | // select the precision at which to perform | ||
| 800 | |||
| 801 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
|
36 | llvm::Type* precision = argcopy[0]->getType(); |
| 802 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
|
36 | if (precision->isIntegerTy()) { |
| 803 | precision = LLVMType<double>::get(B.getContext()); | ||
| 804 | } | ||
| 805 | |||
| 806 | // See if the input range has a valid magnitude .i.e. the values are not the same | ||
| 807 | |||
| 808 | llvm::Value* isInputRangeValid = | ||
| 809 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | binaryOperator(argcopy[1], argcopy[2], ast::tokens::NOTEQUALS, B); |
| 810 | |||
| 811 | // clamp the input to the ORDERED inMin to inMax range | ||
| 812 | |||
| 813 | llvm::Value* minRangeComp = | ||
| 814 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | binaryOperator(argcopy[1], argcopy[2], ast::tokens::LESSTHAN, B); |
| 815 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | llvm::Value* minInputRange = B.CreateSelect(minRangeComp, argcopy[1], argcopy[2]); |
| 816 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | llvm::Value* maxInputRange = B.CreateSelect(minRangeComp, argcopy[2], argcopy[1]); |
| 817 | |||
| 818 | // clamp | ||
| 819 | { | ||
| 820 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | auto clamp = axclamp(op); |
| 821 |
3/6✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
|
72 | argcopy[0] = clamp->execute({ argcopy[0], minInputRange, maxInputRange }, B); |
| 822 | } | ||
| 823 | |||
| 824 | // cast all (the following requires floating point precision) | ||
| 825 | |||
| 826 |
3/4✓ Branch 0 taken 180 times.
✓ Branch 1 taken 36 times.
✓ Branch 3 taken 180 times.
✗ Branch 4 not taken.
|
216 | for (auto& arg : argcopy) arg = arithmeticConversion(arg, precision, B); |
| 827 | |||
| 828 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | llvm::Value* valueMinusMin = B.CreateFSub(argcopy[0], argcopy[1]); |
| 829 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | llvm::Value* inputRange = B.CreateFSub(argcopy[2], argcopy[1]); |
| 830 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | llvm::Value* outputRange = B.CreateFSub(argcopy[4], argcopy[3]); |
| 831 | |||
| 832 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | llvm::Value* result = B.CreateFMul(outputRange, valueMinusMin); |
| 833 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | result = B.CreateFDiv(result, inputRange); // NOTE - This can cause division by zero |
| 834 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | result = B.CreateFAdd(argcopy[3], result); |
| 835 | |||
| 836 | // calculate the output range over 2 and use this value if the input range is invalid | ||
| 837 | |||
| 838 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | llvm::Value* outputRangeOverTwo = B.CreateFAdd(argcopy[3], argcopy[4]); |
| 839 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | llvm::Value* two = llvm::ConstantFP::get(precision, 2.0); |
| 840 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | outputRangeOverTwo = B.CreateFDiv(outputRangeOverTwo, two); |
| 841 | |||
| 842 |
2/6✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
72 | return B.CreateSelect(isInputRangeValid, result, outputRangeOverTwo); |
| 843 | 13 | }; | |
| 844 | |||
| 845 | using FitD = double(double, double, double, double, double); | ||
| 846 | using FitF = float(float, float, float, float, float); | ||
| 847 | using FitL = double(int64_t, int64_t, int64_t, int64_t, int64_t); | ||
| 848 | using FitI = double(int32_t, int32_t, int32_t, int32_t, int32_t); | ||
| 849 | |||
| 850 | 13 | return FunctionBuilder("fit") | |
| 851 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | .addSignature<FitD>(generate) |
| 852 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<FitF>(generate) |
| 853 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<FitL>(generate) |
| 854 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<FitI>(generate) |
| 855 | 13 | .addDependency("clamp") | |
| 856 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"value", "omin", "omax", "nmin", "nmax"}) |
| 857 | .setConstantFold(false) | ||
| 858 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 859 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 860 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 861 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 862 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 863 | .setDocumentation("Fit the first argument to the output range by " | ||
| 864 | "first clamping the value between the second and third input range " | ||
| 865 | "arguments and then remapping the result to the output range fourth and " | ||
| 866 | "fifth arguments") | ||
| 867 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 868 | } | ||
| 869 | |||
| 870 | 14 | inline FunctionGroup::UniquePtr axrand(const FunctionOptions& op) | |
| 871 | { | ||
| 872 | struct Rand | ||
| 873 | { | ||
| 874 | 100712556 | static double rand(const std::mt19937_64::result_type* seed) | |
| 875 | { | ||
| 876 | using ThreadLocalEngineContainer = | ||
| 877 | tbb::enumerable_thread_specific<std::mt19937_64>; | ||
| 878 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 100712555 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
100712556 | static ThreadLocalEngineContainer ThreadLocalEngines; |
| 879 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 100712555 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
100712556 | static std::uniform_real_distribution<double> Generator(0.0,1.0); |
| 880 | std::mt19937_64& engine = ThreadLocalEngines.local(); | ||
| 881 |
2/2✓ Branch 0 taken 75534417 times.
✓ Branch 1 taken 25178139 times.
|
100712556 | if (seed) { |
| 882 | 75534417 | engine.seed(static_cast<std::mt19937_64::result_type>(*seed)); | |
| 883 | } | ||
| 884 | 100712556 | return Generator(engine); | |
| 885 | } | ||
| 886 | |||
| 887 | 25178139 | static double rand() { return Rand::rand(nullptr); } | |
| 888 | |||
| 889 |
1/2✓ Branch 0 taken 75534417 times.
✗ Branch 1 not taken.
|
75534417 | static double rand(double seed) |
| 890 | { | ||
| 891 | const std::mt19937_64::result_type hash = | ||
| 892 | 75534417 | static_cast<std::mt19937_64::result_type>(std::hash<double>()(seed)); | |
| 893 | 75534417 | return Rand::rand(&hash); | |
| 894 | } | ||
| 895 | |||
| 896 | ✗ | static double rand(int64_t seed) | |
| 897 | { | ||
| 898 | ✗ | const std::mt19937_64::result_type hash = | |
| 899 | ✗ | static_cast<std::mt19937_64::result_type>(seed); | |
| 900 | ✗ | return Rand::rand(&hash); | |
| 901 | } | ||
| 902 | }; | ||
| 903 | |||
| 904 | 14 | return FunctionBuilder("rand") | |
| 905 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | .addSignature<double()>((double(*)())(Rand::rand)) |
| 906 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | .addSignature<double(double)>((double(*)(double))(Rand::rand)) |
| 907 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | .addSignature<double(int64_t)>((double(*)(int64_t))(Rand::rand)) |
| 908 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
|
28 | .setArgumentNames({"seed"}) |
| 909 | // We can't constant fold rand even if it's been called with a constant as | ||
| 910 | // it will leave the generator in a different state in comparison to other | ||
| 911 | // threads and, as it relies on an internal state, doesn't respect branching | ||
| 912 | // etc. We also can't use a different generate for constant calls as subsequent | ||
| 913 | // calls to rand() without an argument won't know to advance the generator. | ||
| 914 | .setConstantFold(false) | ||
| 915 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 916 | .setDocumentation("Creates a random number based on the provided " | ||
| 917 | "seed. The number will be in the range of 0 to 1. The same number is " | ||
| 918 | "produced for the same seed. Note that if rand is called without a seed " | ||
| 919 | "the previous state of the random number generator is advanced for the " | ||
| 920 | "currently processing element. This state is determined by the last call to " | ||
| 921 | "rand() with a given seed. If rand is not called with a seed, the generator " | ||
| 922 | "advances continuously across different elements which can produce non-" | ||
| 923 | "deterministic results. It is important that rand is always called with a " | ||
| 924 | "seed at least once for deterministic results.") | ||
| 925 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | .get(); |
| 926 | } | ||
| 927 | |||
| 928 | 13 | inline FunctionGroup::UniquePtr axrand32(const FunctionOptions& op) | |
| 929 | { | ||
| 930 | struct Rand | ||
| 931 | { | ||
| 932 | 252 | static double rand(const std::mt19937::result_type* seed) | |
| 933 | { | ||
| 934 | using ThreadLocalEngineContainer = | ||
| 935 | tbb::enumerable_thread_specific<std::mt19937>; | ||
| 936 | // Obtain thread-local engine (or create if it doesn't exist already). | ||
| 937 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 251 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
252 | static ThreadLocalEngineContainer ThreadLocalEngines; |
| 938 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 251 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
252 | static std::uniform_real_distribution<double> Generator(0.0,1.0); |
| 939 | std::mt19937& engine = ThreadLocalEngines.local(); | ||
| 940 |
2/2✓ Branch 0 taken 189 times.
✓ Branch 1 taken 63 times.
|
252 | if (seed) { |
| 941 | 189 | engine.seed(static_cast<std::mt19937::result_type>(*seed)); | |
| 942 | } | ||
| 943 | // Once we have seeded the random number generator, we then evaluate it, | ||
| 944 | // which returns a floating point number in the range [0,1) | ||
| 945 | 252 | return Generator(engine); | |
| 946 | } | ||
| 947 | |||
| 948 | 63 | static double rand() { return Rand::rand(nullptr); } | |
| 949 | |||
| 950 |
1/2✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
|
189 | static double rand(double seed) |
| 951 | { | ||
| 952 | // We initially hash the double-precision seed with `std::hash`. The | ||
| 953 | // important thing about the hash is that it produces a "reliable" hash value, | ||
| 954 | // taking into account a number of special cases for floating point numbers | ||
| 955 | // (e.g. -0 and +0 must return the same hash value, etc). Other than these | ||
| 956 | // special cases, this function will usually just copy the binary | ||
| 957 | // representation of a float into the resultant `size_t` | ||
| 958 | 189 | const size_t hash = std::hash<double>()(seed); | |
| 959 | |||
| 960 | // Now that we have a reliable hash (with special floating-point cases taken | ||
| 961 | // care of), we proceed to use this hash to seed a random number generator. | ||
| 962 | // The generator takes an unsigned int, which is not guaranteed to be the | ||
| 963 | // same size as size_t. | ||
| 964 | // | ||
| 965 | // So, we must convert it. I should note that the OpenVDB math libraries will | ||
| 966 | // do this for us, but its implementation static_casts `size_t` to `unsigned int`, | ||
| 967 | // and because `std::hash` returns a binary copy of the original | ||
| 968 | // double-precision number in almost all cases, this ends up producing noticable | ||
| 969 | // patterns in the result (e.g. by truncating the upper 4 bytes, values of 1.0, | ||
| 970 | // 2.0, 3.0, and 4.0 all return the same hash value because their lower 4 bytes | ||
| 971 | // are all zero). | ||
| 972 | // | ||
| 973 | // We use the `hashToSeed` function to reduce our `size_t` to an `unsigned int`, | ||
| 974 | // whilst taking all bits in the `size_t` into account. | ||
| 975 | // On some architectures std::uint_fast32_t may be size_t, but we always hash to | ||
| 976 | // be consistent. | ||
| 977 | const std::mt19937::result_type uintseed = | ||
| 978 | 189 | static_cast<std::mt19937::result_type>(hashToSeed<uint32_t>(hash)); | |
| 979 | 189 | return Rand::rand(&uintseed); | |
| 980 | } | ||
| 981 | |||
| 982 | ✗ | static double rand(int32_t seed) | |
| 983 | { | ||
| 984 | ✗ | const std::mt19937::result_type uintseed = | |
| 985 | ✗ | static_cast<std::mt19937::result_type>(seed); | |
| 986 | ✗ | return Rand::rand(&uintseed); | |
| 987 | } | ||
| 988 | }; | ||
| 989 | |||
| 990 | 13 | return FunctionBuilder("rand32") | |
| 991 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double()>((double(*)())(Rand::rand)) |
| 992 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double(double)>((double(*)(double))(Rand::rand)) |
| 993 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double(int32_t)>((double(*)(int32_t))(Rand::rand)) |
| 994 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"seed"}) |
| 995 | // We can't constant fold rand even if it's been called with a constant as | ||
| 996 | // it will leave the generator in a different state in comparison to other | ||
| 997 | // threads and, as it relies on an internal state, doesn't respect branching | ||
| 998 | // etc. We also can't use a different generate for constant calls as subsequent | ||
| 999 | // calls to rand() without an argument won't know to advance the generator. | ||
| 1000 | .setConstantFold(false) | ||
| 1001 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1002 | .setDocumentation("Creates a random number based on the provided 32 bit " | ||
| 1003 | "seed. The number will be in the range of 0 to 1. The same number is " | ||
| 1004 | "produced for the same seed. " | ||
| 1005 | "NOTE: This function does not share the same random number generator as " | ||
| 1006 | "rand(). rand32() may provide a higher throughput on some architectures, " | ||
| 1007 | "but will produce different results to rand(). " | ||
| 1008 | "NOTE: If rand32 is called without a seed the previous state of the random " | ||
| 1009 | "number generator is advanced for the currently processing element. This " | ||
| 1010 | "state is determined by the last call to rand32() with a given seed. If " | ||
| 1011 | "rand32 is not called with a seed, the generator advances continuously " | ||
| 1012 | "across different elements which can produce non-deterministic results. " | ||
| 1013 | "It is important that rand32 is always called with a seed at least once " | ||
| 1014 | "for deterministic results.") | ||
| 1015 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1016 | } | ||
| 1017 | |||
| 1018 | 13 | inline FunctionGroup::UniquePtr axsign(const FunctionOptions& op) | |
| 1019 | { | ||
| 1020 | static auto generate = | ||
| 1021 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | [](const std::vector<llvm::Value*>& args, |
| 1022 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1023 | { | ||
| 1024 | // int r = (T(0) < val) - (val < T(0)); | ||
| 1025 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | assert(args.size() == 1); |
| 1026 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
|
36 | llvm::Value* arg = args.front(); |
| 1027 | llvm::Type* type = arg->getType(); | ||
| 1028 | llvm::Value* zero; | ||
| 1029 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
|
36 | if (type->isIntegerTy()) { |
| 1030 | 12 | zero = llvm::ConstantInt::get(type, static_cast<uint64_t>(0), /*signed*/true); | |
| 1031 | } | ||
| 1032 | else { | ||
| 1033 | ✗ | assert(type->isFloatingPointTy()); | |
| 1034 | 24 | zero = llvm::ConstantFP::get(type, static_cast<double>(0.0)); | |
| 1035 | } | ||
| 1036 | |||
| 1037 | 36 | llvm::Value* c1 = binaryOperator(zero, arg, ast::tokens::LESSTHAN, B); | |
| 1038 | 36 | c1 = arithmeticConversion(c1, LLVMType<int32_t>::get(B.getContext()), B); | |
| 1039 | 36 | llvm::Value* c2 = binaryOperator(arg, zero, ast::tokens::LESSTHAN, B); | |
| 1040 | 36 | c2 = arithmeticConversion(c2, LLVMType<int32_t>::get(B.getContext()), B); | |
| 1041 | 36 | llvm::Value* r = binaryOperator(c1, c2, ast::tokens::MINUS, B); | |
| 1042 | 36 | return arithmeticConversion(r, LLVMType<int32_t>::get(B.getContext()), B); | |
| 1043 | }; | ||
| 1044 | |||
| 1045 | 13 | return FunctionBuilder("sign") | |
| 1046 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | .addSignature<int32_t(double)>(generate) |
| 1047 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<int32_t(float)>(generate) |
| 1048 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<int32_t(int64_t)>(generate) |
| 1049 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<int32_t(int32_t)>(generate) |
| 1050 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"n"}) |
| 1051 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 1052 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 1053 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1054 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1055 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1056 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1057 | .setDocumentation("Implements signum, determining if the input is negative, zero " | ||
| 1058 | "or positive. Returns -1 for a negative number, 0 for the number zero, and +1 " | ||
| 1059 | "for a positive number. Note that this function does not check the sign of " | ||
| 1060 | "floating point +/-0.0 values. See signbit().") | ||
| 1061 | 13 | .get(); | |
| 1062 | } | ||
| 1063 | |||
| 1064 | 13 | inline FunctionGroup::UniquePtr axsignbit(const FunctionOptions& op) | |
| 1065 | { | ||
| 1066 | 13 | return FunctionBuilder("signbit") | |
| 1067 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<bool(double)>((bool(*)(double))(std::signbit)) |
| 1068 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<bool(float)>((bool(*)(float))(std::signbit)) |
| 1069 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"n"}) |
| 1070 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 1071 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 1072 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1073 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1074 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1075 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1076 | .setDocumentation("Determines if the given floating point number input is negative. " | ||
| 1077 | "Returns true if arg is negative, false otherwise. Will return true for -0.0, " | ||
| 1078 | "false for +0.0") | ||
| 1079 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1080 | } | ||
| 1081 | |||
| 1082 | 13 | inline FunctionGroup::UniquePtr axtruncatemod(const FunctionOptions& op) | |
| 1083 | { | ||
| 1084 | static auto generate = | ||
| 1085 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | [](const std::vector<llvm::Value*>& args, |
| 1086 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1087 | { | ||
| 1088 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | assert(args.size() == 2); |
| 1089 | 36 | return binaryOperator(args[0], args[1], ast::tokens::MODULO, B); | |
| 1090 | }; | ||
| 1091 | |||
| 1092 | 13 | return FunctionBuilder("truncatemod") | |
| 1093 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | .addSignature<double(double,double)>(generate) |
| 1094 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<float(float,float)>(generate) |
| 1095 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<int64_t(int64_t,int64_t)>(generate) |
| 1096 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<int32_t(int32_t,int32_t)>(generate) |
| 1097 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"dividend", "divisor"}) |
| 1098 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 1099 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 1100 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1101 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1102 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1103 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1104 | .setDocumentation("Truncated modulo, where the result of the division operator " | ||
| 1105 | "on (dividend / divisor) is truncated. The remainder is thus calculated with " | ||
| 1106 | "D - d * trunc(D/d). This is equal to the C/C++ % implementation. This is NOT " | ||
| 1107 | "equal to a%b in AX. See floormod(), euclideanmod().") | ||
| 1108 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1109 | } | ||
| 1110 | |||
| 1111 | 153 | inline FunctionGroup::UniquePtr axfloormod(const FunctionOptions& op) | |
| 1112 | { | ||
| 1113 | static auto ifmod = [](auto D, auto d) -> auto | ||
| 1114 | { | ||
| 1115 | using ValueType = decltype(D); | ||
| 1116 | auto r = D % d; // tmod | ||
| 1117 | if ((r > 0 && d < 0) || (r < 0 && d > 0)) r = r+d; | ||
| 1118 | return ValueType(r); | ||
| 1119 | }; | ||
| 1120 | |||
| 1121 |
2/2✓ Branch 0 taken 420 times.
✓ Branch 1 taken 420 times.
|
4544 | static auto ffmod = [](auto D, auto d) -> auto |
| 1122 | { | ||
| 1123 | 2864 | auto r = std::fmod(D, d); | |
| 1124 |
8/8✓ Branch 0 taken 1062 times.
✓ Branch 1 taken 1210 times.
✓ Branch 2 taken 642 times.
✓ Branch 3 taken 420 times.
✓ Branch 4 taken 988 times.
✓ Branch 5 taken 864 times.
✓ Branch 6 taken 568 times.
✓ Branch 7 taken 420 times.
|
4544 | if ((r > 0 && d < 0) || (r < 0 && d > 0)) r = r+d; |
| 1125 | 4544 | return r; | |
| 1126 | }; | ||
| 1127 | |||
| 1128 | static auto generate = | ||
| 1129 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
|
144 | [](const std::vector<llvm::Value*>& args, |
| 1130 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1131 | { | ||
| 1132 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
|
144 | assert(args.size() == 2); |
| 1133 | 144 | llvm::Value* D = args[0]; | |
| 1134 | 144 | llvm::Value* d = args[1]; | |
| 1135 | // tmod | ||
| 1136 | 144 | llvm::Value* r = binaryOperator(D, d, ast::tokens::MODULO, B); | |
| 1137 | |||
| 1138 | 144 | llvm::Value* zero = llvmConstant(0, D->getType()); | |
| 1139 | 144 | llvm::Value* a1 = binaryOperator(r, zero, ast::tokens::MORETHAN, B); | |
| 1140 | 144 | llvm::Value* a2 = binaryOperator(d, zero, ast::tokens::LESSTHAN, B); | |
| 1141 | 144 | a1 = binaryOperator(a1, a2, ast::tokens::AND, B); | |
| 1142 | 144 | llvm::Value* b1 = binaryOperator(r, zero, ast::tokens::LESSTHAN, B); | |
| 1143 | 144 | llvm::Value* b2 = binaryOperator(d, zero, ast::tokens::MORETHAN, B); | |
| 1144 | 144 | b1 = binaryOperator(b1, b2, ast::tokens::AND, B); | |
| 1145 | 144 | a1 = binaryOperator(a1, b1, ast::tokens::OR, B); | |
| 1146 | |||
| 1147 | 144 | llvm::Value* rplus = binaryOperator(r, d, ast::tokens::PLUS, B); | |
| 1148 | 144 | return B.CreateSelect(a1, rplus, r); | |
| 1149 | }; | ||
| 1150 | |||
| 1151 | 153 | return FunctionBuilder("floormod") | |
| 1152 | 306 | .addSignature<double(double,double)>(generate, (double(*)(double,double))(ffmod)) | |
| 1153 |
1/4✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
306 | .addSignature<float(float,float)>(generate, (float(*)(float,float))(ffmod)) |
| 1154 |
1/4✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
306 | .addSignature<int64_t(int64_t,int64_t)>(generate, (int64_t(*)(int64_t,int64_t))(ifmod)) |
| 1155 |
1/4✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
306 | .addSignature<int32_t(int32_t,int32_t)>(generate, (int32_t(*)(int32_t,int32_t))(ifmod)) |
| 1156 |
3/8✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 153 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 153 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
306 | .setArgumentNames({"dividend", "divisor"}) |
| 1157 |
1/2✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
|
153 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 1158 |
1/2✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
|
153 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 1159 |
1/2✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
|
153 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1160 | 153 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1161 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 129 times.
|
153 | .setConstantFold(op.mConstantFoldCBindings) |
| 1162 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 129 times.
|
153 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1163 | .setDocumentation("Floored modulo, where the result of the division operator " | ||
| 1164 | "on (dividend / divisor) is floored. The remainder is thus calculated with " | ||
| 1165 | "D - d * floor(D/d). This is the implemented modulo % operator of AX. This is " | ||
| 1166 | "equal to the python % implementation. See trucnatemod(), euclideanmod().") | ||
| 1167 |
1/2✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
|
306 | .get(); |
| 1168 | } | ||
| 1169 | |||
| 1170 | 13 | inline FunctionGroup::UniquePtr axeuclideanmod(const FunctionOptions& op) | |
| 1171 | { | ||
| 1172 | static auto iemod = [](auto D, auto d) -> auto | ||
| 1173 | { | ||
| 1174 | using ValueType = decltype(D); | ||
| 1175 | auto r = D%d; | ||
| 1176 | if (r < 0) { | ||
| 1177 | if (d > 0) r = r + d; | ||
| 1178 | else r = r - d; | ||
| 1179 | } | ||
| 1180 | return ValueType(r); | ||
| 1181 | }; | ||
| 1182 | |||
| 1183 | static auto femod = [](auto D, auto d) -> auto | ||
| 1184 | { | ||
| 1185 | auto r = std::fmod(D, d); | ||
| 1186 | if (r < 0) { | ||
| 1187 | if (d > 0) r = r + d; | ||
| 1188 | else r = r - d; | ||
| 1189 | } | ||
| 1190 | return r; | ||
| 1191 | }; | ||
| 1192 | |||
| 1193 | static auto generate = | ||
| 1194 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | [](const std::vector<llvm::Value*>& args, |
| 1195 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1196 | { | ||
| 1197 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | assert(args.size() == 2); |
| 1198 | 12 | llvm::Value* D = args[0], *d = args[1]; | |
| 1199 | 12 | llvm::Value* r = binaryOperator(D, d, ast::tokens::MODULO, B); // tmod | |
| 1200 | |||
| 1201 | 12 | llvm::Value* zero = llvmConstant(0, D->getType()); | |
| 1202 | 12 | llvm::Value* a1 = binaryOperator(d, zero, ast::tokens::MORETHAN, B); | |
| 1203 | 12 | llvm::Value* rplus = binaryOperator(r, d, ast::tokens::PLUS, B); | |
| 1204 | 12 | llvm::Value* rminus = binaryOperator(r, d, ast::tokens::MINUS, B); | |
| 1205 | 12 | llvm::Value* rd = B.CreateSelect(a1, rplus, rminus); | |
| 1206 | |||
| 1207 | 12 | a1 = binaryOperator(r, zero, ast::tokens::LESSTHAN, B); | |
| 1208 | 12 | return B.CreateSelect(a1, rd, r); | |
| 1209 | }; | ||
| 1210 | |||
| 1211 | 13 | return FunctionBuilder("euclideanmod") | |
| 1212 | 26 | .addSignature<double(double,double)>(generate, (double(*)(double,double))(femod)) | |
| 1213 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<float(float,float)>(generate, (float(*)(float,float))(femod)) |
| 1214 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<int64_t(int64_t,int64_t)>(generate, (int64_t(*)(int64_t,int64_t))(iemod)) |
| 1215 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<int32_t(int32_t,int32_t)>(generate, (int32_t(*)(int32_t,int32_t))(iemod)) |
| 1216 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"dividend", "divisor"}) |
| 1217 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 1218 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 1219 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1220 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1221 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1222 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1223 | .setDocumentation("Euclidean modulo, where by the result of the division operator " | ||
| 1224 | "on (dividend / divisor) is floored or ceiled depending on its sign, guaranteeing " | ||
| 1225 | "that the return value is always positive. The remainder is thus calculated with " | ||
| 1226 | "D - d * (d < 0 ? ceil(D/d) : floor(D/d)). This is NOT equal to a%b in AX. See " | ||
| 1227 | "truncatemod(), floormod().") | ||
| 1228 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1229 | } | ||
| 1230 | |||
| 1231 | 13 | inline FunctionGroup::UniquePtr axisfinite(const FunctionOptions& op) | |
| 1232 | { | ||
| 1233 | auto generate = | ||
| 1234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | [op](const std::vector<llvm::Value*>& args, |
| 1235 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1236 | { | ||
| 1237 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | assert(args.size() == 1); |
| 1238 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
|
48 | llvm::Value* arg = args[0]; |
| 1239 | llvm::Type* etype = arg->getType(); | ||
| 1240 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
|
48 | if (etype->isPointerTy()) { |
| 1241 | etype = etype->getPointerElementType()->getArrayElementType(); | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | llvm::Value* inf; | ||
| 1245 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
|
48 | if (etype->isFloatTy()) { |
| 1246 | const llvm::APFloat apinf = | ||
| 1247 | 24 | llvm::APFloat::getInf(llvm::APFloatBase::IEEEsingle()); | |
| 1248 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | inf = LLVMType<float>::get(B.getContext(), apinf.convertToFloat()); |
| 1249 | } | ||
| 1250 | else { | ||
| 1251 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | assert(etype->isDoubleTy()); |
| 1252 | const llvm::APFloat apinf = | ||
| 1253 | 24 | llvm::APFloat::getInf(llvm::APFloatBase::IEEEdouble()); | |
| 1254 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | inf = LLVMType<double>::get(B.getContext(), apinf.convertToDouble()); |
| 1255 | } | ||
| 1256 | |||
| 1257 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
|
48 | if (!arg->getType()->isPointerTy()) { |
| 1258 |
2/4✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
|
16 | arg = llvm_fabs(op)->execute({arg}, B); |
| 1259 | 8 | return binaryOperator(inf, arg, ast::tokens::NOTEQUALS, B); | |
| 1260 | } | ||
| 1261 | |||
| 1262 | std::vector<llvm::Value*> array; | ||
| 1263 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | arrayUnpack(arg, array, B, /*load*/true); |
| 1264 | |||
| 1265 | // @todo short-circuit? | ||
| 1266 | llvm::Value* result = B.getTrue(); | ||
| 1267 |
2/2✓ Branch 0 taken 272 times.
✓ Branch 1 taken 40 times.
|
312 | for (auto& value : array) { |
| 1268 |
4/8✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 272 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 272 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 272 times.
✗ Branch 10 not taken.
|
544 | value = llvm_fabs(op)->execute({value}, B); |
| 1269 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
272 | llvm::Value* comp = binaryOperator(inf, value, ast::tokens::NOTEQUALS, B); |
| 1270 |
1/4✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
272 | result = binaryOperator(comp, result, ast::tokens::AND, B); |
| 1271 | } | ||
| 1272 | return result; | ||
| 1273 | 13 | }; | |
| 1274 | |||
| 1275 | static auto isfinitearray = [](const auto input) -> bool | ||
| 1276 | { | ||
| 1277 | return input->isFinite(); | ||
| 1278 | }; | ||
| 1279 | |||
| 1280 | 13 | return FunctionBuilder("isfinite") | |
| 1281 | 26 | .addSignature<bool(openvdb::Vec2d*)>(generate, (bool(*)(openvdb::Vec2d*))(isfinitearray)) | |
| 1282 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec2f*)>(generate, (bool(*)(openvdb::Vec2f*))(isfinitearray)) |
| 1283 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec3d*)>(generate, (bool(*)(openvdb::Vec3d*))(isfinitearray)) |
| 1284 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec3f*)>(generate, (bool(*)(openvdb::Vec3f*))(isfinitearray)) |
| 1285 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec4d*)>(generate, (bool(*)(openvdb::Vec4d*))(isfinitearray)) |
| 1286 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec4f*)>(generate, (bool(*)(openvdb::Vec4f*))(isfinitearray)) |
| 1287 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat3<float>*)>(generate, (bool(*)(openvdb::math::Mat3<float>*))(isfinitearray)) |
| 1288 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat3<double>*)>(generate, (bool(*)(openvdb::math::Mat3<double>*))(isfinitearray)) |
| 1289 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat4<float>*)>(generate, (bool(*)(openvdb::math::Mat4<float>*))(isfinitearray)) |
| 1290 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat4<double>*)>(generate, (bool(*)(openvdb::math::Mat4<double>*))(isfinitearray)) |
| 1291 | 13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) | |
| 1292 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(double)>(generate, (bool(*)(double))(std::isfinite)) |
| 1293 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(float)>(generate, (bool(*)(float))(std::isfinite)) |
| 1294 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"arg"}) |
| 1295 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("fabs") |
| 1296 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 1297 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 1298 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1299 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1300 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1301 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1302 | .setDocumentation("Returns whether the value is finite i.e. not infinite or NaN. " | ||
| 1303 | "For matrix and vector types will return false if any element is not finite.") | ||
| 1304 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1305 | } | ||
| 1306 | |||
| 1307 | 13 | inline FunctionGroup::UniquePtr axisinf(const FunctionOptions& op) | |
| 1308 | { | ||
| 1309 | auto generate = | ||
| 1310 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | [op](const std::vector<llvm::Value*>& args, |
| 1311 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1312 | { | ||
| 1313 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | assert(args.size() == 1); |
| 1314 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
|
48 | llvm::Value* arg = args[0]; |
| 1315 | llvm::Type* etype = arg->getType(); | ||
| 1316 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
|
48 | if (etype->isPointerTy()) { |
| 1317 | etype = etype->getPointerElementType()->getArrayElementType(); | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | llvm::Value* inf; | ||
| 1321 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
|
48 | if (etype->isFloatTy()) { |
| 1322 | const llvm::APFloat apinf = | ||
| 1323 | 24 | llvm::APFloat::getInf(llvm::APFloatBase::IEEEsingle()); | |
| 1324 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | inf = LLVMType<float>::get(B.getContext(), apinf.convertToFloat()); |
| 1325 | } | ||
| 1326 | else { | ||
| 1327 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | assert(etype->isDoubleTy()); |
| 1328 | const llvm::APFloat apinf = | ||
| 1329 | 24 | llvm::APFloat::getInf(llvm::APFloatBase::IEEEdouble()); | |
| 1330 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | inf = LLVMType<double>::get(B.getContext(), apinf.convertToDouble()); |
| 1331 | } | ||
| 1332 | |||
| 1333 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
|
48 | if (!arg->getType()->isPointerTy()) { |
| 1334 |
2/4✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
|
16 | arg = llvm_fabs(op)->execute({arg}, B); |
| 1335 | 8 | return binaryOperator(inf, arg, ast::tokens::EQUALSEQUALS, B); | |
| 1336 | } | ||
| 1337 | |||
| 1338 | std::vector<llvm::Value*> array; | ||
| 1339 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | arrayUnpack(arg, array, B, /*load*/true); |
| 1340 | |||
| 1341 | // @todo short-circuit? | ||
| 1342 | llvm::Value* result = B.getFalse(); | ||
| 1343 |
2/2✓ Branch 0 taken 272 times.
✓ Branch 1 taken 40 times.
|
312 | for (auto& value : array) { |
| 1344 |
4/8✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 272 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 272 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 272 times.
✗ Branch 10 not taken.
|
544 | value = llvm_fabs(op)->execute({value}, B); |
| 1345 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
272 | llvm::Value* comp = binaryOperator(inf, value, ast::tokens::EQUALSEQUALS, B); |
| 1346 |
1/4✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
272 | result = binaryOperator(comp, result, ast::tokens::OR, B); |
| 1347 | } | ||
| 1348 | return result; | ||
| 1349 | 13 | }; | |
| 1350 | |||
| 1351 | static auto isinfarray = [](const auto input) -> bool | ||
| 1352 | { | ||
| 1353 | return input->isInfinite(); | ||
| 1354 | }; | ||
| 1355 | |||
| 1356 | 13 | return FunctionBuilder("isinf") | |
| 1357 | 26 | .addSignature<bool(openvdb::Vec2d*)>(generate, (bool(*)(openvdb::Vec2d*))(isinfarray)) | |
| 1358 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec2f*)>(generate, (bool(*)(openvdb::Vec2f*))(isinfarray)) |
| 1359 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec3d*)>(generate, (bool(*)(openvdb::Vec3d*))(isinfarray)) |
| 1360 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec3f*)>(generate, (bool(*)(openvdb::Vec3f*))(isinfarray)) |
| 1361 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec4d*)>(generate, (bool(*)(openvdb::Vec4d*))(isinfarray)) |
| 1362 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec4f*)>(generate, (bool(*)(openvdb::Vec4f*))(isinfarray)) |
| 1363 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat3<float>*)>(generate, (bool(*)(openvdb::math::Mat3<float>*))(isinfarray)) |
| 1364 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat3<double>*)>(generate, (bool(*)(openvdb::math::Mat3<double>*))(isinfarray)) |
| 1365 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat4<float>*)>(generate, (bool(*)(openvdb::math::Mat4<float>*))(isinfarray)) |
| 1366 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat4<double>*)>(generate, (bool(*)(openvdb::math::Mat4<double>*))(isinfarray)) |
| 1367 | 13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) | |
| 1368 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<bool(double)>(generate /*, (bool(*)(double))(std::isinf)*/) // @note: gcc needs _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC defined |
| 1369 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(float)>(generate, (bool(*)(float))(std::isinf)) |
| 1370 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"arg"}) |
| 1371 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("fabs") |
| 1372 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 1373 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 1374 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1375 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1376 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1377 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1378 | .setDocumentation("Returns whether the value is inf. " | ||
| 1379 | "For matrix and vector types will return true if any element is inf.") | ||
| 1380 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1381 | } | ||
| 1382 | |||
| 1383 | 13 | inline FunctionGroup::UniquePtr axisnan(const FunctionOptions& op) | |
| 1384 | { | ||
| 1385 | static auto generate = | ||
| 1386 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | [](const std::vector<llvm::Value*>& args, |
| 1387 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1388 | { | ||
| 1389 | // uno (unordered) comparison with self | ||
| 1390 | // https://llvm.org/docs/LangRef.html#fcmp-instruction | ||
| 1391 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | assert(args.size() == 1); |
| 1392 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
|
48 | llvm::Value* arg = args[0]; |
| 1393 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
|
48 | if (!arg->getType()->isPointerTy()) { |
| 1394 | 16 | return B.CreateFCmpUNO(arg, arg); | |
| 1395 | } | ||
| 1396 | |||
| 1397 | std::vector<llvm::Value*> array; | ||
| 1398 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | arrayUnpack(arg, array, B, /*load*/true); |
| 1399 | |||
| 1400 | // @todo short-circuit? | ||
| 1401 | llvm::Value* result = B.getFalse(); | ||
| 1402 |
2/2✓ Branch 0 taken 272 times.
✓ Branch 1 taken 40 times.
|
312 | for (auto& value : array) { |
| 1403 |
1/2✓ Branch 2 taken 272 times.
✗ Branch 3 not taken.
|
272 | llvm::Value* comp = B.CreateFCmpUNO(value, value); |
| 1404 |
1/4✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
272 | result = binaryOperator(comp, result, ast::tokens::OR, B); |
| 1405 | } | ||
| 1406 | return result; | ||
| 1407 | }; | ||
| 1408 | |||
| 1409 | static auto isnanarray = [](const auto input) -> bool | ||
| 1410 | { | ||
| 1411 | return input->isNan(); | ||
| 1412 | }; | ||
| 1413 | |||
| 1414 | 13 | return FunctionBuilder("isnan") | |
| 1415 | 26 | .addSignature<bool(openvdb::Vec2d*)>(generate, (bool(*)(openvdb::Vec2d*))(isnanarray)) | |
| 1416 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec2f*)>(generate, (bool(*)(openvdb::Vec2f*))(isnanarray)) |
| 1417 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec3d*)>(generate, (bool(*)(openvdb::Vec3d*))(isnanarray)) |
| 1418 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec3f*)>(generate, (bool(*)(openvdb::Vec3f*))(isnanarray)) |
| 1419 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec4d*)>(generate, (bool(*)(openvdb::Vec4d*))(isnanarray)) |
| 1420 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::Vec4f*)>(generate, (bool(*)(openvdb::Vec4f*))(isnanarray)) |
| 1421 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat3<float>*)>(generate, (bool(*)(openvdb::math::Mat3<float>*))(isnanarray)) |
| 1422 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat3<double>*)>(generate, (bool(*)(openvdb::math::Mat3<double>*))(isnanarray)) |
| 1423 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat4<float>*)>(generate, (bool(*)(openvdb::math::Mat4<float>*))(isnanarray)) |
| 1424 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(openvdb::math::Mat4<double>*)>(generate, (bool(*)(openvdb::math::Mat4<double>*))(isnanarray)) |
| 1425 | 13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) | |
| 1426 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<bool(double)>(generate/*, (bool(*)(double))(std::isnan)*/) // @note: gcc needs _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC defined |
| 1427 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<bool(float)>(generate, (bool(*)(float))(std::isnan)) |
| 1428 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"arg"}) |
| 1429 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 1430 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 1431 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1432 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1433 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1434 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1435 | .setDocumentation("Returns whether the value is NaN (not-a-number).") | ||
| 1436 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1437 | } | ||
| 1438 | |||
| 1439 | /////////////////////////////////////////////////////////////////////////// | ||
| 1440 | /////////////////////////////////////////////////////////////////////////// | ||
| 1441 | |||
| 1442 | // Matrix math | ||
| 1443 | |||
| 1444 | 13 | inline FunctionGroup::UniquePtr axdeterminant(const FunctionOptions& op) | |
| 1445 | { | ||
| 1446 | // 3 by 3 determinant | ||
| 1447 | static auto generate3 = | ||
| 1448 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | [](const std::vector<llvm::Value*>& args, |
| 1449 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1450 | { | ||
| 1451 | std::vector<llvm::Value*> m1; | ||
| 1452 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | arrayUnpack(args[0], m1, B, /*load*/true); |
| 1453 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | assert(m1.size() == 9); |
| 1454 | |||
| 1455 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* e1 = binaryOperator(m1[4], m1[8], ast::tokens::MULTIPLY, B); |
| 1456 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* e2 = binaryOperator(m1[5], m1[7], ast::tokens::MULTIPLY, B); |
| 1457 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* c0 = binaryOperator(e1, e2, ast::tokens::MINUS, B); |
| 1458 | |||
| 1459 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | e1 = binaryOperator(m1[5], m1[6], ast::tokens::MULTIPLY, B); |
| 1460 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | e2 = binaryOperator(m1[3], m1[8], ast::tokens::MULTIPLY, B); |
| 1461 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* c1 = binaryOperator(e1, e2, ast::tokens::MINUS, B); |
| 1462 | |||
| 1463 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | e1 = binaryOperator(m1[3], m1[7], ast::tokens::MULTIPLY, B); |
| 1464 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | e2 = binaryOperator(m1[4], m1[6], ast::tokens::MULTIPLY, B); |
| 1465 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* c2 = binaryOperator(e1, e2, ast::tokens::MINUS, B); |
| 1466 | |||
| 1467 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | c0 = binaryOperator(m1[0], c0, ast::tokens::MULTIPLY, B); |
| 1468 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | c1 = binaryOperator(m1[1], c1, ast::tokens::MULTIPLY, B); |
| 1469 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | c2 = binaryOperator(m1[2], c2, ast::tokens::MULTIPLY, B); |
| 1470 | |||
| 1471 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | c0 = binaryOperator(c0, c1, ast::tokens::PLUS, B); |
| 1472 |
2/6✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
40 | c0 = binaryOperator(c0, c2, ast::tokens::PLUS, B); |
| 1473 | 40 | return c0; | |
| 1474 | }; | ||
| 1475 | |||
| 1476 | // 4 by 4 determinant | ||
| 1477 | static auto generate4 = | ||
| 1478 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 1479 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1480 | { | ||
| 1481 | std::vector<llvm::Value*> m1; | ||
| 1482 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[0], m1, B, /*load*/true); |
| 1483 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(m1.size() == 16); |
| 1484 | |||
| 1485 | // @note Okay to alloca here as long as embed IR is false | ||
| 1486 |
3/8✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
8 | llvm::Value* subMat = B.CreateAlloca(llvm::ArrayType::get(m1.front()->getType(), 9)); |
| 1487 | std::vector<llvm::Value*> elements; | ||
| 1488 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(subMat, elements, B, /*load elements*/false); |
| 1489 | |||
| 1490 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* result = llvm::ConstantFP::get(m1.front()->getType(), 0.0); |
| 1491 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
|
40 | for (size_t i = 0; i < 4; ++i) { |
| 1492 | size_t sourceIndex = 0, targetIndex = 0; | ||
| 1493 |
2/2✓ Branch 0 taken 128 times.
✓ Branch 1 taken 32 times.
|
160 | for (size_t j = 0; j < 4; ++j) { |
| 1494 |
2/2✓ Branch 0 taken 512 times.
✓ Branch 1 taken 128 times.
|
640 | for (size_t k = 0; k < 4; ++k) { |
| 1495 |
2/2✓ Branch 0 taken 288 times.
✓ Branch 1 taken 224 times.
|
512 | if ((k != i) && (j != 0)) { |
| 1496 |
1/2✓ Branch 1 taken 288 times.
✗ Branch 2 not taken.
|
288 | B.CreateStore(m1[sourceIndex], elements[targetIndex]); |
| 1497 | 288 | ++targetIndex; | |
| 1498 | } | ||
| 1499 | 512 | ++sourceIndex; | |
| 1500 | } | ||
| 1501 | } | ||
| 1502 |
2/4✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
|
32 | llvm::Value* subResult = generate3({subMat}, B); |
| 1503 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | subResult = binaryOperator(m1[i], subResult, ast::tokens::MULTIPLY, B); |
| 1504 | |||
| 1505 |
3/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
32 | if (i % 2) result = binaryOperator(result, subResult, ast::tokens::MINUS, B); |
| 1506 |
1/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
16 | else result = binaryOperator(result, subResult, ast::tokens::PLUS, B); |
| 1507 | } | ||
| 1508 | |||
| 1509 | 8 | return result; | |
| 1510 | }; | ||
| 1511 | |||
| 1512 | static auto determinant = [](auto mat) -> auto { | ||
| 1513 | return mat->det(); | ||
| 1514 | }; | ||
| 1515 | |||
| 1516 | using DeterminantM3D = double(openvdb::math::Mat3<double>*); | ||
| 1517 | using DeterminantM3F = float(openvdb::math::Mat3<float>*); | ||
| 1518 | using DeterminantM4D = double(openvdb::math::Mat4<double>*); | ||
| 1519 | using DeterminantM4F = float(openvdb::math::Mat4<float>*); | ||
| 1520 | |||
| 1521 | 13 | return FunctionBuilder("determinant") | |
| 1522 | 26 | .addSignature<DeterminantM3D>(generate3, (DeterminantM3D*)(determinant)) | |
| 1523 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DeterminantM3F>(generate3, (DeterminantM3F*)(determinant)) |
| 1524 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DeterminantM4D>(generate4, (DeterminantM4D*)(determinant)) |
| 1525 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DeterminantM4F>(generate4, (DeterminantM4F*)(determinant)) |
| 1526 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"mat"}) |
| 1527 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 1528 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1529 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1530 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1531 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1532 | .setDocumentation("Returns the determinant of a matrix.") | ||
| 1533 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1534 | } | ||
| 1535 | |||
| 1536 | 13 | inline FunctionGroup::UniquePtr axdiag(const FunctionOptions& op) | |
| 1537 | { | ||
| 1538 | static auto generate = | ||
| 1539 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | [](const std::vector<llvm::Value*>& args, |
| 1540 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1541 | { | ||
| 1542 | std::vector<llvm::Value*> ptrs, arg1; | ||
| 1543 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | arrayUnpack(args[0], ptrs, B, /*load*/false); |
| 1544 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | arrayUnpack(args[1], arg1, B, /*load*/true); |
| 1545 | |||
| 1546 | const size_t size = arg1.size(); | ||
| 1547 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | if (size == 3 || size == 4) { |
| 1548 | //vector - convert to diagonal matrix | ||
| 1549 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | const size_t dim = size*size; |
| 1550 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | assert(ptrs.size() == dim); |
| 1551 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | llvm::Type* type = arg1.front()->getType(); |
| 1552 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* zero = type->isFloatTy() ? LLVMType<float>::get(B.getContext(), 0.0f) |
| 1553 |
3/4✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
16 | : LLVMType<double>::get(B.getContext(), 0.0); |
| 1554 | |||
| 1555 |
2/2✓ Branch 0 taken 200 times.
✓ Branch 1 taken 16 times.
|
216 | for (size_t i = 0, j = 0; i < dim; ++i) { |
| 1556 | llvm::Value* m = zero; | ||
| 1557 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 144 times.
|
200 | if (i % (size + 1) == 0) { |
| 1558 | 56 | m = arg1[j]; | |
| 1559 | 56 | ++j; | |
| 1560 | } | ||
| 1561 |
1/2✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
|
200 | B.CreateStore(m, ptrs[i]); |
| 1562 | } | ||
| 1563 | } | ||
| 1564 | else { | ||
| 1565 | // matrix - convert to vector | ||
| 1566 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | assert(size == 9 || size == 16); |
| 1567 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | const size_t dim = size == 9 ? 3 : 4; |
| 1568 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | assert(ptrs.size() == dim); |
| 1569 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 16 times.
|
72 | for (size_t i = 0; i < dim; ++i) { |
| 1570 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
56 | B.CreateStore(arg1[i+(i*dim)], ptrs[i]); |
| 1571 | } | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | 32 | return nullptr; | |
| 1575 | }; | ||
| 1576 | |||
| 1577 | 592 | static auto diag = [](auto result, const auto input) | |
| 1578 | { | ||
| 1579 | using ValueType = typename std::remove_pointer<decltype(input)>::type; | ||
| 1580 | using ResultType = typename std::remove_pointer<decltype(result)>::type; | ||
| 1581 | using ElementT = typename openvdb::ValueTraits<ValueType>::ElementType; | ||
| 1582 | using RElementT = typename openvdb::ValueTraits<ResultType>::ElementType; | ||
| 1583 | |||
| 1584 | static_assert(std::is_same<ElementT, RElementT>::value, | ||
| 1585 | "Input and result arguments for diag are not the same type"); | ||
| 1586 | |||
| 1587 | if (openvdb::ValueTraits<ValueType>::IsVec) { | ||
| 1588 | // input is a vec, result is a matrix | ||
| 1589 | const int size = openvdb::ValueTraits<ValueType>::Size; | ||
| 1590 | int element = 0; | ||
| 1591 |
2/2✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 296 times.
|
2664 | for (int i = 0; i < size; ++i) { |
| 1592 |
2/2✓ Branch 0 taken 3700 times.
✓ Branch 1 taken 1036 times.
|
9472 | for (int j = 0; j < size; ++j) { |
| 1593 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3700 times.
|
7400 | assert(element < openvdb::ValueTraits<ResultType>::Elements); |
| 1594 |
2/2✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 2664 times.
|
7400 | if (i == j) result->asPointer()[element] = (input->asPointer())[i]; |
| 1595 | 5328 | else result->asPointer()[element] = ElementT(0.0); | |
| 1596 | 7400 | ++element; | |
| 1597 | } | ||
| 1598 | } | ||
| 1599 | } | ||
| 1600 | else { | ||
| 1601 | assert(openvdb::ValueTraits<ValueType>::IsMat); | ||
| 1602 | // input is a matrix, result is a vec | ||
| 1603 | const int size = openvdb::ValueTraits<ValueType>::Size; | ||
| 1604 | for (int i = 0; i < size; ++i) { | ||
| 1605 | assert(i < openvdb::ValueTraits<ResultType>::Size); | ||
| 1606 | result->asPointer()[i] = input->asPointer()[i+(i*size)]; | ||
| 1607 | } | ||
| 1608 | } | ||
| 1609 | 592 | }; | |
| 1610 | |||
| 1611 | using DiagV3M3D = void(openvdb::math::Vec3<double>*, openvdb::math::Mat3<double>*); | ||
| 1612 | using DiagV3M3F = void(openvdb::math::Vec3<float>*, openvdb::math::Mat3<float>*); | ||
| 1613 | using DiagV4M4D = void(openvdb::math::Vec4<double>*, openvdb::math::Mat4<double>*); | ||
| 1614 | using DiagV4M4F = void(openvdb::math::Vec4<float>*, openvdb::math::Mat4<float>*); | ||
| 1615 | |||
| 1616 | using DiagM3V3D = void(openvdb::math::Mat3<double>*, openvdb::math::Vec3<double>*); | ||
| 1617 | using DiagM3V3F = void(openvdb::math::Mat3<float>*, openvdb::math::Vec3<float>*); | ||
| 1618 | using DiagM4V4D = void(openvdb::math::Mat4<double>*, openvdb::math::Vec4<double>*); | ||
| 1619 | using DiagM4V4F = void(openvdb::math::Mat4<float>*, openvdb::math::Vec4<float>*); | ||
| 1620 | |||
| 1621 | 13 | return FunctionBuilder("diag") | |
| 1622 | 26 | .addSignature<DiagV3M3D, true>(generate, (DiagV3M3D*)(diag)) | |
| 1623 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DiagV3M3F, true>(generate, (DiagV3M3F*)(diag)) |
| 1624 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DiagV4M4D, true>(generate, (DiagV4M4D*)(diag)) |
| 1625 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DiagV4M4F, true>(generate, (DiagV4M4F*)(diag)) |
| 1626 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"vec"}) |
| 1627 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 1628 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 1629 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 1630 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1631 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 1632 | 13 | .setConstantFold(op.mConstantFoldCBindings) | |
| 1633 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DiagM3V3D, true>(generate, (DiagM3V3D*)(diag)) |
| 1634 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DiagM3V3F, true>(generate, (DiagM3V3F*)(diag)) |
| 1635 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DiagM4V4D, true>(generate, (DiagM4V4D*)(diag)) |
| 1636 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<DiagM4V4F, true>(generate, (DiagM4V4F*)(diag)) |
| 1637 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"mat"}) |
| 1638 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 1639 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 1640 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 1641 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1642 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 1643 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1644 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1645 | .setDocumentation("Create a diagonal matrix from a vector, or return the diagonal " | ||
| 1646 | "components of a matrix as a vector.") | ||
| 1647 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1648 | } | ||
| 1649 | |||
| 1650 | 50 | inline FunctionGroup::UniquePtr axidentity3(const FunctionOptions& op) | |
| 1651 | { | ||
| 1652 | static auto generate = | ||
| 1653 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | [](const std::vector<llvm::Value*>& args, |
| 1654 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1655 | { | ||
| 1656 | std::vector<llvm::Value*> elements; | ||
| 1657 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | arrayUnpack(args[0], elements, B, /*load elements*/false); |
| 1658 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
|
49 | assert(elements.size() == 9); |
| 1659 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | llvm::Value* zero = LLVMType<float>::get(B.getContext(), 0.0f); |
| 1660 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | llvm::Value* one = LLVMType<float>::get(B.getContext(), 1.0f); |
| 1661 |
2/2✓ Branch 0 taken 441 times.
✓ Branch 1 taken 49 times.
|
490 | for (size_t i = 0; i < 9; ++i) { |
| 1662 |
4/4✓ Branch 0 taken 343 times.
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 294 times.
✓ Branch 3 taken 49 times.
|
441 | llvm::Value* m = ((i == 0 || i == 4 || i == 8) ? one : zero); |
| 1663 |
1/2✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
|
441 | B.CreateStore(m, elements[i]); |
| 1664 | } | ||
| 1665 | 49 | return nullptr; | |
| 1666 | }; | ||
| 1667 | |||
| 1668 | 50 | return FunctionBuilder("identity3") | |
| 1669 |
1/2✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
|
100 | .addSignature<void(openvdb::math::Mat3<float>*), true>(generate) |
| 1670 | .setConstantFold(false) | ||
| 1671 |
1/2✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
|
50 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1672 | 50 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1673 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 18 times.
|
50 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1674 | .setDocumentation("Returns the 3x3 identity matrix") | ||
| 1675 |
1/2✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
|
100 | .get(); |
| 1676 | } | ||
| 1677 | |||
| 1678 | 49 | inline FunctionGroup::UniquePtr axidentity4(const FunctionOptions& op) | |
| 1679 | { | ||
| 1680 | static auto generate = | ||
| 1681 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | [](const std::vector<llvm::Value*>& args, |
| 1682 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1683 | { | ||
| 1684 | std::vector<llvm::Value*> elements; | ||
| 1685 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | arrayUnpack(args[0], elements, B, /*load elements*/false); |
| 1686 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | assert(elements.size() == 16); |
| 1687 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | llvm::Value* zero = LLVMType<float>::get(B.getContext(), 0.0f); |
| 1688 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | llvm::Value* one = LLVMType<float>::get(B.getContext(), 1.0f); |
| 1689 |
2/2✓ Branch 0 taken 768 times.
✓ Branch 1 taken 48 times.
|
816 | for (size_t i = 0; i < 16; ++i) { |
| 1690 |
4/4✓ Branch 0 taken 672 times.
✓ Branch 1 taken 96 times.
✓ Branch 2 taken 576 times.
✓ Branch 3 taken 96 times.
|
768 | llvm::Value* m = ((i == 0 || i == 5 || i == 10 || i == 15) ? one : zero); |
| 1691 |
1/2✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
|
768 | B.CreateStore(m, elements[i]); |
| 1692 | } | ||
| 1693 | 48 | return nullptr; | |
| 1694 | }; | ||
| 1695 | |||
| 1696 | 49 | return FunctionBuilder("identity4") | |
| 1697 |
1/2✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
|
98 | .addSignature<void(openvdb::math::Mat4<float>*), true>(generate) |
| 1698 | .setConstantFold(false) | ||
| 1699 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
49 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1700 | 49 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 1701 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 17 times.
|
49 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1702 | .setDocumentation("Returns the 4x4 identity matrix") | ||
| 1703 |
1/2✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
|
98 | .get(); |
| 1704 | } | ||
| 1705 | |||
| 1706 | 37 | inline FunctionGroup::UniquePtr axmmmult(const FunctionOptions& op) | |
| 1707 | { | ||
| 1708 | static auto generate = | ||
| 1709 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | [](const std::vector<llvm::Value*>& args, |
| 1710 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1711 | { | ||
| 1712 | std::vector<llvm::Value*> ptrs, m1, m2; | ||
| 1713 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | arrayUnpack(args[0], ptrs, B, /*load*/false); |
| 1714 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | arrayUnpack(args[1], m1, B, /*load*/true); |
| 1715 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | arrayUnpack(args[2], m2, B, /*load*/true); |
| 1716 | |||
| 1717 |
3/4✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
|
48 | assert(m1.size() == 9 || m1.size() == 16); |
| 1718 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | assert(ptrs.size() == m1.size()); |
| 1719 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | assert(ptrs.size() == m2.size()); |
| 1720 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
|
48 | const size_t dim = m1.size() == 9 ? 3 : 4; |
| 1721 | |||
| 1722 | llvm::Value* e3 = nullptr, *e4 = nullptr; | ||
| 1723 |
2/2✓ Branch 0 taken 168 times.
✓ Branch 1 taken 48 times.
|
216 | for (size_t i = 0; i < dim; ++i) { |
| 1724 | 168 | const size_t row = i*dim; | |
| 1725 |
2/2✓ Branch 0 taken 600 times.
✓ Branch 1 taken 168 times.
|
768 | for (size_t j = 0; j < dim; ++j) { |
| 1726 |
1/2✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
|
600 | llvm::Value* e1 = binaryOperator(m1[0+row], m2[j], ast::tokens::MULTIPLY, B); |
| 1727 |
1/2✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
|
600 | llvm::Value* e2 = binaryOperator(m1[1+row], m2[dim+j], ast::tokens::MULTIPLY, B); |
| 1728 |
2/4✓ Branch 0 taken 600 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
|
600 | if (dim >=3) e3 = binaryOperator(m1[2+row], m2[(dim*2)+j], ast::tokens::MULTIPLY, B); |
| 1729 |
3/4✓ Branch 0 taken 384 times.
✓ Branch 1 taken 216 times.
✓ Branch 3 taken 384 times.
✗ Branch 4 not taken.
|
600 | if (dim >=4) e4 = binaryOperator(m1[3+row], m2[(dim*3)+j], ast::tokens::MULTIPLY, B); |
| 1730 |
1/2✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
|
600 | e1 = binaryOperator(e1, e2, ast::tokens::PLUS, B); |
| 1731 |
2/4✓ Branch 0 taken 600 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
|
600 | if (dim >=3) e1 = binaryOperator(e1, e3, ast::tokens::PLUS, B); |
| 1732 |
3/6✓ Branch 0 taken 384 times.
✓ Branch 1 taken 216 times.
✓ Branch 3 taken 384 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
600 | if (dim >=4) e1 = binaryOperator(e1, e4, ast::tokens::PLUS, B); |
| 1733 |
1/2✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
|
600 | B.CreateStore(e1, ptrs[row+j]); |
| 1734 | } | ||
| 1735 | } | ||
| 1736 | |||
| 1737 | 48 | return nullptr; | |
| 1738 | }; | ||
| 1739 | |||
| 1740 | static auto mmmult = [](auto out, auto mat2, auto mat1) { | ||
| 1741 | *out = (*mat1) * (*mat2); | ||
| 1742 | }; | ||
| 1743 | |||
| 1744 | using MMMultM3D = void(openvdb::math::Mat3<double>*, openvdb::math::Mat3<double>*, openvdb::math::Mat3<double>*); | ||
| 1745 | using MMMultM3F = void(openvdb::math::Mat3<float>*, openvdb::math::Mat3<float>*, openvdb::math::Mat3<float>*); | ||
| 1746 | using MMMultM4D = void(openvdb::math::Mat4<double>*, openvdb::math::Mat4<double>*, openvdb::math::Mat4<double>*); | ||
| 1747 | using MMMultM4F = void(openvdb::math::Mat4<float>*, openvdb::math::Mat4<float>*, openvdb::math::Mat4<float>*); | ||
| 1748 | |||
| 1749 | 37 | return FunctionBuilder("mmmult") | |
| 1750 | 74 | .addSignature<MMMultM3D, true>(generate, (MMMultM3D*)(mmmult)) | |
| 1751 |
1/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
74 | .addSignature<MMMultM3F, true>(generate, (MMMultM3F*)(mmmult)) |
| 1752 |
1/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
74 | .addSignature<MMMultM4D, true>(generate, (MMMultM4D*)(mmmult)) |
| 1753 |
1/4✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
74 | .addSignature<MMMultM4F, true>(generate, (MMMultM4F*)(mmmult)) |
| 1754 |
3/8✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
74 | .setArgumentNames({"a", "b"}) |
| 1755 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 1756 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 1757 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 1758 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | .addParameterAttribute(2, llvm::Attribute::ReadOnly) |
| 1759 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1760 | 37 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 1761 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
|
37 | .setConstantFold(op.mConstantFoldCBindings) |
| 1762 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
|
37 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1763 | .setDocumentation("Multiplies two matrices together and returns the result") | ||
| 1764 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
74 | .get(); |
| 1765 | } | ||
| 1766 | |||
| 1767 | 13 | inline FunctionGroup::UniquePtr axpolardecompose(const FunctionOptions& op) | |
| 1768 | { | ||
| 1769 | 25178154 | static auto polardecompose = [](auto in, auto orth, auto symm) -> bool { | |
| 1770 | bool success = false; | ||
| 1771 | try { | ||
| 1772 |
1/2✓ Branch 1 taken 12589077 times.
✗ Branch 2 not taken.
|
25178154 | success = openvdb::math::polarDecomposition(*in, *orth, *symm); |
| 1773 | } | ||
| 1774 | ✗ | catch (const openvdb::ArithmeticError&) { | |
| 1775 | success = false; | ||
| 1776 | } | ||
| 1777 | 25178154 | return success; | |
| 1778 | }; | ||
| 1779 | |||
| 1780 | using PolarDecompositionM3D = | ||
| 1781 | bool(openvdb::math::Mat3<double>*, | ||
| 1782 | openvdb::math::Mat3<double>*, | ||
| 1783 | openvdb::math::Mat3<double>*); | ||
| 1784 | using PolarDecompositionM3F = | ||
| 1785 | bool(openvdb::math::Mat3<float>*, | ||
| 1786 | openvdb::math::Mat3<float>*, | ||
| 1787 | openvdb::math::Mat3<float>*); | ||
| 1788 | |||
| 1789 | 13 | return FunctionBuilder("polardecompose") | |
| 1790 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<PolarDecompositionM3D>((PolarDecompositionM3D*)(polardecompose)) |
| 1791 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<PolarDecompositionM3F>((PolarDecompositionM3F*)(polardecompose)) |
| 1792 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"input", "unitary", "symmetric"}) |
| 1793 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 1794 | 13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) | |
| 1795 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1796 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1797 | .setDocumentation("Decompose an invertible 3x3 matrix into its orthogonal (unitary) " | ||
| 1798 | "matrix and symmetric matrix components. If the determinant of the unitary matrix " | ||
| 1799 | "is 1 it is a rotation, otherwise if it is -1 there is some part reflection.") | ||
| 1800 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1801 | } | ||
| 1802 | |||
| 1803 | 13 | inline FunctionGroup::UniquePtr axpostscale(const FunctionOptions& op) | |
| 1804 | { | ||
| 1805 | static auto generate = | ||
| 1806 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 1807 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1808 | { | ||
| 1809 | std::vector<llvm::Value*> m1, v1; | ||
| 1810 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[0], m1, B, /*load*/false); |
| 1811 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[1], v1, B, /*load*/true); |
| 1812 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(m1.size() == 16); |
| 1813 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | assert(v1.size() == 3); |
| 1814 | |||
| 1815 | // modify first 3 elements in all mat rows | ||
| 1816 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
|
40 | for (size_t row = 0; row < 4; ++row) { |
| 1817 |
2/2✓ Branch 0 taken 96 times.
✓ Branch 1 taken 32 times.
|
128 | for (size_t col = 0; col < 3; ++col) { |
| 1818 | 96 | const size_t idx = (row*4) + col; | |
| 1819 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
|
96 | assert(idx <= 14); |
| 1820 |
1/2✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
96 | llvm::Value* m1v = B.CreateLoad(m1[idx]); |
| 1821 |
2/6✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
96 | m1v = binaryOperator(m1v, v1[col], ast::tokens::MULTIPLY, B); |
| 1822 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | B.CreateStore(m1v, m1[idx]); |
| 1823 | } | ||
| 1824 | } | ||
| 1825 | |||
| 1826 | // @warning this is invalid for embedded IR | ||
| 1827 | 8 | return nullptr; | |
| 1828 | }; | ||
| 1829 | |||
| 1830 | static auto postscale = [](auto mat, auto vec) { | ||
| 1831 | mat->postScale(*vec); | ||
| 1832 | }; | ||
| 1833 | |||
| 1834 | using PostscaleM4D = void(openvdb::math::Mat4<double>*, openvdb::math::Vec3<double>*); | ||
| 1835 | using PostscaleM4F = void(openvdb::math::Mat4<float>*, openvdb::math::Vec3<float>*); | ||
| 1836 | |||
| 1837 | 13 | return FunctionBuilder("postscale") | |
| 1838 | 26 | .addSignature<PostscaleM4D>(generate, (PostscaleM4D*)(postscale)) | |
| 1839 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<PostscaleM4F>(generate, (PostscaleM4F*)(postscale)) |
| 1840 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"transform", "vec"}) |
| 1841 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 1842 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1843 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 1844 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1845 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1846 | .setDocumentation("Post-scale a given matrix by the provided vector.") | ||
| 1847 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1848 | } | ||
| 1849 | |||
| 1850 | 13 | inline FunctionGroup::UniquePtr axpretransform(const FunctionOptions& op) | |
| 1851 | { | ||
| 1852 | static auto generate = | ||
| 1853 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | [](const std::vector<llvm::Value*>& args, |
| 1854 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1855 | { | ||
| 1856 | std::vector<llvm::Value*> ptrs, m1, v1; | ||
| 1857 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[0], ptrs, B, /*load*/false); |
| 1858 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[1], m1, B, /*load*/true); |
| 1859 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[2], v1, B, /*load*/true); |
| 1860 | |||
| 1861 | const size_t vec = v1.size(); | ||
| 1862 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
|
12 | const size_t dim = (m1.size() == 9 ? 3 : 4); |
| 1863 | |||
| 1864 |
3/4✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
12 | assert(m1.size() == 9 || m1.size() == 16); |
| 1865 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | assert(vec == 3 || vec == 4); |
| 1866 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | assert(ptrs.size() == vec); |
| 1867 | |||
| 1868 | // mat * vec | ||
| 1869 | llvm::Value* e3 = nullptr, *e4 = nullptr; | ||
| 1870 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 12 times.
|
52 | for (size_t i = 0; i < vec; ++i) { |
| 1871 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* e1 = binaryOperator(v1[0], m1[0+(i*dim)], ast::tokens::MULTIPLY, B); |
| 1872 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* e2 = binaryOperator(v1[1], m1[1+(i*dim)], ast::tokens::MULTIPLY, B); |
| 1873 |
2/4✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | if (dim >= 3) e3 = binaryOperator(v1[2], m1[2+(i*dim)], ast::tokens::MULTIPLY, B); |
| 1874 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
|
40 | if (dim == 4) { |
| 1875 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
|
28 | if (vec == 3) e4 = m1[3+(i*dim)]; |
| 1876 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | else if (vec == 4) e4 = binaryOperator(v1[3], m1[3+(i*dim)], ast::tokens::MULTIPLY, B); |
| 1877 | } | ||
| 1878 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | e1 = binaryOperator(e1, e2, ast::tokens::PLUS, B); |
| 1879 |
2/4✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | if (e3) e1 = binaryOperator(e1, e3, ast::tokens::PLUS, B); |
| 1880 |
3/6✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
40 | if (e4) e1 = binaryOperator(e1, e4, ast::tokens::PLUS, B); |
| 1881 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | B.CreateStore(e1, ptrs[i]); |
| 1882 | } | ||
| 1883 | |||
| 1884 | 12 | return nullptr; | |
| 1885 | }; | ||
| 1886 | |||
| 1887 | static auto transform = [](auto out, auto mat, auto vec) { | ||
| 1888 | *out = mat->pretransform(*vec); | ||
| 1889 | }; | ||
| 1890 | |||
| 1891 | using PretransformM3DV3D = void(openvdb::math::Vec3<double>*, openvdb::math::Mat3<double>*, openvdb::math::Vec3<double>*); | ||
| 1892 | using PretransformM3FV3F = void(openvdb::math::Vec3<float>*, openvdb::math::Mat3<float>*, openvdb::math::Vec3<float>*); | ||
| 1893 | using PretransformM4DV3D = void(openvdb::math::Vec3<double>*, openvdb::math::Mat4<double>*, openvdb::math::Vec3<double>*); | ||
| 1894 | using PretransformM4FV3F = void(openvdb::math::Vec3<float>*, openvdb::math::Mat4<float>*, openvdb::math::Vec3<float>*); | ||
| 1895 | using PretransformM4DV4D = void(openvdb::math::Vec4<double>*, openvdb::math::Mat4<double>*, openvdb::math::Vec4<double>*); | ||
| 1896 | using PretransformM4FV4F = void(openvdb::math::Vec4<float>*, openvdb::math::Mat4<float>*, openvdb::math::Vec4<float>*); | ||
| 1897 | |||
| 1898 | 13 | return FunctionBuilder("pretransform") | |
| 1899 | 26 | .addSignature<PretransformM3DV3D, true>(generate, (PretransformM3DV3D*)(transform)) | |
| 1900 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<PretransformM3FV3F, true>(generate, (PretransformM3FV3F*)(transform)) |
| 1901 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<PretransformM4DV3D, true>(generate, (PretransformM4DV3D*)(transform)) |
| 1902 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<PretransformM4FV3F, true>(generate, (PretransformM4FV3F*)(transform)) |
| 1903 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<PretransformM4DV4D, true>(generate, (PretransformM4DV4D*)(transform)) |
| 1904 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<PretransformM4FV4F, true>(generate, (PretransformM4FV4F*)(transform)) |
| 1905 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"vec", "mat"}) |
| 1906 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias |
| 1907 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 1908 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 1909 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(2, llvm::Attribute::ReadOnly) |
| 1910 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1911 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 1912 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1913 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1914 | .setDocumentation("Return the transformed vector by transpose of this matrix. " | ||
| 1915 | "This function is equivalent to pre-multiplying the matrix.") | ||
| 1916 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1917 | } | ||
| 1918 | |||
| 1919 | 13 | inline FunctionGroup::UniquePtr axprescale(const FunctionOptions& op) | |
| 1920 | { | ||
| 1921 | static auto generate = | ||
| 1922 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 1923 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1924 | { | ||
| 1925 | std::vector<llvm::Value*> m1, v1; | ||
| 1926 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[0], m1, B, /*load*/false); |
| 1927 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[1], v1, B, /*load*/true); |
| 1928 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(m1.size() == 16); |
| 1929 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | assert(v1.size() == 3); |
| 1930 | |||
| 1931 | // modify first 3 mat rows, all columns | ||
| 1932 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
|
32 | for (size_t row = 0; row < 3; ++row) { |
| 1933 |
2/2✓ Branch 0 taken 96 times.
✓ Branch 1 taken 24 times.
|
120 | for (size_t col = 0; col < 4; ++col) { |
| 1934 | 96 | const size_t idx = (row*4) + col; | |
| 1935 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
|
96 | assert(idx <= 11); |
| 1936 |
1/2✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
96 | llvm::Value* m1v = B.CreateLoad(m1[idx]); |
| 1937 |
2/6✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
96 | m1v = binaryOperator(m1v, v1[row], ast::tokens::MULTIPLY, B); |
| 1938 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | B.CreateStore(m1v, m1[idx]); |
| 1939 | } | ||
| 1940 | } | ||
| 1941 | // @warning this is invalid for embedded IR | ||
| 1942 | 8 | return nullptr; | |
| 1943 | }; | ||
| 1944 | |||
| 1945 | static auto prescale = [](auto mat, auto vec) { | ||
| 1946 | mat->preScale(*vec); | ||
| 1947 | }; | ||
| 1948 | |||
| 1949 | using PrescaleM4D = void(openvdb::math::Mat4<double>*, openvdb::math::Vec3<double>*); | ||
| 1950 | using PrescaleM4F = void(openvdb::math::Mat4<float>*, openvdb::math::Vec3<float>*); | ||
| 1951 | |||
| 1952 | 13 | return FunctionBuilder("prescale") | |
| 1953 | 26 | .addSignature<PrescaleM4D>(generate, (PrescaleM4D*)(prescale)) | |
| 1954 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<PrescaleM4F>(generate, (PrescaleM4F*)(prescale)) |
| 1955 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"transform", "vec"}) |
| 1956 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 1957 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 1958 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 1959 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 1960 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 1961 | .setDocumentation("Pre-scale a given matrix by the provided vector.") | ||
| 1962 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 1963 | } | ||
| 1964 | |||
| 1965 | 13 | inline FunctionGroup::UniquePtr axtrace(const FunctionOptions& op) | |
| 1966 | { | ||
| 1967 | static auto generate = | ||
| 1968 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 1969 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 1970 | { | ||
| 1971 | std::vector<llvm::Value*> m1; | ||
| 1972 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[0], m1, B, /*load*/true); |
| 1973 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | const size_t dim = (m1.size() == 9 ? 3 : 4); |
| 1974 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
8 | assert(m1.size() == 9 || m1.size() == 16); |
| 1975 | |||
| 1976 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* result = binaryOperator(m1[0], m1[1+dim], ast::tokens::PLUS, B); |
| 1977 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | result = binaryOperator(result, m1[2+(2*dim)], ast::tokens::PLUS, B); |
| 1978 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (dim == 4) { |
| 1979 | ✗ | result = binaryOperator(result, m1[3+(3*dim)], ast::tokens::PLUS, B); | |
| 1980 | } | ||
| 1981 | |||
| 1982 | 8 | return result; | |
| 1983 | }; | ||
| 1984 | |||
| 1985 | static auto trace = [](const auto input) -> auto | ||
| 1986 | { | ||
| 1987 | using MatType = typename std::remove_pointer<decltype(input)>::type; | ||
| 1988 | using ElementT = typename openvdb::ValueTraits<MatType>::ElementType; | ||
| 1989 | ElementT value((*input)(static_cast<int>(0), static_cast<int>(0))); | ||
| 1990 | for (size_t i = 1; i < MatType::numRows(); ++i) { | ||
| 1991 | value += (*input)(static_cast<int>(i), static_cast<int>(i)); | ||
| 1992 | } | ||
| 1993 | return value; | ||
| 1994 | }; | ||
| 1995 | |||
| 1996 | using TraceM3D = double(openvdb::math::Mat3<double>*); | ||
| 1997 | using TraceM3F = float(openvdb::math::Mat3<float>*); | ||
| 1998 | using TraceM4D = double(openvdb::math::Mat4<double>*); | ||
| 1999 | using TraceM4F = float(openvdb::math::Mat4<float>*); | ||
| 2000 | |||
| 2001 | 13 | return FunctionBuilder("trace") | |
| 2002 | 26 | .addSignature<TraceM3D>(generate, (TraceM3D*)(trace)) | |
| 2003 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TraceM3F>(generate, (TraceM3F*)(trace)) |
| 2004 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TraceM4D>(generate, (TraceM4D*)(trace)) |
| 2005 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TraceM4F>(generate, (TraceM4F*)(trace)) |
| 2006 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"mat"}) |
| 2007 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 2008 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2009 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 2010 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2011 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2012 | .setDocumentation("Return the trace of a matrix, the sum of the diagonal elements.") | ||
| 2013 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2014 | } | ||
| 2015 | |||
| 2016 | 13 | inline FunctionGroup::UniquePtr axtransform(const FunctionOptions& op) | |
| 2017 | { | ||
| 2018 | static auto generate = | ||
| 2019 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | [](const std::vector<llvm::Value*>& args, |
| 2020 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2021 | { | ||
| 2022 | std::vector<llvm::Value*> ptrs, m1, v1; | ||
| 2023 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[0], ptrs, B, /*load*/false); |
| 2024 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[1], v1, B, /*load*/true); |
| 2025 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[2], m1, B, /*load*/true); |
| 2026 | |||
| 2027 | const size_t vec = v1.size(); | ||
| 2028 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
|
12 | const size_t dim = (m1.size() == 9 ? 3 : 4); |
| 2029 | |||
| 2030 |
3/4✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
12 | assert(m1.size() == 9 || m1.size() == 16); |
| 2031 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | assert(vec == 3 || vec == 4); |
| 2032 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | assert(ptrs.size() == vec); |
| 2033 | |||
| 2034 | // vec * mat | ||
| 2035 | llvm::Value* e3 = nullptr, *e4 = nullptr; | ||
| 2036 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 12 times.
|
52 | for (size_t i = 0; i < vec; ++i) { |
| 2037 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* e1 = binaryOperator(v1[0], m1[i+(0*dim)], ast::tokens::MULTIPLY, B); |
| 2038 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | llvm::Value* e2 = binaryOperator(v1[1], m1[i+(1*dim)], ast::tokens::MULTIPLY, B); |
| 2039 |
2/4✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | if (dim >= 3) e3 = binaryOperator(v1[2], m1[i+(2*dim)], ast::tokens::MULTIPLY, B); |
| 2040 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
|
40 | if (dim == 4) { |
| 2041 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
|
28 | if (vec == 3) e4 = m1[i+(3*dim)]; |
| 2042 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | else if (vec == 4) e4 = binaryOperator(v1[3], m1[i+(3*dim)], ast::tokens::MULTIPLY, B); |
| 2043 | } | ||
| 2044 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | e1 = binaryOperator(e1, e2, ast::tokens::PLUS, B); |
| 2045 |
2/4✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
40 | if (e3) e1 = binaryOperator(e1, e3, ast::tokens::PLUS, B); |
| 2046 |
3/6✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
40 | if (e4) e1 = binaryOperator(e1, e4, ast::tokens::PLUS, B); |
| 2047 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | B.CreateStore(e1, ptrs[i]); |
| 2048 | } | ||
| 2049 | |||
| 2050 | 12 | return nullptr; | |
| 2051 | }; | ||
| 2052 | |||
| 2053 | static auto transform = [](auto out, auto vec, auto mat) { | ||
| 2054 | *out = mat->transform(*vec); | ||
| 2055 | }; | ||
| 2056 | |||
| 2057 | using TransformV3DM3D = void(openvdb::math::Vec3<double>*, openvdb::math::Vec3<double>*, openvdb::math::Mat3<double>*); | ||
| 2058 | using TransformV3FM3F = void(openvdb::math::Vec3<float>*, openvdb::math::Vec3<float>*, openvdb::math::Mat3<float>*); | ||
| 2059 | using TransformV3DM4D = void(openvdb::math::Vec3<double>*, openvdb::math::Vec3<double>*, openvdb::math::Mat4<double>*); | ||
| 2060 | using TransformV3FM4F = void(openvdb::math::Vec3<float>*, openvdb::math::Vec3<float>*, openvdb::math::Mat4<float>*); | ||
| 2061 | using TransformV4DM4D = void(openvdb::math::Vec4<double>*, openvdb::math::Vec4<double>*, openvdb::math::Mat4<double>*); | ||
| 2062 | using TransformV4FM4F = void(openvdb::math::Vec4<float>*, openvdb::math::Vec4<float>*, openvdb::math::Mat4<float>*); | ||
| 2063 | |||
| 2064 | 13 | return FunctionBuilder("transform") | |
| 2065 | 26 | .addSignature<TransformV3DM3D, true>(generate, (TransformV3DM3D*)(transform)) | |
| 2066 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TransformV3FM3F, true>(generate, (TransformV3FM3F*)(transform)) |
| 2067 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TransformV3DM4D, true>(generate, (TransformV3DM4D*)(transform)) |
| 2068 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TransformV3FM4F, true>(generate, (TransformV3FM4F*)(transform)) |
| 2069 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TransformV4DM4D, true>(generate, (TransformV4DM4D*)(transform)) |
| 2070 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TransformV4FM4F, true>(generate, (TransformV4FM4F*)(transform)) |
| 2071 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"vec", "mat"}) |
| 2072 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias |
| 2073 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 2074 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2075 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(2, llvm::Attribute::ReadOnly) |
| 2076 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2077 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 2078 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2079 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2080 | .setDocumentation("Return the transformed vector by the provided " | ||
| 2081 | "matrix. This function is equivalent to post-multiplying the matrix, i.e. vec * mult.") | ||
| 2082 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2083 | } | ||
| 2084 | |||
| 2085 | 13 | inline FunctionGroup::UniquePtr axtranspose(const FunctionOptions& op) | |
| 2086 | { | ||
| 2087 | static auto generate = | ||
| 2088 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | [](const std::vector<llvm::Value*>& args, |
| 2089 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2090 | { | ||
| 2091 | std::vector<llvm::Value*> ptrs, m1; | ||
| 2092 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | arrayUnpack(args[0], ptrs, B, /*load*/false); |
| 2093 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | arrayUnpack(args[1], m1, B, /*load*/true); |
| 2094 |
3/4✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
16 | assert(m1.size() == 9 || m1.size() == 16); |
| 2095 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | assert(ptrs.size() == m1.size()); |
| 2096 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | const size_t dim = m1.size() == 9 ? 3 : 4; |
| 2097 | |||
| 2098 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 16 times.
|
72 | for (size_t i = 0; i < dim; ++i) { |
| 2099 |
2/2✓ Branch 0 taken 200 times.
✓ Branch 1 taken 56 times.
|
256 | for (size_t j = 0; j < dim; ++j) { |
| 2100 | 200 | const size_t source = (i*dim) + j; | |
| 2101 |
1/2✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
|
200 | const size_t target = (j*dim) + i; |
| 2102 |
1/2✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
|
200 | B.CreateStore(m1[source], ptrs[target]); |
| 2103 | } | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | 16 | return nullptr; | |
| 2107 | }; | ||
| 2108 | |||
| 2109 | 336 | static auto transpose = [](auto out, auto in) { | |
| 2110 | 336 | *out = in->transpose(); | |
| 2111 | 336 | }; | |
| 2112 | |||
| 2113 | using TransposeM3D = void(openvdb::math::Mat3<double>*, openvdb::math::Mat3<double>*); | ||
| 2114 | using TransposeM3F = void(openvdb::math::Mat3<float>*, openvdb::math::Mat3<float>*); | ||
| 2115 | using TransposeM4D = void(openvdb::math::Mat4<double>*, openvdb::math::Mat4<double>*); | ||
| 2116 | using TransposeM4F = void(openvdb::math::Mat4<float>*, openvdb::math::Mat4<float>*); | ||
| 2117 | |||
| 2118 | 13 | return FunctionBuilder("transpose") | |
| 2119 | 26 | .addSignature<TransposeM3D, true>(generate, (TransposeM3D*)(transpose)) | |
| 2120 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TransposeM3F, true>(generate, (TransposeM3F*)(transpose)) |
| 2121 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TransposeM4D, true>(generate, (TransposeM4D*)(transpose)) |
| 2122 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<TransposeM4F, true>(generate, (TransposeM4F*)(transpose)) |
| 2123 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"mat"}) |
| 2124 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias |
| 2125 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 2126 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2127 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2128 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 2129 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2130 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2131 | .setDocumentation("Returns the transpose of a matrix") | ||
| 2132 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2133 | } | ||
| 2134 | |||
| 2135 | 33 | inline FunctionGroup::UniquePtr axadjoint(const FunctionOptions& op) | |
| 2136 | { | ||
| 2137 | static auto generate = | ||
| 2138 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | [](const std::vector<llvm::Value*>& args, |
| 2139 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2140 | { | ||
| 2141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | assert(args.size() == 2); |
| 2142 | std::vector<llvm::Value*> m1, m2; | ||
| 2143 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | arrayUnpack(args[1], m1, B, /*load*/true); |
| 2144 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | arrayUnpack(args[0], m2, B, /*load*/false); // args[0] is return type |
| 2145 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
16 | assert(m1.size() == 9 && m2.size() == 9); |
| 2146 | |||
| 2147 | 144 | auto mul_sub = [&](const size_t a, const size_t b, const size_t c, const size_t d) { | |
| 2148 |
3/6✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 144 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 144 times.
✗ Branch 8 not taken.
|
144 | return binaryOperator( |
| 2149 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
144 | binaryOperator(m1[a], m1[b], ast::tokens::MULTIPLY, B), |
| 2150 | 288 | binaryOperator(m1[c], m1[d], ast::tokens::MULTIPLY, B), | |
| 2151 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
288 | ast::tokens::MINUS, B); |
| 2152 | 16 | }; | |
| 2153 | |||
| 2154 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(4,8, 5,7), m2[0]); |
| 2155 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(2,7, 1,8), m2[1]); |
| 2156 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(1,5, 2,4), m2[2]); |
| 2157 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(5,6, 3,8), m2[3]); |
| 2158 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(0,8, 2,6), m2[4]); |
| 2159 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(2,3, 0,5), m2[5]); |
| 2160 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(3,7, 4,6), m2[6]); |
| 2161 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(1,6, 0,7), m2[7]); |
| 2162 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
16 | B.CreateStore(mul_sub(0,4, 1,3), m2[8]); |
| 2163 | 16 | return nullptr; | |
| 2164 | }; | ||
| 2165 | |||
| 2166 | static auto adjoint = [](auto out, const auto in) { | ||
| 2167 | *out = in->adjoint(); | ||
| 2168 | }; | ||
| 2169 | |||
| 2170 | using AdjointM3D = | ||
| 2171 | void(openvdb::math::Mat3<double>*, | ||
| 2172 | openvdb::math::Mat3<double>*); | ||
| 2173 | using AjointM3F = | ||
| 2174 | void(openvdb::math::Mat3<float>*, | ||
| 2175 | openvdb::math::Mat3<float>*); | ||
| 2176 | |||
| 2177 | 33 | return FunctionBuilder("adjoint") | |
| 2178 | 66 | .addSignature<AdjointM3D, true>(generate, (AdjointM3D*)(adjoint)) | |
| 2179 |
1/4✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
66 | .addSignature<AjointM3F, true>(generate, (AjointM3F*)(adjoint)) |
| 2180 |
3/8✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 33 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
66 | .setArgumentNames({"input"} ) |
| 2181 |
1/2✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
|
33 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 2182 |
1/2✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
|
33 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2183 |
1/2✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
|
33 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2184 | 33 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2185 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 17 times.
|
33 | .setConstantFold(op.mConstantFoldCBindings) |
| 2186 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 17 times.
|
33 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2187 | .setDocumentation("Returns the adjoint of a 3x3 matrix. That is, " | ||
| 2188 | "the transpose of its cofactor matrix.") | ||
| 2189 |
1/2✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
|
66 | .get(); |
| 2190 | } | ||
| 2191 | |||
| 2192 | 13 | inline FunctionGroup::UniquePtr axcofactor(const FunctionOptions& op) | |
| 2193 | { | ||
| 2194 | static auto generate = | ||
| 2195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | [](const std::vector<llvm::Value*>& args, |
| 2196 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2197 | { | ||
| 2198 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(args.size() == 2); |
| 2199 | std::vector<llvm::Value*> m1, m2; | ||
| 2200 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[1], m1, B, /*load*/true); |
| 2201 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[0], m2, B, /*load*/false); // args[0] is return type |
| 2202 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
8 | assert(m1.size() == 9 && m2.size() == 9); |
| 2203 | |||
| 2204 | 72 | auto mul_sub = [&](const size_t a, const size_t b, const size_t c, const size_t d) { | |
| 2205 |
3/6✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 72 times.
✗ Branch 8 not taken.
|
72 | return binaryOperator( |
| 2206 |
1/2✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
|
72 | binaryOperator(m1[a], m1[b], ast::tokens::MULTIPLY, B), |
| 2207 | 144 | binaryOperator(m1[c], m1[d], ast::tokens::MULTIPLY, B), | |
| 2208 |
1/2✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
|
144 | ast::tokens::MINUS, B); |
| 2209 | 8 | }; | |
| 2210 | |||
| 2211 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(4,8, 5,7), m2[0]); |
| 2212 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(5,6, 3,8), m2[1]); |
| 2213 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(3,7, 4,6), m2[2]); |
| 2214 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(2,7, 1,8), m2[3]); |
| 2215 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(0,8, 2,6), m2[4]); |
| 2216 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(1,6, 0,7), m2[5]); |
| 2217 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(1,5, 2,4), m2[6]); |
| 2218 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(2,3, 0,5), m2[7]); |
| 2219 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | B.CreateStore(mul_sub(0,4, 1,3), m2[8]); |
| 2220 | 8 | return nullptr; | |
| 2221 | }; | ||
| 2222 | |||
| 2223 | static auto cofactor = [](auto out, const auto in) { | ||
| 2224 | *out = in->cofactor(); | ||
| 2225 | }; | ||
| 2226 | |||
| 2227 | using CofactorM3D = | ||
| 2228 | void(openvdb::math::Mat3<double>*, | ||
| 2229 | openvdb::math::Mat3<double>*); | ||
| 2230 | using CofactorM3F = | ||
| 2231 | void(openvdb::math::Mat3<float>*, | ||
| 2232 | openvdb::math::Mat3<float>*); | ||
| 2233 | |||
| 2234 | 13 | return FunctionBuilder("cofactor") | |
| 2235 | 26 | .addSignature<CofactorM3D, true>(generate, (CofactorM3D*)(cofactor)) | |
| 2236 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<CofactorM3F, true>(generate, (CofactorM3F*)(cofactor)) |
| 2237 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"input"} ) |
| 2238 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 2239 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2240 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2241 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2242 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2243 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2244 | .setDocumentation("Returns the cofactor matrix of a 3x3 matrix. That is, " | ||
| 2245 | "the matrix of its cofactors.") | ||
| 2246 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2247 | } | ||
| 2248 | |||
| 2249 | 13 | inline FunctionGroup::UniquePtr axinverse(const FunctionOptions& op) | |
| 2250 | { | ||
| 2251 | auto generate = | ||
| 2252 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | [op](const std::vector<llvm::Value*>& args, |
| 2253 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2254 | { | ||
| 2255 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(args.size() == 2); |
| 2256 | |||
| 2257 |
3/6✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
|
16 | llvm::Value* adj = axadjoint(op)->execute({args[1]}, B); |
| 2258 | std::vector<llvm::Value*> m1, madj; | ||
| 2259 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(adj, madj, B, /*load*/true); |
| 2260 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[0], m1, B, /*load*/false); // result |
| 2261 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
8 | assert(madj.size() == 9 && m1.size() == 9); |
| 2262 | |||
| 2263 | // compute determinant of the input mat by reusing the adjoint's 0, 3 and 6 terms | ||
| 2264 |
2/4✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
|
8 | llvm::Value* m20 = B.CreateLoad(B.CreateConstGEP2_64(args[1], 0, 0)); |
| 2265 |
2/4✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
|
8 | llvm::Value* m23 = B.CreateLoad(B.CreateConstGEP2_64(args[1], 0, 3)); |
| 2266 |
2/4✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
|
8 | llvm::Value* m26 = B.CreateLoad(B.CreateConstGEP2_64(args[1], 0, 6)); |
| 2267 | |||
| 2268 | // compute det and store in c0 | ||
| 2269 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* c0 = binaryOperator(madj[0], m20, ast::tokens::MULTIPLY, B); |
| 2270 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* c1 = binaryOperator(madj[1], m23, ast::tokens::MULTIPLY, B); |
| 2271 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* c2 = binaryOperator(madj[2], m26, ast::tokens::MULTIPLY, B); |
| 2272 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | c0 = binaryOperator(c0, c1, ast::tokens::PLUS, B); |
| 2273 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | c0 = binaryOperator(c0, c2, ast::tokens::PLUS, B); |
| 2274 | |||
| 2275 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* zero = llvm::ConstantFP::get(c0->getType(), 0.0); |
| 2276 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* detisnotzero = binaryOperator(c0, zero, ast::tokens::NOTEQUALS, B); |
| 2277 | |||
| 2278 | llvm::Function* base = B.GetInsertBlock()->getParent(); | ||
| 2279 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | llvm::BasicBlock* then = llvm::BasicBlock::Create(B.getContext(), "then", base); |
| 2280 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | llvm::BasicBlock* post = llvm::BasicBlock::Create(B.getContext(), "post", base); |
| 2281 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | B.CreateCondBr(detisnotzero, then, post); |
| 2282 | |||
| 2283 | B.SetInsertPoint(then); | ||
| 2284 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | llvm::Value* one = llvm::ConstantFP::get(c0->getType(), 1.0); |
| 2285 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | c0 = B.CreateFDiv(one, c0); |
| 2286 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 8 times.
|
80 | for (size_t i = 0; i < 9; ++i) { |
| 2287 |
2/6✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
72 | B.CreateStore(binaryOperator(madj[i], c0, ast::tokens::MULTIPLY, B), m1[i]); |
| 2288 | } | ||
| 2289 | |||
| 2290 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | B.CreateRetVoid(); |
| 2291 | |||
| 2292 | B.SetInsertPoint(post); | ||
| 2293 | |||
| 2294 | madj.clear(); | ||
| 2295 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | arrayUnpack(args[1], madj, B, /*load*/true); |
| 2296 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 8 times.
|
80 | for (size_t i = 0; i < 9; ++i) { |
| 2297 |
1/2✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
|
72 | B.CreateStore(madj[i], m1[i]); |
| 2298 | } | ||
| 2299 | |||
| 2300 | 8 | return nullptr; | |
| 2301 | 13 | }; | |
| 2302 | |||
| 2303 | 336 | static auto inverse = [](auto out, const auto in) { | |
| 2304 | try { | ||
| 2305 |
2/2✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
|
336 | *out = in->inverse(); |
| 2306 | } | ||
| 2307 | 168 | catch (const openvdb::ArithmeticError&) { | |
| 2308 | 168 | *out = *in; | |
| 2309 | } | ||
| 2310 | 336 | }; | |
| 2311 | |||
| 2312 | using InverseM3D = | ||
| 2313 | void(openvdb::math::Mat3<double>*, | ||
| 2314 | openvdb::math::Mat3<double>*); | ||
| 2315 | using InverseM3F = | ||
| 2316 | void(openvdb::math::Mat3<float>*, | ||
| 2317 | openvdb::math::Mat3<float>*); | ||
| 2318 | |||
| 2319 | 13 | return FunctionBuilder("inverse") | |
| 2320 | 26 | .addSignature<InverseM3D, true>(generate, (InverseM3D*)(inverse)) | |
| 2321 |
1/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
26 | .addSignature<InverseM3F, true>(generate, (InverseM3F*)(inverse)) |
| 2322 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"input"} ) |
| 2323 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("adjoint") |
| 2324 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 2325 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2326 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2327 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2328 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2329 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2330 | .setDocumentation("Return the inverse of a 3x3 matrix." | ||
| 2331 | "If the matrix is singular, returns the input matrix.") | ||
| 2332 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2333 | } | ||
| 2334 | |||
| 2335 | /////////////////////////////////////////////////////////////////////////// | ||
| 2336 | /////////////////////////////////////////////////////////////////////////// | ||
| 2337 | |||
| 2338 | // Noise | ||
| 2339 | |||
| 2340 | 13 | inline FunctionGroup::UniquePtr axsimplexnoise(const FunctionOptions& op) | |
| 2341 | { | ||
| 2342 | static auto simplexnoisex = [](double x) -> double { | ||
| 2343 | return SimplexNoise::noise(x, 0.0, 0.0); | ||
| 2344 | }; | ||
| 2345 | static auto simplexnoisexy = [](double x, double y) -> double { | ||
| 2346 | return SimplexNoise::noise(x, y, 0.0); | ||
| 2347 | }; | ||
| 2348 | static auto simplexnoisexyz = [](double x, double y, double z) -> double { | ||
| 2349 | return SimplexNoise::noise(x, y, z); | ||
| 2350 | }; | ||
| 2351 | static auto simplexnoisev = [](const openvdb::math::Vec3<double>* v) -> double { | ||
| 2352 | return SimplexNoise::noise((*v)[0], (*v)[1], (*v)[2]); | ||
| 2353 | }; | ||
| 2354 | |||
| 2355 | 13 | return FunctionBuilder("simplexnoise") | |
| 2356 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double(double)>(simplexnoisex) |
| 2357 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"x"}) |
| 2358 | .setConstantFold(false) | ||
| 2359 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double(double, double)>(simplexnoisexy) |
| 2360 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"x", "y"}) |
| 2361 | .setConstantFold(false) | ||
| 2362 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double(double,double,double)>(simplexnoisexyz) |
| 2363 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"x", "y", "z"}) |
| 2364 | .setConstantFold(false) | ||
| 2365 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double(const openvdb::math::Vec3<double>*)>(simplexnoisev) |
| 2366 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"pos"}) |
| 2367 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 2368 | .setConstantFold(false) | ||
| 2369 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2370 | .setDocumentation("Compute simplex noise at coordinates x, y and z. Coordinates which are " | ||
| 2371 | "not provided will be set to 0.") | ||
| 2372 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2373 | } | ||
| 2374 | |||
| 2375 | 13 | inline FunctionGroup::UniquePtr axcurlsimplexnoise(const FunctionOptions& op) | |
| 2376 | { | ||
| 2377 | using CurlSimplexNoiseV3D = void(double(*)[3], const double(*)[3]); | ||
| 2378 | using CurlSimplexNoiseD = void(double(*)[3], double, double, double); | ||
| 2379 | |||
| 2380 | 13 | return FunctionBuilder("curlsimplexnoise") | |
| 2381 | .addSignature<CurlSimplexNoiseV3D, true>( | ||
| 2382 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | (CurlSimplexNoiseV3D*)(openvdb::ax::math::curlnoise<SimplexNoise>)) |
| 2383 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"pos"}) |
| 2384 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias |
| 2385 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 2386 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2387 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2388 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 2389 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2390 | .addSignature<CurlSimplexNoiseD, true>( | ||
| 2391 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | (CurlSimplexNoiseD*)(openvdb::ax::math::curlnoise<SimplexNoise>)) |
| 2392 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"pos"}) |
| 2393 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias |
| 2394 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 2395 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2396 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 2397 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2398 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2399 | .setDocumentation("Generates divergence-free 3D noise, computed using a " | ||
| 2400 | "curl function on Simplex Noise.") | ||
| 2401 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2402 | } | ||
| 2403 | |||
| 2404 | |||
| 2405 | /////////////////////////////////////////////////////////////////////////// | ||
| 2406 | /////////////////////////////////////////////////////////////////////////// | ||
| 2407 | |||
| 2408 | // Trig/Hyperbolic | ||
| 2409 | |||
| 2410 | /// @todo Depending on the platform, some of these methods may be available though | ||
| 2411 | /// LLVM as "intrinsics". To avoid conflicts, we currently only expose the C | ||
| 2412 | /// bindings. We should perhaps override the C Bindings if the method exists | ||
| 2413 | /// in LLVM, so long as it's clear that these methods may produce different | ||
| 2414 | /// results from stdlib. | ||
| 2415 | /// @note See the following LLVM files for some details: | ||
| 2416 | /// Analysis/TargetLibraryInfo.def | ||
| 2417 | /// Analysis/ConstantFolding.cpp | ||
| 2418 | /// Analysis/TargetLibraryInfo.cpp | ||
| 2419 | /// | ||
| 2420 |
10/18✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
|
47 | DEFINE_AX_C_FP_BINDING(acos, "Computes the principal value of the arc cosine of the input.") |
| 2421 |
9/18✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
|
3 | DEFINE_AX_C_FP_BINDING(acosh, "Computes the inverse hyperbolic cosine of the input.") |
| 2422 |
10/18✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
|
47 | DEFINE_AX_C_FP_BINDING(asin, "Computes the principal value of the arc sine of the input.") |
| 2423 |
9/18✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
|
3 | DEFINE_AX_C_FP_BINDING(asinh, "Computes the inverse hyperbolic sine of the input.") |
| 2424 |
10/18✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
|
47 | DEFINE_AX_C_FP_BINDING(atan, "Computes the principal value of the arc tangent of the input.") |
| 2425 |
9/18✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
|
3 | DEFINE_AX_C_FP_BINDING(atanh, "Computes the inverse hyperbolic tangent of the input.") |
| 2426 |
10/18✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
|
47 | DEFINE_AX_C_FP_BINDING(cosh, "Computes the hyperbolic cosine of the input.") |
| 2427 |
10/18✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
|
47 | DEFINE_AX_C_FP_BINDING(sinh, "Computes the hyperbolic sine of the input.") |
| 2428 |
10/18✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
|
47 | DEFINE_AX_C_FP_BINDING(tanh, "Computes the hyperbolic tangent of the input.") |
| 2429 | |||
| 2430 | 13 | inline FunctionGroup::UniquePtr axdegrees(const FunctionOptions& op) | |
| 2431 | { | ||
| 2432 | static auto generate = | ||
| 2433 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | [](const std::vector<llvm::Value*>& args, |
| 2434 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2435 | { | ||
| 2436 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | assert(args.size() == 1); |
| 2437 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
|
24 | llvm::Value* arg = args.front(); |
| 2438 | llvm::Value* pi180 = arg->getType()->isFloatTy() ? | ||
| 2439 | 12 | LLVMType<float>::get(B.getContext(), 180.f / openvdb::math::pi<float>()) : | |
| 2440 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
|
24 | LLVMType<double>::get(B.getContext(), 180.0 / openvdb::math::pi<double>()); |
| 2441 | 24 | return binaryOperator(arg, pi180, ast::tokens::MULTIPLY, B); | |
| 2442 | }; | ||
| 2443 | |||
| 2444 | 13 | return FunctionBuilder("degrees") | |
| 2445 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | .addSignature<double(double)>(generate) |
| 2446 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<float(float)>(generate) |
| 2447 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"radians"}) |
| 2448 | .setConstantFold(true) | ||
| 2449 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2450 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2451 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 2452 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2453 | .setDocumentation("Converts the number of radians to degrees.") | ||
| 2454 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2455 | } | ||
| 2456 | |||
| 2457 | 13 | inline FunctionGroup::UniquePtr axradians(const FunctionOptions& op) | |
| 2458 | { | ||
| 2459 | static auto generate = | ||
| 2460 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | [](const std::vector<llvm::Value*>& args, |
| 2461 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2462 | { | ||
| 2463 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | assert(args.size() == 1); |
| 2464 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
|
24 | llvm::Value* arg = args.front(); |
| 2465 | llvm::Value* pi180 = arg->getType()->isFloatTy() ? | ||
| 2466 | 12 | LLVMType<float>::get(B.getContext(), openvdb::math::pi<float>() / 180.f) : | |
| 2467 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
|
24 | LLVMType<double>::get(B.getContext(), openvdb::math::pi<double>() / 180.0); |
| 2468 | 24 | return binaryOperator(arg, pi180, ast::tokens::MULTIPLY, B); | |
| 2469 | }; | ||
| 2470 | |||
| 2471 | 13 | return FunctionBuilder("radians") | |
| 2472 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | .addSignature<double(double)>(generate) |
| 2473 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<float(float)>(generate) |
| 2474 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"degrees"}) |
| 2475 | .setConstantFold(true) | ||
| 2476 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2477 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2478 | 13 | .addFunctionAttribute(llvm::Attribute::InlineHint) | |
| 2479 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2480 | .setDocumentation("Converts the number of degrees to radians.") | ||
| 2481 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2482 | } | ||
| 2483 | |||
| 2484 | 13 | inline FunctionGroup::UniquePtr axtan(const FunctionOptions& op) | |
| 2485 | { | ||
| 2486 | // @todo consider using this IR implementation over std::tan, however | ||
| 2487 | // we then lose constant folding (as results don't match). Ideally | ||
| 2488 | // this ir implementation should exist at compile time as a valid | ||
| 2489 | // function for constant folding | ||
| 2490 | // | ||
| 2491 | // static auto generate = | ||
| 2492 | // [](const std::vector<llvm::Value*>& args, | ||
| 2493 | // const std::unordered_map<std::string, llvm::Value*>&, | ||
| 2494 | // llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2495 | // { | ||
| 2496 | // llvm::Module* M = B.GetInsertBlock()->getParent()->getParent(); | ||
| 2497 | // llvm::Type* type = args[0]->getType(); | ||
| 2498 | // llvm::Function* sinFunction = | ||
| 2499 | // llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::sin, type); | ||
| 2500 | // llvm::Function* cosFunction = | ||
| 2501 | // llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::cos, type); | ||
| 2502 | |||
| 2503 | // llvm::Value* sin = B.CreateCall(sinFunction, args[0]); | ||
| 2504 | // llvm::Value* cos = B.CreateCall(cosFunction, args[0]); | ||
| 2505 | // return binaryOperator(sin, cos, ast::tokens::DIVIDE, B); | ||
| 2506 | // }; | ||
| 2507 | |||
| 2508 | 13 | return FunctionBuilder("tan") | |
| 2509 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double(double)>((double(*)(double))(std::tan)) |
| 2510 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<float(float)>((float(*)(float))(std::tan)) |
| 2511 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"n"}) |
| 2512 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 2513 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2514 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2515 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2516 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2517 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2518 | .setDocumentation("Computes the tangent of arg (measured in radians).") | ||
| 2519 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2520 | } | ||
| 2521 | |||
| 2522 | 13 | inline FunctionGroup::UniquePtr axatan2(const FunctionOptions& op) | |
| 2523 | { | ||
| 2524 | 13 | return FunctionBuilder("atan2") | |
| 2525 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<double(double,double)>((double(*)(double,double))(std::atan2)) |
| 2526 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<float(float,float)>((float(*)(float,float))(std::atan2)) |
| 2527 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"y", "x"}) |
| 2528 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 2529 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2530 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2531 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2532 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2533 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2534 | .setDocumentation("Computes the arc tangent of y/x using the signs of arguments " | ||
| 2535 | "to determine the correct quadrant.") | ||
| 2536 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2537 | } | ||
| 2538 | |||
| 2539 | /////////////////////////////////////////////////////////////////////////// | ||
| 2540 | /////////////////////////////////////////////////////////////////////////// | ||
| 2541 | |||
| 2542 | // String | ||
| 2543 | |||
| 2544 | 13 | inline FunctionGroup::UniquePtr axatoi(const FunctionOptions& op) | |
| 2545 | { | ||
| 2546 | // WARNING: decltype removes the throw identifer from atoi. We should | ||
| 2547 | // use this are automatically update the function attributes as appropriate | ||
| 2548 | 13 | return FunctionBuilder("atoi") | |
| 2549 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<decltype(std::atoi)>(std::atoi) |
| 2550 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"str"}) |
| 2551 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 2552 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 2553 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2554 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2555 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2556 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2557 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2558 | .setDocumentation("Parses the string input interpreting its " | ||
| 2559 | "content as an integral number, which is returned as a value of type int.") | ||
| 2560 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2561 | } | ||
| 2562 | |||
| 2563 | 13 | inline FunctionGroup::UniquePtr axatof(const FunctionOptions& op) | |
| 2564 | { | ||
| 2565 | // WARNING: decltype removes the throw identifer from atof. We should | ||
| 2566 | // use this are automatically update the function attributes as appropriate | ||
| 2567 | 13 | return FunctionBuilder("atof") | |
| 2568 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<decltype(std::atof)>(std::atof) |
| 2569 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"str"}) |
| 2570 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 2571 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 2572 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2573 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2574 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2575 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2576 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2577 | .setDocumentation("Parses the string input, interpreting its " | ||
| 2578 | "content as a floating point number and returns its value as a double.") | ||
| 2579 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2580 | } | ||
| 2581 | |||
| 2582 | 13 | inline FunctionGroup::UniquePtr axhash(const FunctionOptions& op) | |
| 2583 | { | ||
| 2584 | 252 | static auto hash = [](const codegen::String* str) -> int64_t { | |
| 2585 | 252 | return static_cast<int64_t>(std::hash<std::string>{}(str->str())); | |
| 2586 | }; | ||
| 2587 | |||
| 2588 | 13 | return FunctionBuilder("hash") | |
| 2589 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<int64_t(const codegen::String*)>((int64_t(*)(const codegen::String*))(hash)) |
| 2590 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"str"}) |
| 2591 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 2592 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 2593 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2594 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2595 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2596 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2597 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2598 | .setDocumentation("Return a hash of the provided string.") | ||
| 2599 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2600 | } | ||
| 2601 | |||
| 2602 | /////////////////////////////////////////////////////////////////////////// | ||
| 2603 | /////////////////////////////////////////////////////////////////////////// | ||
| 2604 | |||
| 2605 | // Utility | ||
| 2606 | |||
| 2607 | 3 | inline FunctionGroup::UniquePtr axprint(const FunctionOptions& op) | |
| 2608 | { | ||
| 2609 | static auto print = [](auto v) { std::cout << v << std::endl; }; | ||
| 2610 | static auto printv = [](auto* v) { std::cout << *v << std::endl; }; | ||
| 2611 | static auto printstr = [](const codegen::String* axstr) { | ||
| 2612 | std::cout << axstr->c_str() << std::endl; | ||
| 2613 | }; | ||
| 2614 | |||
| 2615 | 3 | return FunctionBuilder("print") | |
| 2616 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(double)>((void(*)(double))(print)) |
| 2617 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(float)>((void(*)(float))(print)) |
| 2618 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(int64_t)>((void(*)(int64_t))(print)) |
| 2619 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(int32_t)>((void(*)(int32_t))(print)) |
| 2620 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
6 | .setArgumentNames({"n"}) |
| 2621 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 2622 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2623 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) |
| 2624 | .setConstantFold(false /*never cf*/) | ||
| 2625 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(const codegen::String*)>((void(*)(const codegen::String*))(printstr)) |
| 2626 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec2<int32_t>*)>((void(*)(openvdb::math::Vec2<int32_t>*))(printv)) |
| 2627 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec2<float>*)>((void(*)(openvdb::math::Vec2<float>*))(printv)) |
| 2628 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec2<double>*)>((void(*)(openvdb::math::Vec2<double>*))(printv)) |
| 2629 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec3<int32_t>*)>((void(*)(openvdb::math::Vec3<int32_t>*))(printv)) |
| 2630 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec3<float>*)>((void(*)(openvdb::math::Vec3<float>*))(printv)) |
| 2631 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec3<double>*)>((void(*)(openvdb::math::Vec3<double>*))(printv)) |
| 2632 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec4<int32_t>*)>((void(*)(openvdb::math::Vec4<int32_t>*))(printv)) |
| 2633 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec4<float>*)>((void(*)(openvdb::math::Vec4<float>*))(printv)) |
| 2634 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Vec4<double>*)>((void(*)(openvdb::math::Vec4<double>*))(printv)) |
| 2635 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Mat3<float>*)>((void(*)(openvdb::math::Mat3<float>*))(printv)) |
| 2636 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Mat3<double>*)>((void(*)(openvdb::math::Mat3<double>*))(printv)) |
| 2637 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Mat4<float>*)>((void(*)(openvdb::math::Mat4<float>*))(printv)) |
| 2638 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addSignature<void(openvdb::math::Mat4<double>*)>((void(*)(openvdb::math::Mat4<double>*))(printv)) |
| 2639 | 3 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) | |
| 2640 |
3/8✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
6 | .setArgumentNames({"n"}) |
| 2641 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 2642 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 2643 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) |
| 2644 | .setConstantFold(false /*never cf*/) | ||
| 2645 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2646 | .setDocumentation("Prints the input to the standard output stream. " | ||
| 2647 | "Warning: This will be run for every element.") | ||
| 2648 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
6 | .get(); |
| 2649 | } | ||
| 2650 | |||
| 2651 | 13 | inline FunctionGroup::UniquePtr axargsort(const FunctionOptions& op) | |
| 2652 | { | ||
| 2653 | 1044 | static auto argsort = [](auto out, const auto in){ | |
| 2654 | using VecType = typename std::remove_pointer<decltype(in)>::type; | ||
| 2655 | // initialize original index locations | ||
| 2656 | 1044 | std::iota(out->asPointer(), out->asPointer() + VecType::size, 0); | |
| 2657 | // sort indexes based on comparing values in v | ||
| 2658 | // using std::stable_sort instead of std::sort | ||
| 2659 | // to avoid unnecessary index re-orderings | ||
| 2660 | // when v contains elements of equal values | ||
| 2661 | 1044 | std::stable_sort(out->asPointer(), out->asPointer() + VecType::size, | |
| 2662 | 2349 | [&in](int32_t i1, int32_t i2) {return (*in)[i1] < (*in)[i2];}); | |
| 2663 | 1044 | }; | |
| 2664 | |||
| 2665 | using Argsort3D = void(openvdb::math::Vec3<int>*, openvdb::math::Vec3<double>*); | ||
| 2666 | using Argsort3F = void(openvdb::math::Vec3<int>*, openvdb::math::Vec3<float>*); | ||
| 2667 | using Argsort3I = void(openvdb::math::Vec3<int>*, openvdb::math::Vec3<int32_t>*); | ||
| 2668 | using Argsort4D = void(openvdb::math::Vec4<int>*, openvdb::math::Vec4<double>*); | ||
| 2669 | using Argsort4F = void(openvdb::math::Vec4<int>*, openvdb::math::Vec4<float>*); | ||
| 2670 | using Argsort4I = void(openvdb::math::Vec4<int>*, openvdb::math::Vec4<int32_t>*); | ||
| 2671 | |||
| 2672 | 13 | return FunctionBuilder("argsort") | |
| 2673 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Argsort3D, true>((Argsort3D*)(argsort)) |
| 2674 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Argsort3F, true>((Argsort3F*)(argsort)) |
| 2675 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Argsort3I, true>((Argsort3I*)(argsort)) |
| 2676 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Argsort4D, true>((Argsort4D*)(argsort)) |
| 2677 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Argsort4F, true>((Argsort4F*)(argsort)) |
| 2678 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Argsort4I, true>((Argsort4I*)(argsort)) |
| 2679 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"v"}) |
| 2680 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 2681 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2682 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2683 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2684 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2685 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2686 | .setDocumentation("Returns a vector of the indexes that would sort the input vector.") | ||
| 2687 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2688 | } | ||
| 2689 | |||
| 2690 | 13 | inline FunctionGroup::UniquePtr axsort(const FunctionOptions& op) | |
| 2691 | { | ||
| 2692 |
1/2✓ Branch 0 taken 87 times.
✗ Branch 1 not taken.
|
87 | static auto sort3 = [](auto out, const auto in) { |
| 2693 | 87 | *out = in->sorted(); | |
| 2694 | 87 | }; | |
| 2695 | |||
| 2696 | static auto sort = [](auto out, const auto in) { | ||
| 2697 | using VecType = typename std::remove_pointer<decltype(out)>::type; | ||
| 2698 | *out = *in; | ||
| 2699 | std::sort(out->asPointer(), out->asPointer() + VecType::size); | ||
| 2700 | }; | ||
| 2701 | |||
| 2702 | using Sort3D = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*); | ||
| 2703 | using Sort3F = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*); | ||
| 2704 | using Sort3I = void(openvdb::math::Vec3<int32_t>*, openvdb::math::Vec3<int32_t>*); | ||
| 2705 | using Sort4D = void(openvdb::math::Vec4<double>*,openvdb::math::Vec4<double>*); | ||
| 2706 | using Sort4F = void(openvdb::math::Vec4<float>*,openvdb::math::Vec4<float>*); | ||
| 2707 | using Sort4I = void(openvdb::math::Vec4<int32_t>*, openvdb::math::Vec4<int32_t>*); | ||
| 2708 | |||
| 2709 | 13 | return FunctionBuilder("sort") | |
| 2710 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Sort3D, true>((Sort3D*)(sort3)) |
| 2711 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Sort3F, true>((Sort3F*)(sort3)) |
| 2712 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Sort3I, true>((Sort3I*)(sort3)) |
| 2713 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Sort4D, true>((Sort4D*)(sort)) |
| 2714 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Sort4F, true>((Sort4F*)(sort)) |
| 2715 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addSignature<Sort4I, true>((Sort4I*)(sort)) |
| 2716 |
2/4✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
|
26 | .setArgumentNames({"v"}) |
| 2717 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 2718 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2719 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2720 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2721 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2722 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2723 | .setDocumentation("Returns the sorted result of the given vector.") | ||
| 2724 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2725 | } | ||
| 2726 | |||
| 2727 | /////////////////////////////////////////////////////////////////////////// | ||
| 2728 | /////////////////////////////////////////////////////////////////////////// | ||
| 2729 | |||
| 2730 | // Colour | ||
| 2731 | |||
| 2732 | 13 | inline FunctionGroup::UniquePtr axhsvtorgb(const FunctionOptions& op) | |
| 2733 | { | ||
| 2734 | auto generate = | ||
| 2735 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | [op](const std::vector<llvm::Value*>& args, |
| 2736 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2737 | { | ||
| 2738 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | assert(args.size() == 2); |
| 2739 | llvm::Function* base = B.GetInsertBlock()->getParent(); | ||
| 2740 | |||
| 2741 | std::vector<llvm::Value*> hsv, rgb; | ||
| 2742 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[0], rgb, B, /*load*/false); //output |
| 2743 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[1], hsv, B, /*load*/true); //input |
| 2744 | |||
| 2745 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Type* precision = hsv[0]->getType(); |
| 2746 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* zero = llvm::ConstantFP::get(precision, 0.0); |
| 2747 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* one = llvm::ConstantFP::get(precision, 1.0); |
| 2748 | |||
| 2749 | // wrap hue values to [0,1] domain, including negative values | ||
| 2750 | // i.e. -0.1 -> 0.9, 4.5 -> 0.5 | ||
| 2751 |
4/8✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
|
24 | hsv[0] = axfloormod(op)->execute({hsv[0], one}, B); |
| 2752 | |||
| 2753 | // clamp saturation values to [0,1] | ||
| 2754 |
4/8✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
|
24 | hsv[1] = axclamp(op)->execute({hsv[1], zero, one}, B); |
| 2755 | |||
| 2756 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::BasicBlock* then = llvm::BasicBlock::Create(B.getContext(), "then", base); |
| 2757 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::BasicBlock* el = llvm::BasicBlock::Create(B.getContext(), "else", base); |
| 2758 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::BasicBlock* post = llvm::BasicBlock::Create(B.getContext(), "post", base); |
| 2759 | |||
| 2760 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* hueisone = binaryOperator(hsv[0], one, ast::tokens::EQUALSEQUALS, B); |
| 2761 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateCondBr(hueisone, then, el); |
| 2762 | |||
| 2763 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* h = insertStaticAlloca(B, precision); |
| 2764 | |||
| 2765 | B.SetInsertPoint(then); | ||
| 2766 | { | ||
| 2767 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* r = binaryOperator(hsv[0], zero, ast::tokens::MULTIPLY, B); // zero hue |
| 2768 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(r, h); |
| 2769 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateBr(post); |
| 2770 | } | ||
| 2771 | B.SetInsertPoint(el); | ||
| 2772 | { | ||
| 2773 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* six = llvm::ConstantFP::get(hsv[0]->getType(), 6.0); |
| 2774 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* r = binaryOperator(hsv[0], six, ast::tokens::MULTIPLY, B); |
| 2775 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(r, h); |
| 2776 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateBr(post); |
| 2777 | } | ||
| 2778 | |||
| 2779 | B.SetInsertPoint(post); | ||
| 2780 | |||
| 2781 |
2/4✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
12 | h = B.CreateLoad(h); |
| 2782 | 12 | llvm::Value* sat = hsv[1]; | |
| 2783 | 12 | llvm::Value* val = hsv[2]; | |
| 2784 | |||
| 2785 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
|
24 | llvm::Value* i = llvm_floor(op)->execute({h}, B); |
| 2786 | llvm::Value* f = | ||
| 2787 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | binaryOperator(h, i, ast::tokens::MINUS, B); |
| 2788 | llvm::Value* p = | ||
| 2789 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | binaryOperator(val, |
| 2790 | 24 | binaryOperator(one, sat, ast::tokens::MINUS, B), | |
| 2791 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | ast::tokens::MULTIPLY, B); |
| 2792 | llvm::Value* q = | ||
| 2793 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
12 | binaryOperator(val, |
| 2794 | binaryOperator(one, | ||
| 2795 | binaryOperator(sat, f, | ||
| 2796 | 24 | ast::tokens::MULTIPLY, B), | |
| 2797 | ✗ | ast::tokens::MINUS, B), | |
| 2798 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | ast::tokens::MULTIPLY, B); |
| 2799 | llvm::Value* t = | ||
| 2800 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
|
12 | binaryOperator(val, |
| 2801 | binaryOperator(one, | ||
| 2802 | binaryOperator(sat, | ||
| 2803 | binaryOperator(one, f, | ||
| 2804 | 24 | ast::tokens::MINUS, B), | |
| 2805 | ✗ | ast::tokens::MULTIPLY, B), | |
| 2806 | 24 | ast::tokens::MINUS, B), | |
| 2807 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | ast::tokens::MULTIPLY, B); |
| 2808 | |||
| 2809 | // start main switch | ||
| 2810 | |||
| 2811 |
2/4✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
12 | post = llvm::BasicBlock::Create(B.getContext(), "post", base); |
| 2812 | |||
| 2813 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | i = arithmeticConversion(i, LLVMType<int64_t>::get(B.getContext()), B); |
| 2814 | |||
| 2815 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 12 times.
|
84 | for (int64_t j = 0; j <= 5; ++j) |
| 2816 | { | ||
| 2817 |
1/2✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
|
72 | llvm::BasicBlock* then = llvm::BasicBlock::Create(B.getContext(), "then", base); |
| 2818 |
2/4✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 72 times.
✗ Branch 6 not taken.
|
72 | llvm::BasicBlock* el = llvm::BasicBlock::Create(B.getContext(), "else", base); |
| 2819 | |||
| 2820 |
1/2✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
|
72 | llvm::Value* constant = LLVMType<int64_t>::get(B.getContext(), j); |
| 2821 |
1/4✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
72 | llvm::Value* switchv = binaryOperator(i, constant, ast::tokens::EQUALSEQUALS, B); |
| 2822 |
1/2✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
|
72 | B.CreateCondBr(switchv, then, el); |
| 2823 | |||
| 2824 | B.SetInsertPoint(then); | ||
| 2825 | { | ||
| 2826 | // The final logic for storing the RGB values | ||
| 2827 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 60 times.
|
72 | if (j == 0) { |
| 2828 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(val, rgb[0]); |
| 2829 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(t, rgb[1]); |
| 2830 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(p, rgb[2]); |
| 2831 | } | ||
| 2832 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 48 times.
|
60 | else if (j == 1) { |
| 2833 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(q, rgb[0]); |
| 2834 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(val, rgb[1]); |
| 2835 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(p, rgb[2]); |
| 2836 | } | ||
| 2837 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 36 times.
|
48 | else if (j == 2) { |
| 2838 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(p, rgb[0]); |
| 2839 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(val, rgb[1]); |
| 2840 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(t, rgb[2]); |
| 2841 | } | ||
| 2842 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
|
36 | else if (j == 3) { |
| 2843 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(p, rgb[0]); |
| 2844 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(q, rgb[1]); |
| 2845 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(val, rgb[2]); |
| 2846 | } | ||
| 2847 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
|
24 | else if (j == 4) { |
| 2848 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(t, rgb[0]); |
| 2849 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(p, rgb[1]); |
| 2850 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(val, rgb[2]); |
| 2851 | } | ||
| 2852 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | else if (j == 5) { |
| 2853 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(val, rgb[0]); |
| 2854 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(p, rgb[1]); |
| 2855 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(q, rgb[2]); |
| 2856 | } | ||
| 2857 | |||
| 2858 |
1/2✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
|
72 | B.CreateBr(post); |
| 2859 | } | ||
| 2860 | // set for next iteration | ||
| 2861 | B.SetInsertPoint(el); | ||
| 2862 | } | ||
| 2863 | |||
| 2864 | // Final case (hue > 1 || hue < 0), zero intialize | ||
| 2865 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(zero, rgb[0]); |
| 2866 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(zero, rgb[1]); |
| 2867 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(zero, rgb[2]); |
| 2868 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateBr(post); |
| 2869 | |||
| 2870 | B.SetInsertPoint(post); | ||
| 2871 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
24 | return B.CreateRetVoid(); |
| 2872 | 13 | }; | |
| 2873 | |||
| 2874 | using HSVtoRGB3D = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*); | ||
| 2875 | using HSVtoRGB3F = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*); | ||
| 2876 | |||
| 2877 | 13 | return FunctionBuilder("hsvtorgb") | |
| 2878 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | .addSignature<HSVtoRGB3D, true>(generate) |
| 2879 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<HSVtoRGB3F, true>(generate) |
| 2880 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"input"} ) |
| 2881 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("floor") |
| 2882 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("floormod") |
| 2883 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("clamp") |
| 2884 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 2885 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 2886 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 2887 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 2888 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 2889 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 2890 | .setDocumentation("Convert HSV color space into RGB color space. Note " | ||
| 2891 | "that the input hue is wrapped to its periodic [0,1] values and " | ||
| 2892 | "the input saturation is clamped between [0,1].") | ||
| 2893 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 2894 | } | ||
| 2895 | |||
| 2896 | 13 | inline FunctionGroup::UniquePtr axrgbtohsv(const FunctionOptions& op) | |
| 2897 | { | ||
| 2898 | auto generate = | ||
| 2899 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | [op](const std::vector<llvm::Value*>& args, |
| 2900 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 2901 | { | ||
| 2902 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | assert(args.size() == 2); |
| 2903 | llvm::Function* base = B.GetInsertBlock()->getParent(); | ||
| 2904 | llvm::LLVMContext& C = B.getContext(); | ||
| 2905 | |||
| 2906 | std::vector<llvm::Value*> hsv, rgb; | ||
| 2907 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[0], hsv, B, /*load*/false); //output |
| 2908 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | arrayUnpack(args[1], rgb, B, /*load*/true); //input |
| 2909 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Type* precision = rgb[0]->getType(); |
| 2910 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* zero = llvm::ConstantFP::get(precision, 0.0); |
| 2911 | |||
| 2912 | |||
| 2913 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
|
24 | llvm::Value* max = axmax(op)->execute({rgb[0], rgb[1]}, B); |
| 2914 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
|
24 | max = axmax(op)->execute({max, rgb[2]}, B); |
| 2915 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
|
24 | llvm::Value* min = axmin(op)->execute({rgb[0], rgb[1]}, B); |
| 2916 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
|
24 | min = axmin(op)->execute({min, rgb[2]}, B); |
| 2917 | |||
| 2918 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
12 | llvm::Value* range = binaryOperator(max, min, ast::tokens::MINUS, B); |
| 2919 | |||
| 2920 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(zero, hsv[0]); |
| 2921 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(zero, hsv[1]); |
| 2922 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(max, hsv[2]); |
| 2923 | |||
| 2924 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::BasicBlock* then = llvm::BasicBlock::Create(C, "then", base); |
| 2925 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::BasicBlock* post = llvm::BasicBlock::Create(C, "post", base); |
| 2926 | |||
| 2927 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* maxneqzero = binaryOperator(max, zero, ast::tokens::NOTEQUALS, B); |
| 2928 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateCondBr(maxneqzero, then, post); |
| 2929 | |||
| 2930 | B.SetInsertPoint(then); | ||
| 2931 | { | ||
| 2932 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
12 | llvm::Value* sat = binaryOperator(range, max, ast::tokens::DIVIDE, B); |
| 2933 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(sat, hsv[1]); |
| 2934 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateBr(post); |
| 2935 | } | ||
| 2936 | |||
| 2937 | B.SetInsertPoint(post); | ||
| 2938 | |||
| 2939 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::Value* sat = B.CreateLoad(hsv[1]); |
| 2940 | |||
| 2941 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | then = llvm::BasicBlock::Create(C, "then", base); |
| 2942 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | post = llvm::BasicBlock::Create(C, "post", base); |
| 2943 | |||
| 2944 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* satneqzero = binaryOperator(sat, zero, ast::tokens::NOTEQUALS, B); |
| 2945 | |||
| 2946 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateCondBr(satneqzero, then, post); |
| 2947 | |||
| 2948 | B.SetInsertPoint(then); | ||
| 2949 | { | ||
| 2950 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | then = llvm::BasicBlock::Create(C, "then", base); |
| 2951 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::BasicBlock* elif1 = llvm::BasicBlock::Create(C, "elif1", base); |
| 2952 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::BasicBlock* el = llvm::BasicBlock::Create(C, "el", base); |
| 2953 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::BasicBlock* end = llvm::BasicBlock::Create(C, "end", base); |
| 2954 | |||
| 2955 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* reqmax = binaryOperator(rgb[0], max, ast::tokens::EQUALSEQUALS, B); |
| 2956 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateCondBr(reqmax, then, elif1); |
| 2957 | |||
| 2958 | B.SetInsertPoint(then); | ||
| 2959 | { | ||
| 2960 | llvm::Value* h = | ||
| 2961 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
12 | binaryOperator( |
| 2962 | 24 | binaryOperator(rgb[1], rgb[2], ast::tokens::MINUS, B), | |
| 2963 | range, | ||
| 2964 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
24 | ast::tokens::DIVIDE, B); |
| 2965 | |||
| 2966 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(h, hsv[0]); |
| 2967 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateBr(end); |
| 2968 | } | ||
| 2969 | |||
| 2970 | B.SetInsertPoint(elif1); | ||
| 2971 | { | ||
| 2972 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | then = llvm::BasicBlock::Create(C, "then", base); |
| 2973 | |||
| 2974 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* geqmax = binaryOperator(rgb[1], max, ast::tokens::EQUALSEQUALS, B); |
| 2975 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateCondBr(geqmax, then, el); |
| 2976 | |||
| 2977 | B.SetInsertPoint(then); | ||
| 2978 | { | ||
| 2979 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* two = llvm::ConstantFP::get(precision, 2.0); |
| 2980 | |||
| 2981 | llvm::Value* h = | ||
| 2982 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
|
12 | binaryOperator(two, |
| 2983 | binaryOperator( | ||
| 2984 | 24 | binaryOperator(rgb[2], rgb[0], ast::tokens::MINUS, B), | |
| 2985 | range, | ||
| 2986 | ✗ | ast::tokens::DIVIDE, B), | |
| 2987 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
24 | ast::tokens::PLUS, B); |
| 2988 | |||
| 2989 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(h, hsv[0]); |
| 2990 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateBr(end); |
| 2991 | } | ||
| 2992 | } | ||
| 2993 | |||
| 2994 | B.SetInsertPoint(el); | ||
| 2995 | { | ||
| 2996 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* four = llvm::ConstantFP::get(precision, 4.0); |
| 2997 | |||
| 2998 | llvm::Value* h = | ||
| 2999 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
|
12 | binaryOperator(four, |
| 3000 | binaryOperator( | ||
| 3001 | 24 | binaryOperator(rgb[0], rgb[1], ast::tokens::MINUS, B), | |
| 3002 | range, | ||
| 3003 | ✗ | ast::tokens::DIVIDE, B), | |
| 3004 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
24 | ast::tokens::PLUS, B); |
| 3005 | |||
| 3006 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(h, hsv[0]); |
| 3007 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateBr(end); |
| 3008 | } | ||
| 3009 | |||
| 3010 | B.SetInsertPoint(end); | ||
| 3011 | |||
| 3012 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* six = llvm::ConstantFP::get(precision, 6.0); |
| 3013 | |||
| 3014 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | llvm::Value* h = B.CreateLoad(hsv[0]); |
| 3015 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
12 | h = binaryOperator(h, six, ast::tokens::DIVIDE, B); |
| 3016 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(h, hsv[0]); |
| 3017 | |||
| 3018 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | then = llvm::BasicBlock::Create(C, "then", base); |
| 3019 | |||
| 3020 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* hlesszero = binaryOperator(h, zero, ast::tokens::LESSTHAN, B); |
| 3021 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateCondBr(hlesszero, then, post); |
| 3022 | |||
| 3023 | B.SetInsertPoint(then); | ||
| 3024 | { | ||
| 3025 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | llvm::Value* one = llvm::ConstantFP::get(precision, 1.0); |
| 3026 |
2/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
12 | h = binaryOperator(h, one, ast::tokens::PLUS, B); |
| 3027 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateStore(h, hsv[0]); |
| 3028 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | B.CreateBr(post); |
| 3029 | } | ||
| 3030 | } | ||
| 3031 | |||
| 3032 | B.SetInsertPoint(post); | ||
| 3033 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
24 | return B.CreateRetVoid(); |
| 3034 | 13 | }; | |
| 3035 | |||
| 3036 | using HSVtoRGB3D = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*); | ||
| 3037 | using HSVtoRGB3F = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*); | ||
| 3038 | |||
| 3039 | 13 | return FunctionBuilder("rgbtohsv") | |
| 3040 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | .addSignature<HSVtoRGB3D, true>(generate) |
| 3041 |
2/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
26 | .addSignature<HSVtoRGB3F, true>(generate) |
| 3042 |
3/8✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
26 | .setArgumentNames({"input"} ) |
| 3043 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("max") |
| 3044 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addDependency("min") |
| 3045 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 3046 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 3047 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | .addFunctionAttribute(llvm::Attribute::NoUnwind) |
| 3048 | 13 | .addFunctionAttribute(llvm::Attribute::AlwaysInline) | |
| 3049 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setConstantFold(op.mConstantFoldCBindings) |
| 3050 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
|
13 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 3051 | .setDocumentation("Convert RGB color space into HSV color space.") | ||
| 3052 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
26 | .get(); |
| 3053 | } | ||
| 3054 | |||
| 3055 | /////////////////////////////////////////////////////////////////////////// | ||
| 3056 | /////////////////////////////////////////////////////////////////////////// | ||
| 3057 | |||
| 3058 | // Custom | ||
| 3059 | |||
| 3060 | 42 | inline FunctionGroup::UniquePtr ax_external(const FunctionOptions& op) | |
| 3061 | { | ||
| 3062 | 208 | static auto find = [](auto out, const void* const data, const codegen::String* const name) | |
| 3063 | { | ||
| 3064 | using ValueType = typename std::remove_pointer<decltype(out)>::type; | ||
| 3065 | const ax::CustomData* const customData = | ||
| 3066 | static_cast<const ax::CustomData*>(data); | ||
| 3067 | 208 | const TypedMetadata<ValueType>* const metaData = | |
| 3068 | customData->getData<TypedMetadata<ValueType>>(name->str()); | ||
| 3069 |
1/2✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
|
208 | *out = (metaData ? metaData->value() : zeroVal<ValueType>()); |
| 3070 | 208 | }; | |
| 3071 | |||
| 3072 | |||
| 3073 | using FindF = void(float*, const void* const, const codegen::String* const); | ||
| 3074 | using FindV3F = void(openvdb::math::Vec3<float>*, const void* const, const codegen::String* const); | ||
| 3075 | |||
| 3076 | 42 | return FunctionBuilder("_external") | |
| 3077 |
1/2✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
|
42 | .addSignature<FindF>((FindF*)(find)) |
| 3078 |
1/2✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
|
42 | .addSignature<FindV3F>((FindV3F*)(find)) |
| 3079 |
2/4✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
|
84 | .setArgumentNames({"str", "custom_data", "result"}) |
| 3080 |
1/2✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
|
42 | .addParameterAttribute(0, llvm::Attribute::NoAlias) |
| 3081 |
1/2✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
|
42 | .addParameterAttribute(0, llvm::Attribute::WriteOnly) |
| 3082 |
1/2✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
|
42 | .addParameterAttribute(1, llvm::Attribute::ReadOnly) |
| 3083 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 18 times.
|
42 | .addParameterAttribute(2, llvm::Attribute::ReadOnly) |
| 3084 | .setConstantFold(false) | ||
| 3085 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 18 times.
|
42 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 3086 | .setDocumentation("Internal function for looking up a custom float value.") | ||
| 3087 |
1/2✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
|
84 | .get(); |
| 3088 | } | ||
| 3089 | |||
| 3090 | 14 | inline FunctionGroup::UniquePtr axexternal(const FunctionOptions& op) | |
| 3091 | { | ||
| 3092 | auto generate = | ||
| 3093 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | [op](const std::vector<llvm::Value*>& args, |
| 3094 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 3095 | { | ||
| 3096 | // Pull out the custom data from the parent function | ||
| 3097 | llvm::Function* compute = B.GetInsertBlock()->getParent(); | ||
| 3098 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | assert(compute); |
| 3099 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
|
28 | assert(std::string(compute->getName()).rfind("ax.compute", 0) == 0); |
| 3100 | 14 | llvm::Value* arg = extractArgument(compute, 0); | |
| 3101 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | assert(arg); |
| 3102 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
|
14 | assert(arg->getName() == "custom_data"); |
| 3103 | |||
| 3104 | std::vector<llvm::Value*> inputs; | ||
| 3105 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | inputs.reserve(2 + args.size()); |
| 3106 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
|
14 | inputs.emplace_back(insertStaticAlloca(B, LLVMType<float>::get(B.getContext()))); |
| 3107 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | inputs.emplace_back(arg); |
| 3108 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | inputs.insert(inputs.end(), args.begin(), args.end()); |
| 3109 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
|
14 | ax_external(op)->execute(inputs, B); |
| 3110 |
2/6✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
28 | return B.CreateLoad(inputs.front()); |
| 3111 | 14 | }; | |
| 3112 | |||
| 3113 | 14 | return FunctionBuilder("external") | |
| 3114 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | .addSignature<float(const codegen::String*)>(generate) |
| 3115 |
3/8✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
28 | .setArgumentNames({"str"}) |
| 3116 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | .addDependency("_external") |
| 3117 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 3118 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | .addFunctionAttribute(llvm::Attribute::ReadOnly) |
| 3119 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | .addFunctionAttribute(llvm::Attribute::NoRecurse) |
| 3120 | .setConstantFold(false) | ||
| 3121 | .setEmbedIR(true) // always embed as we pass through function param "custom_data" | ||
| 3122 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 3123 | .setDocumentation("Find a custom user parameter with a given name of type 'float' " | ||
| 3124 | "in the Custom data provided to the AX compiler. If the data can not be found, " | ||
| 3125 | "or is not of the expected type 0.0f is returned.") | ||
| 3126 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | .get(); |
| 3127 | } | ||
| 3128 | |||
| 3129 | 14 | inline FunctionGroup::UniquePtr axexternalv(const FunctionOptions& op) | |
| 3130 | { | ||
| 3131 | auto generate = | ||
| 3132 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | [op](const std::vector<llvm::Value*>& args, |
| 3133 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
| 3134 | { | ||
| 3135 | // Pull out the custom data from the parent function | ||
| 3136 | llvm::Function* compute = B.GetInsertBlock()->getParent(); | ||
| 3137 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | assert(compute); |
| 3138 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
|
28 | assert(std::string(compute->getName()).rfind("ax.compute", 0) == 0); |
| 3139 | 14 | llvm::Value* arg = extractArgument(compute, 0); | |
| 3140 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | assert(arg); |
| 3141 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
|
14 | assert(arg->getName() == "custom_data"); |
| 3142 | |||
| 3143 | std::vector<llvm::Value*> inputs; | ||
| 3144 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | inputs.reserve(2 + args.size()); |
| 3145 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
|
14 | inputs.emplace_back(insertStaticAlloca(B, LLVMType<float[3]>::get(B.getContext()))); |
| 3146 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | inputs.emplace_back(arg); |
| 3147 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | inputs.insert(inputs.end(), args.begin(), args.end()); |
| 3148 |
3/8✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
14 | ax_external(op)->execute(inputs, B); |
| 3149 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
28 | return inputs.front(); |
| 3150 | 14 | }; | |
| 3151 | |||
| 3152 | 14 | return FunctionBuilder("externalv") | |
| 3153 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | .addSignature<openvdb::math::Vec3<float>*(const codegen::String*)>(generate) |
| 3154 |
3/8✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
28 | .setArgumentNames({"str"}) |
| 3155 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | .addDependency("_external") |
| 3156 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | .addParameterAttribute(0, llvm::Attribute::ReadOnly) |
| 3157 | .setConstantFold(false) | ||
| 3158 | .setEmbedIR(true) // always embed as we pass through function param "custom_data" | ||
| 3159 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) |
| 3160 | .setDocumentation("Find a custom user parameter with a given name of type 'vector float' " | ||
| 3161 | "in the Custom data provided to the AX compiler. If the data can not be found, or is " | ||
| 3162 | "not of the expected type { 0.0f, 0.0f, 0.0f } is returned.") | ||
| 3163 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | .get(); |
| 3164 | } | ||
| 3165 | |||
| 3166 | /////////////////////////////////////////////////////////////////////////// | ||
| 3167 | /////////////////////////////////////////////////////////////////////////// | ||
| 3168 | |||
| 3169 | |||
| 3170 | void insertStringFunctions(FunctionRegistry& reg, const FunctionOptions* options = nullptr); | ||
| 3171 | |||
| 3172 | 1486 | void insertStandardFunctions(FunctionRegistry& registry, | |
| 3173 | const FunctionOptions* options) | ||
| 3174 | { | ||
| 3175 |
3/4✓ Branch 0 taken 1485 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
|
1486 | const bool create = options && !options->mLazyFunctions; |
| 3176 | 117394 | auto add = [&](const std::string& name, | |
| 3177 | const FunctionRegistry::ConstructorT creator, | ||
| 3178 | const bool internal = false) | ||
| 3179 | { | ||
| 3180 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 117394 times.
|
117394 | if (create) registry.insertAndCreate(name, creator, *options, internal); |
| 3181 | 117394 | else registry.insert(name, creator, internal); | |
| 3182 | 118880 | }; | |
| 3183 | |||
| 3184 | // memory | ||
| 3185 | |||
| 3186 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("axmalloc", axmalloc, true); |
| 3187 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("axfree", axfree, true); |
| 3188 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("axrealloc", axrealloc, true); |
| 3189 | |||
| 3190 | // llvm instrinsics | ||
| 3191 | |||
| 3192 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("ceil", llvm_ceil); |
| 3193 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("cos", llvm_cos); |
| 3194 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("exp2", llvm_exp2); |
| 3195 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("exp", llvm_exp); |
| 3196 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("fabs", llvm_fabs); |
| 3197 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("floor", llvm_floor); |
| 3198 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("log10", llvm_log10); |
| 3199 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("log2", llvm_log2); |
| 3200 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("log", llvm_log); |
| 3201 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("pow", llvm_pow); |
| 3202 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("round", llvm_round); |
| 3203 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("sin", llvm_sin); |
| 3204 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("sqrt", llvm_sqrt); |
| 3205 | |||
| 3206 | // math | ||
| 3207 | |||
| 3208 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("abs", axabs); |
| 3209 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("cbrt", axcbrt); |
| 3210 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("clamp", axclamp); |
| 3211 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("cross", axcross); |
| 3212 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("dot", axdot); |
| 3213 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("euclideanmod", axeuclideanmod); |
| 3214 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("fit", axfit); |
| 3215 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("floormod", axfloormod); |
| 3216 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("isfinite", axisfinite); |
| 3217 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("isinf", axisinf); |
| 3218 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("isnan", axisnan); |
| 3219 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("length", axlength); |
| 3220 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("lengthsq", axlengthsq); |
| 3221 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("lerp", axlerp); |
| 3222 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("max", axmax); |
| 3223 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("min", axmin); |
| 3224 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("normalize", axnormalize); |
| 3225 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("rand", axrand); |
| 3226 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("rand32", axrand32); |
| 3227 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("sign", axsign); |
| 3228 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("signbit", axsignbit); |
| 3229 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("truncatemod", axtruncatemod); |
| 3230 | |||
| 3231 | // matrix math | ||
| 3232 | |||
| 3233 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("adjoint", axadjoint); |
| 3234 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("cofactor", axcofactor); |
| 3235 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("determinant", axdeterminant); |
| 3236 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("diag", axdiag); |
| 3237 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("identity3", axidentity3); |
| 3238 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("identity4", axidentity4); |
| 3239 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("inverse", axinverse); |
| 3240 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("mmmult", axmmmult, true); |
| 3241 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("polardecompose", axpolardecompose); |
| 3242 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("postscale", axpostscale); |
| 3243 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("prescale", axprescale); |
| 3244 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("pretransform", axpretransform); |
| 3245 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("trace", axtrace); |
| 3246 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("transform", axtransform); |
| 3247 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("transpose", axtranspose); |
| 3248 | |||
| 3249 | // noise | ||
| 3250 | |||
| 3251 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("simplexnoise", axsimplexnoise); |
| 3252 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("curlsimplexnoise", axcurlsimplexnoise); |
| 3253 | |||
| 3254 | // trig | ||
| 3255 | |||
| 3256 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("degrees", axdegrees); |
| 3257 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("radians", axradians); |
| 3258 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("acos", axacos); |
| 3259 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("acosh", axacosh); |
| 3260 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("asin", axasin); |
| 3261 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("asinh", axasinh); |
| 3262 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("atan", axatan); |
| 3263 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("atan2", axatan2); |
| 3264 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("atanh", axatanh); |
| 3265 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("cosh", axcosh); |
| 3266 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("sinh", axsinh); |
| 3267 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("tan", axtan); |
| 3268 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("tanh", axtanh); |
| 3269 | |||
| 3270 | // string | ||
| 3271 | |||
| 3272 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("atoi", axatoi); |
| 3273 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("atof", axatof); |
| 3274 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("hash", axhash); |
| 3275 | |||
| 3276 | // util | ||
| 3277 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("argsort", axargsort); |
| 3278 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("sort", axsort); |
| 3279 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("print", axprint); |
| 3280 | |||
| 3281 | // colour | ||
| 3282 | |||
| 3283 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("hsvtorgb", axhsvtorgb); |
| 3284 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("rgbtohsv", axrgbtohsv); |
| 3285 | |||
| 3286 | // custom | ||
| 3287 | |||
| 3288 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("_external", ax_external, true); |
| 3289 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("external", axexternal); |
| 3290 |
2/4✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
|
1486 | add("externalv", axexternalv); |
| 3291 | |||
| 3292 | 1486 | insertStringFunctions(registry, options); | |
| 3293 | 1486 | } | |
| 3294 | |||
| 3295 | |||
| 3296 | } // namespace codegen | ||
| 3297 | } // namespace ax | ||
| 3298 | } // namespace OPENVDB_VERSION_NAME | ||
| 3299 | } // namespace openvdb | ||
| 3300 | |||
| 3301 |