diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2021-01-07 12:18:55 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-07 12:18:55 -0800 |
| commit | 66d4466d680bcd97b7eb561f08bd6da80a1d6c4e (patch) | |
| tree | a83e3ee0e2662d2ffc77485ccd77da77da81a5f0 | |
| parent | 92636513abe72d2da0c45f0e2c1235415e0671c3 (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.slang | 3 | ||||
| -rw-r--r-- | source/slang/slang-ast-modifier.h | 12 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 11 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.cpp | 14 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 5 |
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); } |
