diff options
| author | David Siher <32305650+dsiher@users.noreply.github.com> | 2022-02-03 19:16:54 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-03 19:16:54 -0800 |
| commit | 5eb835f0332868fd56ac14ce7560e0ae9cfafec9 (patch) | |
| tree | 67ed2ae3b2527e8cfa66f835062490decf3052ad /source | |
| parent | 1eda86377847155ed3f0e0b2e40a105af35bd387 (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')
| -rw-r--r-- | source/slang/core.meta.slang | 20 | ||||
| -rw-r--r-- | source/slang/slang-ast-modifier.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 29 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 31 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 12 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 17 | ||||
| -rw-r--r-- | source/slang/slang-mangle.cpp | 12 |
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. // |
