summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-10-28 19:45:29 -0700
committeryum <yum.food.vr@gmail.com>2025-10-28 19:45:29 -0700
commit0a2506e2fce7d754489066c51f51574bdd428bc0 (patch)
treeeb0f896a1655e2861bed8a1d8eed06ab7dc67758 /source
parent72ea1c81cafa23ea2398071b5f170b5ceba41f14 (diff)
non-exported public labels get namespaced now
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-ir-autodiff.cpp6
-rw-r--r--source/slang/slang-ir-util.cpp44
-rw-r--r--source/slang/slang-ir-util.h4
-rw-r--r--source/slang/slang-lower-to-ir.cpp127
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)