summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2021-01-07 12:18:55 -0800
committerGitHub <noreply@github.com>2021-01-07 12:18:55 -0800
commit66d4466d680bcd97b7eb561f08bd6da80a1d6c4e (patch)
treea83e3ee0e2662d2ffc77485ccd77da77da81a5f0
parent92636513abe72d2da0c45f0e2c1235415e0671c3 (diff)
Add support for [noinline] attribute (#1650)
This adds the `[noinline]` attribute to the front-end, and passes it through when generating HLSL output. Notes: * This change doesn't include a test since the dxc version I have locally parses `[noinline]` but then generates DXIL that fails validation. * This change doesn't include logic to handle `[noinline]` for other targets. Notably, SPIR-V has decorations that convey the same intention, but we don't yet take advantage of the GLSL extension(s) that would let us generate those decorations. * By necesstiy, `[noinline]` is only a "strong suggestion" and not actually something the compiler can ever guarantee/enforce.
-rw-r--r--source/slang/core.meta.slang3
-rw-r--r--source/slang/slang-ast-modifier.h12
-rw-r--r--source/slang/slang-emit-c-like.cpp11
-rw-r--r--source/slang/slang-emit-c-like.h2
-rw-r--r--source/slang/slang-emit-hlsl.cpp14
-rw-r--r--source/slang/slang-emit-hlsl.h2
-rw-r--r--source/slang/slang-ir-inst-defs.h3
-rw-r--r--source/slang/slang-ir-insts.h1
-rw-r--r--source/slang/slang-lower-to-ir.cpp5
9 files changed, 53 insertions, 0 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index f8b1bd1f9..9fecc7661 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -2082,3 +2082,6 @@ attribute_syntax [builtin] : BuiltinAttribute;
__attributeTarget(DeclBase)
attribute_syntax [__requiresNVAPI] : RequiresNVAPIAttribute;
+
+__attributeTarget(FunctionDeclBase)
+attribute_syntax [noinline] : NoInlineAttribute; \ No newline at end of file
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index 55b62483b..3d0c3c6c1 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -937,4 +937,16 @@ class NVAPISlotModifier : public Modifier
String spaceName;
};
+ /// A `[noinline]` attribute represents a request by the application that,
+ /// to the extent possible, a function should not be inlined into call sites.
+ ///
+ /// Note that due to various limitations of different targets, it is entirely
+ /// possible for such functions to be inlined or specialized to call sites.
+ ///
+class NoInlineAttribute : public Attribute
+{
+ SLANG_AST_CLASS(NoInlineAttribute)
+};
+
+
} // namespace Slang
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index facb8a710..44564e575 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -3160,6 +3160,7 @@ void CLikeSourceEmitter::emitSimpleFuncImpl(IRFunc* func)
auto name = getName(func);
+ emitFuncDecorations(func);
emitType(resultType, name);
emitSimpleFuncParamsImpl(func);
emitSemantics(func);
@@ -3268,6 +3269,7 @@ void CLikeSourceEmitter::emitFuncDecl(IRFunc* func)
auto name = getName(func);
+ emitFuncDecorations(func);
emitType(resultType, name);
m_writer->emit("(");
@@ -3344,6 +3346,15 @@ void CLikeSourceEmitter::emitFunc(IRFunc* func)
}
}
+void CLikeSourceEmitter::emitFuncDecorations(IRFunc* func)
+{
+ for(auto decoration : func->getDecorations())
+ {
+ emitFuncDecorationImpl(decoration);
+ }
+}
+
+
void CLikeSourceEmitter::emitStruct(IRStructType* structType)
{
// If the selected `struct` type is actually an intrinsic
diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h
index a26959e54..0544668cc 100644
--- a/source/slang/slang-emit-c-like.h
+++ b/source/slang/slang-emit-c-like.h
@@ -246,6 +246,7 @@ public:
bool isTargetIntrinsic(IRFunc* func);
void emitFunc(IRFunc* func);
+ void emitFuncDecorations(IRFunc* func);
void emitStruct(IRStructType* structType);
@@ -340,6 +341,7 @@ public:
virtual void emitIntrinsicCallExprImpl(IRCall* inst, IRTargetIntrinsicDecoration* targetIntrinsic, EmitOpInfo const& inOuterPrec);
virtual void emitFunctionPreambleImpl(IRInst* inst) { SLANG_UNUSED(inst); }
virtual void emitLoopControlDecorationImpl(IRLoopControlDecoration* decl) { SLANG_UNUSED(decl); }
+ virtual void emitFuncDecorationImpl(IRDecoration* decoration) { SLANG_UNUSED(decoration); }
// Only needed for glsl output with $ prefix intrinsics - so perhaps removable in the future
virtual void emitTextureOrTextureSamplerTypeImpl(IRTextureTypeBase* type, char const* baseName) { SLANG_UNUSED(type); SLANG_UNUSED(baseName); }
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index 57d603940..a1da1bbdf 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -693,6 +693,20 @@ void HLSLSourceEmitter::emitLoopControlDecorationImpl(IRLoopControlDecoration* d
}
}
+void HLSLSourceEmitter::emitFuncDecorationImpl(IRDecoration* decoration)
+{
+ switch( decoration->op )
+ {
+ case kIROp_NoInlineDecoration:
+ m_writer->emit("[noinline]\n");
+ break;
+
+ default:
+ break;
+ }
+}
+
+
void HLSLSourceEmitter::emitSimpleValueImpl(IRInst* inst)
{
switch (inst->op)
diff --git a/source/slang/slang-emit-hlsl.h b/source/slang/slang-emit-hlsl.h
index b93cc694b..614ee58bc 100644
--- a/source/slang/slang-emit-hlsl.h
+++ b/source/slang/slang-emit-hlsl.h
@@ -45,6 +45,8 @@ protected:
virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE;
virtual void emitSimpleValueImpl(IRInst* inst) SLANG_OVERRIDE;
virtual void emitLoopControlDecorationImpl(IRLoopControlDecoration* decl) SLANG_OVERRIDE;
+ virtual void emitFuncDecorationImpl(IRDecoration* decoration) SLANG_OVERRIDE;
+
virtual void handleRequiredCapabilitiesImpl(IRInst* inst) SLANG_OVERRIDE;
virtual void emitPreludeDirectivesImpl() SLANG_OVERRIDE;
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 736cb0cec..7b26ad9cb 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -599,6 +599,9 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
/// that the NVAPI shader parameter intends to use.
INST(NVAPISlotDecoration, nvapiSlot, 2, 0)
+ /// Applie to an IR function and signals that inlining should not be performed unless unavoidable.
+ INST(NoInlineDecoration, noInline, 0, 0)
+
INST(SemanticDecoration, semantic, 2, 0)
INST_RANGE(Decoration, HighLevelDeclDecoration, SemanticDecoration)
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index dc42fde70..3c7406d3b 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -266,6 +266,7 @@ IR_SIMPLE_DECORATION(PreciseDecoration)
IR_SIMPLE_DECORATION(PublicDecoration)
IR_SIMPLE_DECORATION(KeepAliveDecoration)
IR_SIMPLE_DECORATION(RequiresNVAPIDecoration)
+IR_SIMPLE_DECORATION(NoInlineDecoration)
struct IRNVAPIMagicDecoration : IRDecoration
{
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 34b189b14..1ea3c71fb 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -7041,6 +7041,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
getBuilder()->addSimpleDecoration<IRRequiresNVAPIDecoration>(irFunc);
}
+ if(decl->findModifier<NoInlineAttribute>())
+ {
+ getBuilder()->addSimpleDecoration<IRNoInlineDecoration>(irFunc);
+ }
+
if (decl->findModifier<PublicModifier>()) {
getBuilder()->addSimpleDecoration<IRPublicDecoration>(irFunc);
}