summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-03-23 10:54:01 -0700
committerGitHub <noreply@github.com>2024-03-23 10:54:01 -0700
commita23adc221b1ea26db3f3313226b629eb9e308b0f (patch)
tree6f758d64201f2c606dc3e61394899bff4fa72f51 /source/slang
parent9b0df14cdf9d9ea8857b5b9d59505b18020f8414 (diff)
Make `-no-mangle` option work, add `-no-hlsl-binding`. (#3817)
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-check-decl.cpp8
-rw-r--r--source/slang/slang-emit-hlsl.cpp26
-rw-r--r--source/slang/slang-emit-hlsl.h6
-rw-r--r--source/slang/slang-ir-inst-defs.h2
-rw-r--r--source/slang/slang-ir-insts.h5
-rw-r--r--source/slang/slang-lower-to-ir.cpp5
-rw-r--r--source/slang/slang-options.cpp3
-rw-r--r--source/slang/slang-parser.cpp17
8 files changed, 58 insertions, 14 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 093e2599f..c117dbc14 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -1772,7 +1772,13 @@ namespace Slang
parentAggTypeDecl->unionTagsWith(getTypeTags(varDeclRefType));
}
}
-
+ if (getOptionSet().getBoolOption(CompilerOptionName::NoMangle) &&
+ isGlobalDecl(varDecl))
+ {
+ // If -no-mangle option is set, we will add `ExternCpp` modifier to all
+ // global variables and struct fields to prevent mangling.
+ addModifier(varDecl, m_astBuilder->create<ExternCppModifier>());
+ }
checkVisibility(varDecl);
}
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index 3d45394d3..92866f9c4 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -37,7 +37,7 @@ void HLSLSourceEmitter::_emitHLSLDecorationSingleInt(const char* name, IRFunc* e
m_writer->emit(")]\n");
}
-void HLSLSourceEmitter::_emitHLSLRegisterSemantic(LayoutResourceKind kind, EmitVarChain* chain, char const* uniformSemanticSpelling)
+void HLSLSourceEmitter::_emitHLSLRegisterSemantic(LayoutResourceKind kind, EmitVarChain* chain, IRInst* inst, char const* uniformSemanticSpelling)
{
if (!chain)
return;
@@ -100,6 +100,16 @@ void HLSLSourceEmitter::_emitHLSLRegisterSemantic(LayoutResourceKind kind, EmitV
break;
default:
{
+ if (m_codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::NoHLSLBinding))
+ {
+ // If we are told not to emit hlsl binding, and the user has not provided explicit binding,
+ // then skip emitting the `: register` semantics here.
+ //
+ if (!inst || !inst->findDecoration<IRHasExplicitHLSLBindingDecoration>())
+ {
+ break;
+ }
+ }
m_writer->emit(" : register(");
switch (kind)
{
@@ -130,7 +140,7 @@ void HLSLSourceEmitter::_emitHLSLRegisterSemantic(LayoutResourceKind kind, EmitV
}
}
-void HLSLSourceEmitter::_emitHLSLRegisterSemantics(EmitVarChain* chain, char const* uniformSemanticSpelling)
+void HLSLSourceEmitter::_emitHLSLRegisterSemantics(EmitVarChain* chain, IRInst* inst, char const* uniformSemanticSpelling)
{
if (!chain) return;
@@ -147,17 +157,17 @@ void HLSLSourceEmitter::_emitHLSLRegisterSemantics(EmitVarChain* chain, char con
for (auto rr : layout->getOffsetAttrs())
{
- _emitHLSLRegisterSemantic(rr->getResourceKind(), chain, uniformSemanticSpelling);
+ _emitHLSLRegisterSemantic(rr->getResourceKind(), chain, inst, uniformSemanticSpelling);
}
}
-void HLSLSourceEmitter::_emitHLSLRegisterSemantics(IRVarLayout* varLayout, char const* uniformSemanticSpelling)
+void HLSLSourceEmitter::_emitHLSLRegisterSemantics(IRVarLayout* varLayout, IRInst* inst, char const* uniformSemanticSpelling)
{
if (!varLayout)
return;
EmitVarChain chain(varLayout);
- _emitHLSLRegisterSemantics(&chain, uniformSemanticSpelling);
+ _emitHLSLRegisterSemantics(&chain, inst, uniformSemanticSpelling);
}
void HLSLSourceEmitter::_emitHLSLParameterGroupFieldLayoutSemantics(EmitVarChain* chain)
@@ -168,7 +178,7 @@ void HLSLSourceEmitter::_emitHLSLParameterGroupFieldLayoutSemantics(EmitVarChain
auto layout = chain->varLayout;
for (auto rr : layout->getOffsetAttrs())
{
- _emitHLSLRegisterSemantic(rr->getResourceKind(), chain, "packoffset");
+ _emitHLSLRegisterSemantic(rr->getResourceKind(), chain, nullptr, "packoffset");
}
}
@@ -207,7 +217,7 @@ void HLSLSourceEmitter::_emitHLSLParameterGroup(IRGlobalParam* varDecl, IRUnifor
typeLayout = parameterGroupTypeLayout->getElementVarLayout()->getTypeLayout();
}
- _emitHLSLRegisterSemantic(LayoutResourceKind::ConstantBuffer, &containerChain);
+ _emitHLSLRegisterSemantic(LayoutResourceKind::ConstantBuffer, &containerChain, varDecl);
auto elementType = type->getElementType();
if (hasExplicitConstantBufferOffset(type))
@@ -299,7 +309,7 @@ void HLSLSourceEmitter::emitLayoutSemanticsImpl(IRInst* inst, char const* unifor
auto layout = getVarLayout(inst);
if (layout)
{
- _emitHLSLRegisterSemantics(layout, uniformSemanticSpelling);
+ _emitHLSLRegisterSemantics(layout, inst, uniformSemanticSpelling);
}
}
diff --git a/source/slang/slang-emit-hlsl.h b/source/slang/slang-emit-hlsl.h
index 707667e90..049d8af65 100644
--- a/source/slang/slang-emit-hlsl.h
+++ b/source/slang/slang-emit-hlsl.h
@@ -66,11 +66,11 @@ protected:
// Emit a single `register` semantic, as appropriate for a given resource-type-specific layout info
// Keyword to use in the uniform case (`register` for globals, `packoffset` inside a `cbuffer`)
- void _emitHLSLRegisterSemantic(LayoutResourceKind kind, EmitVarChain* chain, char const* uniformSemanticSpelling = "register");
+ void _emitHLSLRegisterSemantic(LayoutResourceKind kind, EmitVarChain* chain, IRInst* inst, char const* uniformSemanticSpelling = "register");
// Emit all the `register` semantics that are appropriate for a particular variable layout
- void _emitHLSLRegisterSemantics(EmitVarChain* chain, char const* uniformSemanticSpelling = "register");
- void _emitHLSLRegisterSemantics(IRVarLayout* varLayout, char const* uniformSemanticSpelling = "register");
+ void _emitHLSLRegisterSemantics(EmitVarChain* chain, IRInst* inst, char const* uniformSemanticSpelling = "register");
+ void _emitHLSLRegisterSemantics(IRVarLayout* varLayout, IRInst* inst, char const* uniformSemanticSpelling = "register");
void _emitHLSLParameterGroupFieldLayoutSemantics(EmitVarChain* chain);
void _emitHLSLParameterGroupFieldLayoutSemantics(IRVarLayout* fieldLayout, EmitVarChain* inChain);
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 10df5d0d7..63f063154 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -714,6 +714,8 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
INST(RequireGLSLExtensionDecoration, requireGLSLExtension, 1, 0)
INST(RequireCUDASMVersionDecoration, requireCUDASMVersion, 1, 0)
+ INST(HasExplicitHLSLBindingDecoration, HasExplicitHLSLBinding, 0, 0)
+
INST(ReadNoneDecoration, readNone, 0, 0)
INST(VulkanCallablePayloadDecoration, vulkanCallablePayload, 0, 0)
INST(VulkanCallablePayloadInDecoration, vulkanCallablePayloadIn, 0, 0)
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index b104baca7..36f9159a8 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -349,6 +349,7 @@ struct IRRequireGLSLExtensionDecoration : IRDecoration
}
};
+IR_SIMPLE_DECORATION(HasExplicitHLSLBindingDecoration)
IR_SIMPLE_DECORATION(ReadNoneDecoration)
IR_SIMPLE_DECORATION(NoSideEffectDecoration)
IR_SIMPLE_DECORATION(EarlyDepthStencilDecoration)
@@ -4652,6 +4653,10 @@ public:
{
addDecoration(value, kIROp_HLSLExportDecoration);
}
+ void addHasExplicitHLSLBindingDecoration(IRInst* value)
+ {
+ addDecoration(value, kIROp_HasExplicitHLSLBindingDecoration);
+ }
void addNVAPIMagicDecoration(IRInst* value, UnownedStringSlice const& name)
{
addDecoration(value, kIROp_NVAPIMagicDecoration, getStringValue(name));
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 5a3b0c2c5..3dd8da9f1 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -7626,7 +7626,10 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
}
addTargetIntrinsicDecorations(nullptr, irParam, decl);
-
+ if (decl->findModifier<HLSLLayoutSemantic>())
+ {
+ builder->addHasExplicitHLSLBindingDecoration(irParam);
+ }
// A global variable's SSA value is a *pointer* to
// the underlying storage.
context->setGlobalValue(decl, paramVal);
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index 3d0b22edd..e3ccec36a 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -517,6 +517,8 @@ void initCommandOptions(CommandOptions& options)
"Set the filesystem hook to use for a compile request."},
{ OptionKind::Heterogeneous, "-heterogeneous", nullptr, "Output heterogeneity-related code." },
{ OptionKind::NoMangle, "-no-mangle", nullptr, "Do as little mangling of names as possible." },
+ { OptionKind::NoHLSLBinding, "-no-hlsl-binding", nullptr, "Do not include explicit parameter binding semantics in the output HLSL code,"
+ "except for parameters that has explicit bindings in the input source." },
{ OptionKind::ValidateUniformity, "-validate-uniformity", nullptr, "Perform uniformity validation analysis." },
{ OptionKind::AllowGLSL, "-allow-glsl", nullptr, "Enable GLSL as an input language." },
};
@@ -1694,6 +1696,7 @@ SlangResult OptionsParser::_parse(
case OptionKind::PreprocessorOutput:
case OptionKind::DumpAst:
case OptionKind::IncompleteLibrary:
+ case OptionKind::NoHLSLBinding:
linkage->m_optionSet.set(optionKind, true); break;
break;
case OptionKind::NoCodeGen:
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index d64329add..4522f977d 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -84,6 +84,7 @@ namespace Slang
bool enableEffectAnnotations = false;
bool allowGLSLInput = false;
bool isInLanguageServer = false;
+ CompilerOptionSet optionSet;
};
// TODO: implement two pass parsing for file reference and struct type recognition
@@ -3207,7 +3208,20 @@ namespace Slang
else
{
// Otherwise, we need to generate a name for the buffer variable.
- bufferVarDecl->nameAndLoc.name = generateName(parser, "parameterGroup_" + String(reflectionNameToken.getContent()));
+ if (parser->options.optionSet.getBoolOption(CompilerOptionName::NoMangle))
+ {
+ // If no-mangle option is set, use the reflection name as the variable name,
+ // and mark all members of the buffer object as no mangle.
+ bufferVarDecl->nameAndLoc.name = reflectionNameToken.getName();
+ for (auto m : bufferDataTypeDecl->getMembersOfType<VarDecl>())
+ {
+ addModifier(m, parser->astBuilder->create<ExternCppModifier>());
+ }
+ }
+ else
+ {
+ bufferVarDecl->nameAndLoc.name = generateName(parser, "parameterGroup_" + String(reflectionNameToken.getContent()));
+ }
// We also need to make the declaration "transparent" so that their
// members are implicitly made visible in the parent scope.
@@ -7546,6 +7560,7 @@ namespace Slang
translationUnit->compileRequest->optionSet.getBoolOption(CompilerOptionName::AllowGLSL) ||
sourceLanguage == SourceLanguage::GLSL;
options.isInLanguageServer = translationUnit->compileRequest->getLinkage()->isInLanguageServer();
+ options.optionSet = translationUnit->compileRequest->optionSet;
Parser parser(astBuilder, tokens, sink, outerScope, options);
parser.namePool = translationUnit->getNamePool();