diff --git a/src/include/osl_pvt.h b/src/include/osl_pvt.h index f36e3d280..526d838e5 100644 --- a/src/include/osl_pvt.h +++ b/src/include/osl_pvt.h @@ -389,6 +389,13 @@ class TypeSpec { /// to the type. std::string code_from_type() const; + /// Return the type code used to build mangled osl_* runtime function + /// names (e.g. "f" for float, "v" for any triple, "m" for matrix, + /// "s" for string, "i" for int). Unlike code_from_type(), all triple + /// subtypes (color, point, vector, normal) collapse to "v". When + /// derivs is true, float and triple types are prefixed with "d". + std::string runtime_typecode(bool derivs = false) const; + /// Take a type code string (possibly containing many types) /// and turn it into a human-readable string. static std::string typelist_from_code(const char* code); @@ -541,6 +548,13 @@ class Symbol { /// render time should always use the unmangled version for clarity. string_view unmangled() const; + /// Return the runtime type code string for this symbol's type, suitable + /// for building mangled osl_* function names. See TypeSpec::runtime_typecode(). + std::string arg_typecode(bool derivs = false) const + { + return typespec().runtime_typecode(derivs); + } + /// Data type of this symbol. /// const TypeSpec& typespec() const { return m_typespec; } diff --git a/src/liboslexec/llvm_gen.cpp b/src/liboslexec/llvm_gen.cpp index 3b9e788e6..c75a687e0 100644 --- a/src/liboslexec/llvm_gen.cpp +++ b/src/liboslexec/llvm_gen.cpp @@ -2359,21 +2359,8 @@ LLVMGEN(llvm_gen_generic) std::string name = std::string("osl_") + op.opname().string() + "_"; for (int i = 0; i < op.nargs(); ++i) { Symbol* s(rop.opargsym(op, i)); - if (any_deriv_args && Result.has_derivs() && s->has_derivs() - && !s->typespec().is_matrix()) - name += "d"; - if (s->typespec().is_float()) - name += "f"; - else if (s->typespec().is_triple()) - name += "v"; - else if (s->typespec().is_matrix()) - name += "m"; - else if (s->typespec().is_string()) - name += "s"; - else if (s->typespec().is_int()) - name += "i"; - else - OSL_ASSERT(0); + bool derivs = any_deriv_args && Result.has_derivs() && s->has_derivs(); + name += s->arg_typecode(derivs); } if (!Result.has_derivs() || !any_deriv_args) { @@ -3068,31 +3055,6 @@ LLVMGEN(llvm_gen_trace) -static std::string -arg_typecode(Symbol* sym, bool derivs) -{ - const TypeSpec& t(sym->typespec()); - if (t.is_int()) - return "i"; - else if (t.is_matrix()) - return "m"; - else if (t.is_string()) - return "s"; - - std::string name; - if (derivs) - name = "d"; - if (t.is_float()) - name += "f"; - else if (t.is_triple()) - name += "v"; - else - OSL_ASSERT(0); - return name; -} - - - static llvm::Value* llvm_gen_noise_options(BackendLLVM& rop, int opnum, int first_optional_arg) { @@ -3265,7 +3227,7 @@ LLVMGEN(llvm_gen_noise) } std::string funcname = "osl_" + name.string() + "_" - + arg_typecode(&Result, derivs); + + Result.arg_typecode(derivs); llvm::Value* args[10]; int nargs = 0; if (pass_name) { @@ -3280,18 +3242,18 @@ LLVMGEN(llvm_gen_noise) } else args[nargs++] = rop.llvm_void_ptr(Result); } - funcname += arg_typecode(S, derivs); + funcname += S->arg_typecode(derivs); args[nargs++] = rop.llvm_load_arg(*S, derivs); if (T) { - funcname += arg_typecode(T, derivs); + funcname += T->arg_typecode(derivs); args[nargs++] = rop.llvm_load_arg(*T, derivs); } if (periodic) { - funcname += arg_typecode(Sper, false /* no derivs */); + funcname += Sper->arg_typecode(false); args[nargs++] = rop.llvm_load_arg(*Sper, false); if (Tper) { - funcname += arg_typecode(Tper, false /* no derivs */); + funcname += Tper->arg_typecode(false); args[nargs++] = rop.llvm_load_arg(*Tper, false); } } diff --git a/src/liboslexec/typespec.cpp b/src/liboslexec/typespec.cpp index 0722585f7..59f550e7d 100644 --- a/src/liboslexec/typespec.cpp +++ b/src/liboslexec/typespec.cpp @@ -259,6 +259,22 @@ TypeSpec::code_from_type() const +std::string +TypeSpec::runtime_typecode(bool derivs) const +{ + // Reuse code_from_type() for the base char, then collapse all triple + // subtypes (c/p/n) to 'v' since the runtime ABI does not distinguish them. + OSL_DASSERT(!is_array() && !is_structure() && !is_closure()); + std::string code = code_from_type(); + if (code == "c" || code == "p" || code == "n") + code = "v"; + if (derivs && (code == "f" || code == "v")) + code = "d" + code; + return code; +} + + + void TypeSpec::typespecs_from_codes(const char* code, std::vector& types) {