diff options
| -rw-r--r-- | source/slang/slang-ir-autodiff.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-ir-util.cpp | 44 | ||||
| -rw-r--r-- | source/slang/slang-ir-util.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 127 |
4 files changed, 180 insertions, 1 deletions
diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp index c1b724b9d..298dccb1b 100644 --- a/source/slang/slang-ir-autodiff.cpp +++ b/source/slang/slang-ir-autodiff.cpp @@ -5,6 +5,7 @@ #include "slang-ir-autodiff-fwd.h" #include "slang-ir-autodiff-pairs.h" #include "slang-ir-autodiff-rev.h" +#include "slang-ir-util.h" #include "slang-ir-inline.h" #include "slang-ir-single-return.h" #include "slang-ir-ssa-simplification.h" @@ -839,6 +840,11 @@ IRInst* DifferentialPairTypeBuilder::_createDiffPairType(IRType* origBaseType, I StringBuilder nameBuilder; nameBuilder << "DiffPair_"; getTypeNameHint(nameBuilder, origBaseType); + String moduleSuffix = getOrCreateModuleNonPublicSuffix(sharedContext->moduleInst); + if (moduleSuffix.getLength()) + { + nameBuilder.append(moduleSuffix); + } builder.addNameHintDecoration(pairStructType, nameBuilder.toString().getUnownedSlice()); builder.createStructField(pairStructType, _getOrCreatePrimalStructKey(), origBaseType); diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp index 4fb4d61ae..1e00fcaf6 100644 --- a/source/slang/slang-ir-util.cpp +++ b/source/slang/slang-ir-util.cpp @@ -5,9 +5,53 @@ #include "slang-ir-dominators.h" #include "slang-ir-insts.h" +#include <cstdint> +#include <random> + namespace Slang { +static String _generateRandomSuffix() +{ + std::random_device rd; + uint32_t value = rd(); + if (value == 0) + { + value = 0x4AE33F2Eu; // arbitrary non-zero fallback + } + + const char kHexDigits[] = "0123456789abcdef"; + char buffer[9]; + uint32_t temp = value; + for (int i = 7; i >= 0; --i) + { + buffer[i] = kHexDigits[temp & 0xF]; + temp >>= 4; + } + buffer[8] = 0; + + StringBuilder sb; + sb.append("_"); + sb.append(buffer); + return sb.produceString(); +} + +String getOrCreateModuleNonPublicSuffix(IRModuleInst* moduleInst) +{ + static Dictionary<IRModuleInst*, String> map; + + if (!moduleInst) + return String(); + + String suffix; + if (map.tryGetValue(moduleInst, suffix)) + return suffix; + + suffix = _generateRandomSuffix(); + map[moduleInst] = suffix; + return suffix; +} + bool isPointerOfType(IRInst* type, IROp opCode) { if (auto ptrType = as<IRPtrTypeBase>(type)) diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h index 0495bda0f..d49381aa8 100644 --- a/source/slang/slang-ir-util.h +++ b/source/slang/slang-ir-util.h @@ -32,6 +32,10 @@ public: IRInst* cloneInst(IRBuilder* builder, IRInst* src); }; +/// Retrieves or lazily creates a module-scoped suffix applied to non-exported symbols. +/// The suffix remains stable for the lifetime of the module instance. +String getOrCreateModuleNonPublicSuffix(IRModuleInst* moduleInst); + struct DeduplicateContext { diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 2708c0192..d52b9bd04 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -2654,6 +2654,126 @@ static String getNameForNameHint(IRGenContext* context, Decl* decl) return sb.produceString(); } +static bool shouldApplyNonPublicSuffix(Decl* target) +{ + if (!target || !target->getName()) + return false; + + if (!(as<FuncDecl>(target) || as<AggTypeDecl>(target))) + return false; + + if (target->hasModifier<PublicModifier>() || target->hasModifier<HLSLExportModifier>() || + target->hasModifier<ExternModifier>() || target->hasModifier<ExternCppModifier>() || + target->hasModifier<DllImportAttribute>() || target->hasModifier<DllExportAttribute>() || + target->hasModifier<CudaDeviceExportAttribute>() || + target->hasModifier<CudaHostAttribute>() || target->hasModifier<CudaKernelAttribute>() || + target->hasModifier<TorchEntryPointAttribute>() || + target->hasModifier<AutoPyBindCudaAttribute>() || + target->hasModifier<PyExportAttribute>()) + { + return false; + } + + if (auto aggType = as<AggTypeDecl>(target)) + { + if (!(as<StructDecl>(aggType) || as<ClassDecl>(aggType))) + return false; + } + + Decl* parent = target->parentDecl; + while (parent) + { + if (as<GenericDecl>(parent)) + { + parent = parent->parentDecl; + continue; + } + + if (as<NamespaceDecl>(parent) || as<ModuleDecl>(parent)) + return true; + + return false; + } + + return false; +} + +static bool hasExplicitExportedLinkage(IRInst* inst) +{ + if (!inst) + return false; + + return inst->findDecoration<IRPublicDecoration>() || + inst->findDecoration<IRExportDecoration>() || + inst->findDecoration<IRHLSLExportDecoration>() || + inst->findDecoration<IRExternCppDecoration>() || + inst->findDecoration<IRDllImportDecoration>() || + inst->findDecoration<IRDllExportDecoration>() || + inst->findDecoration<IRCudaDeviceExportDecoration>() || + inst->findDecoration<IRCudaHostDecoration>() || + inst->findDecoration<IRCudaKernelDecoration>() || + inst->findDecoration<IRTorchEntryPointDecoration>() || + inst->findDecoration<IRAutoPyBindCudaDecoration>() || + inst->findDecoration<IRPyExportDecoration>(); +} + +static bool shouldApplyNonPublicSuffix(IRInst* inst) +{ + if (!inst) + return false; + + if (hasExplicitExportedLinkage(inst)) + return false; + + if (as<IRGlobalValueWithCode>(inst) || as<IRStructType>(inst) || as<IRClassType>(inst) || + as<IRInterfaceType>(inst)) + { + return true; + } + + return false; +} + +static void appendSuffixIfNeeded(IRGenContext* context, IRInst* inst, Decl* decl, String& name) +{ + bool needsSuffix = false; + if (decl) + { + needsSuffix = shouldApplyNonPublicSuffix(decl); + } + else + { + needsSuffix = shouldApplyNonPublicSuffix(inst); + } + + if (!needsSuffix) + return; + + IRModuleInst* moduleInst = nullptr; + if (inst) + { + if (auto module = inst->getModule()) + moduleInst = module->getModuleInst(); + } + if (!moduleInst && context && context->irBuilder) + { + if (auto module = context->irBuilder->getModule()) + moduleInst = module->getModuleInst(); + } + + String suffix = getOrCreateModuleNonPublicSuffix(moduleInst); + if (!suffix.getLength()) + return; + + if (name.endsWith(suffix)) + return; + + StringBuilder sb; + sb.append(name); + sb.append(suffix); + name = sb.produceString(); +} + /// Try to add an appropriate name hint to the instruction, /// that can be used for back-end code emission or debug info. static void addNameHint(IRGenContext* context, IRInst* inst, Decl* decl) @@ -2661,6 +2781,9 @@ static void addNameHint(IRGenContext* context, IRInst* inst, Decl* decl) String name = getNameForNameHint(context, decl); if (name.getLength() == 0) return; + + appendSuffixIfNeeded(context, inst, decl, name); + context->irBuilder->addNameHintDecoration(inst, name.getUnownedSlice()); } @@ -2672,7 +2795,9 @@ static void addNameHint(IRGenContext* context, IRInst* inst, char const* text) return; } - context->irBuilder->addNameHintDecoration(inst, UnownedTerminatedStringSlice(text)); + String name(text); + appendSuffixIfNeeded(context, inst, nullptr, name); + context->irBuilder->addNameHintDecoration(inst, name.getUnownedSlice()); } LoweredValInfo createVar(IRGenContext* context, IRType* type, Decl* decl = nullptr) |
