From 6bbc70979578de3001b94d1b0b8a7712626a84d5 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Thu, 4 Jun 2026 17:20:17 -0700 Subject: [PATCH] refactor: Reduce redundancy of argument code logic Some of the translation of type codes to the abbreviations we use internally for argument type signatures and internal function naming, like 'f' for float, 'c' for color, etc., were repeated in various place. This tries to remove some of the duplication. Signed-off-by: Larry Gritz --- src/include/osl_pvt.h | 14 ++++++++++ src/liboslexec/llvm_gen.cpp | 52 +++++-------------------------------- src/liboslexec/typespec.cpp | 16 ++++++++++++ 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/include/osl_pvt.h b/src/include/osl_pvt.h index f36e3d2807..526d838e57 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 3b9e788e6d..c75a687e01 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 0722585f7f..59f550e7da 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) {