summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorDavid Siher <32305650+dsiher@users.noreply.github.com>2022-02-03 19:16:54 -0800
committerGitHub <noreply@github.com>2022-02-03 19:16:54 -0800
commit5eb835f0332868fd56ac14ce7560e0ae9cfafec9 (patch)
tree67ed2ae3b2527e8cfa66f835062490decf3052ad /source/slang
parent1eda86377847155ed3f0e0b2e40a105af35bd387 (diff)
Fixed naming conflicts in heterogeneous-hello-world (#2114)
* Fixed naming conflicts in heterogeneous-hello-world Added 3 new modifiers (`__unmangled`, `__exportDirectly`, `__externLib`) `__unmangled` causes mangleName() to return the normal name of the decl. `__exportDirectly` changes parent decl name concatenation behavior to use "::" instead of "." (for Name Hint) and emits the name hint when it exists, otherwise it emits the mangled name. `__externLib` stops Slang from emitting the corresponding struct. Also made necessary changes to heterogeneous-hello-world so that this new functionality is shown off. * Undo unintentional formatting changes Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/core.meta.slang20
-rw-r--r--source/slang/slang-ast-modifier.h3
-rw-r--r--source/slang/slang-emit-c-like.cpp29
-rw-r--r--source/slang/slang-emit-cpp.cpp31
-rw-r--r--source/slang/slang-ir-inst-defs.h3
-rw-r--r--source/slang/slang-ir-insts.h12
-rw-r--r--source/slang/slang-lower-to-ir.cpp17
-rw-r--r--source/slang/slang-mangle.cpp12
8 files changed, 116 insertions, 11 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index ca07b299d..779900fd5 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -63,6 +63,26 @@ syntax unorm : UNormModifier;
///
syntax snorm : SNormModifier;
+/// Modifier to indicate that a function name should not be mangled
+/// by the Slang compiler.
+///
+/// The `__unmangled` modifier should only be valid on functions
+/// and is mainly useful for the experimental heterogeneous
+/// features of Slang.
+///
+syntax __unmangled : UnmangledModifier;
+
+/// Modifier to indicate that a function name should be exported
+/// directly. Used in tandem with `__unmangled` in heterogeneous
+/// features of Slang.
+///
+syntax __exportDirectly : __exportDirectly;
+
+/// Modifier to indicate that a struct is defined externally and
+/// should therefore not be exported by Slang.
+///
+syntax __externLib : __externLib;
+
/// A type that can be used as an operand for builtins
[sealed]
[builtin]
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index 2558d7c4b..ae9e0924e 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -28,6 +28,9 @@ class PostfixModifier : public Modifier { SLANG_AST_CLASS(PostfixModifier)};
class ExportedModifier : public Modifier { SLANG_AST_CLASS(ExportedModifier)};
class ConstExprModifier : public Modifier { SLANG_AST_CLASS(ConstExprModifier)};
class GloballyCoherentModifier : public Modifier { SLANG_AST_CLASS(GloballyCoherentModifier)};
+class UnmangledModifier : public Modifier { SLANG_AST_CLASS(UnmangledModifier)};
+class __exportDirectly : public Modifier { SLANG_AST_CLASS(__exportDirectly)};
+class __externLib : public Modifier { SLANG_AST_CLASS(__externLib)};
/// A modifier that indicates an `InheritanceDecl` should be ignored during name lookup (and related checks).
class IgnoreForLookupModifier : public Modifier { SLANG_AST_CLASS(IgnoreForLookupModifier) };
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index e04759773..c0106e9ad 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -740,6 +740,28 @@ String CLikeSourceEmitter::_generateUniqueName(const UnownedStringSlice& name)
String CLikeSourceEmitter::generateName(IRInst* inst)
{
+ // Handle `__exportDirectly` decoration before all else
+ if (inst->findDecoration<IR__exportDirectly>())
+ {
+ // If instruction has a NameHint, we naively emit it as a namespace
+ // This is automatically handled in `getNameforNameHint` when the
+ // `__exportDirectly` decoration is found, so we can just return it.
+ // TODO: This is a very hacky solution.
+ //
+ // Another option would be to have two separate decorations, one that
+ // handles this namespace, and a separate decoration for unmangled names.
+ if (auto nameHintDecoration = inst->findDecoration<IRNameHintDecoration>())
+ {
+ return nameHintDecoration->getName();
+ }
+ // Otherwise, we just want the instruction to not be mangled, which is
+ // similarly handled in `getMangledName`.
+ if (auto linkageDecoration = inst->findDecoration<IRLinkageDecoration>())
+ {
+ return linkageDecoration->getMangledName();
+ }
+ }
+
// If the instruction names something
// that should be emitted as a target intrinsic,
// then use that name instead.
@@ -2901,6 +2923,13 @@ void CLikeSourceEmitter::emitStruct(IRStructType* structType)
return;
}
+ // If the selected `struct` type is externally defined
+ // then we also don't want to emit anything.
+ if (auto externLibDecoration = structType->findDecoration<IR__externLib>())
+ {
+ return;
+ }
+
m_writer->emit("struct ");
emitPostKeywordTypeAttributes(structType);
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index cb6c210be..e06aa8372 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -2709,26 +2709,43 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
}
}
}
+ // Hardcode in (for now) an include for slang-gfx.h so that we can make use
+ // of the gfx namespace
+ //
+ // TODO: Aside from making sure this approach is viable, it would also be
+ // much better to allow this to be done by the programmer in the Slang file.
+ m_writer->emit("#include \"slang-gfx.h\"\n\n");
+
+ // Emit boilerplate that requires gfx.
+ // This is required by the wrapper, so that will be the next place to look
+ // as far as removing boilerplate goes.
+ m_writer->emit("gfx::IShaderProgram* loadShaderProgram(gfx::IDevice* _0, char* _1, char* _2);\n");
+ m_writer->emit("gfx::ITransientResourceHeap* buildTransientHeap(gfx::IDevice* _0);\n");
+ m_writer->emit("gfx::IPipelineState* buildPipelineState(gfx::IDevice* _0, gfx::IShaderProgram* _1);\n");
+ m_writer->emit("void dispatchComputation(gfx::IDevice* _0, gfx::ITransientResourceHeap* _1, gfx::IPipelineState* _2, gfx::IResourceView* _3, uint32_t gridDimsX, uint32_t gridDimsY, uint32_t gridDimsZ);\n");
+ m_writer->emit("gfx::IResourceView* createBufferView(gfx::IDevice* _0, gfx::IBufferResource* _1);\n");
+ m_writer->emit("gfx::IBufferResource* unconvertBuffer(RWStructuredBuffer<float> _0);\n\n");
+
// Emit a wrapper function for calling the shader blob
m_writer->emit("void ");
m_writer->emit(entryPointName);
- m_writer->emit("_wrapper(gfx_Device_0* device, Vector<uint32_t, 3> gridDims, \n");
+ m_writer->emit("_wrapper(gfx::IDevice* device, Vector<uint32_t, 3> gridDims, \n");
m_writer->emit("\tRWStructuredBuffer<float> buffer)\n{");
/* m_writer->emit("\n\tgfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(device, __");
m_writer->emit(entryPointName);
m_writer->emit(", __");
m_writer->emit(entryPointName);
m_writer->emit("Size);");*/
- m_writer->emit("\n\tgfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(device, \"");
+ m_writer->emit("\n\tgfx::IShaderProgram* shaderProgram = loadShaderProgram(device, \"");
m_writer->emit(entryPointName);
m_writer->emit("\", \"");
m_writer->emit(moduleName);
m_writer->emit("\");");
- m_writer->emit("\n\tgfx_TransientResourceHeap_0* transientHeap = buildTransientHeap_0(device);");
- m_writer->emit("\n\tgfx_PipelineState_0* pipelineState = ");
- m_writer->emit("buildPipelineState_0(device, shaderProgram);");
- m_writer->emit("\n\tgfx_ResourceView_0* bufferView = createBufferView_0(device, unconvertBuffer_0(buffer));");
- m_writer->emit("\n\tdispatchComputation_0(device, transientHeap, pipelineState, ");
+ m_writer->emit("\n\tgfx::ITransientResourceHeap* transientHeap = buildTransientHeap(device);");
+ m_writer->emit("\n\tgfx::IPipelineState* pipelineState = ");
+ m_writer->emit("buildPipelineState(device, shaderProgram);");
+ m_writer->emit("\n\tgfx::IResourceView* bufferView = createBufferView(device, unconvertBuffer(buffer));");
+ m_writer->emit("\n\tdispatchComputation(device, transientHeap, pipelineState, ");
m_writer->emit("bufferView, gridDims.x, gridDims.y, gridDims.z);");
m_writer->emit("\n}\n");
}
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 9fa5a2e9d..0fca118d1 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -553,6 +553,9 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
INST(InstanceDecoration, instance, 1, 0)
INST(NumThreadsDecoration, numThreads, 3, 0)
+ INST(__exportDirectly, __exportDirectly, 0, 0)
+ INST(__externLib, __externLib, 0, 0)
+
// Added to IRParam parameters to an entry point
/* GeometryInputPrimitiveTypeDecoration */
INST(PointInputPrimitiveTypeDecoration, pointPrimitiveType, 0, 0)
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 7ef31d71a..9b50047de 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -269,6 +269,8 @@ IR_SIMPLE_DECORATION(PublicDecoration)
IR_SIMPLE_DECORATION(KeepAliveDecoration)
IR_SIMPLE_DECORATION(RequiresNVAPIDecoration)
IR_SIMPLE_DECORATION(NoInlineDecoration)
+IR_SIMPLE_DECORATION(__exportDirectly)
+IR_SIMPLE_DECORATION(__externLib)
struct IRNVAPIMagicDecoration : IRDecoration
{
@@ -2832,6 +2834,16 @@ public:
{
addDecoration(inst, kIROp_SequentialIDDecoration, getIntValue(getUIntType(), id));
}
+
+ void addExportDirectlyDecoration(IRInst* value)
+ {
+ addDecoration(value, kIROp___exportDirectly);
+ }
+
+ void addExternLibDecoration(IRInst* value)
+ {
+ addDecoration(value, kIROp___externLib);
+ }
};
void addHoistableInst(
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index d4b069dca..b2a71a2e0 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -1034,7 +1034,7 @@ static void addLinkageDecoration(
inst = outerGeneric;
}
- if(isImportedDecl(context, decl))
+ if (isImportedDecl(context, decl))
{
builder->addImportDecoration(inst, mangledName);
}
@@ -1047,6 +1047,14 @@ static void addLinkageDecoration(
builder->addPublicDecoration(inst);
builder->addKeepAliveDecoration(inst);
}
+ if (decl->findModifier<__exportDirectly>())
+ {
+ builder->addExportDirectlyDecoration(inst);
+ }
+ if (decl->findModifier<__externLib>())
+ {
+ builder->addExternLibDecoration(inst);
+ }
}
static void addLinkageDecoration(
@@ -1986,7 +1994,12 @@ static String getNameForNameHint(
StringBuilder sb;
sb.append(parentName);
- sb.append(".");
+ if (decl->hasModifier<__exportDirectly>()) {
+ sb.append("::");
+ }
+ else {
+ sb.append(".");
+ }
sb.append(leafName->text);
return sb.ProduceString();
diff --git a/source/slang/slang-mangle.cpp b/source/slang/slang-mangle.cpp
index b0568994f..acb561531 100644
--- a/source/slang/slang-mangle.cpp
+++ b/source/slang/slang-mangle.cpp
@@ -453,12 +453,20 @@ namespace Slang
// forward to something else? E.g., what if we
// are asked to mangle the name of a `typedef`?
+ auto decl = declRef.getDecl();
+
+ // Handle `__unmangled` modifier by simply emitting
+ // the given name.
+ if (decl->hasModifier<UnmangledModifier>())
+ {
+ emit(context, decl->getName()->text);
+ return;
+ }
+
// We will start with a unique prefix to avoid
// clashes with user-defined symbols:
emitRaw(context, "_S");
- auto decl = declRef.getDecl();
-
// Next we will add a bit of info to register
// the *kind* of declaration we are dealing with.
//