spirv-opt: Add support to prevent functions from being inlined if they have DontInline flag (#3858)

This commit add support for optimizer to not inline functions with DontInline control flag, so that the [noinline] attribute in HLSL will be useful in DXC SPIR-V generation.

This is part of work of github.com/microsoft/DirectXShaderCompiler/issues/3158
This commit is contained in:
Junda Liu 2020-10-30 04:38:56 +08:00 committed by GitHub
parent 56d0f50357
commit 82b378d671
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 0 deletions

View File

@ -94,6 +94,9 @@ class Function {
// Returns function's return type id
inline uint32_t type_id() const { return def_inst_->type_id(); }
// Returns the function's control mask
inline uint32_t control_mask() const { return def_inst_->GetSingleWordInOperand(0); }
// Returns the entry basic block for this function.
const std::unique_ptr<BasicBlock>& entry() const { return blocks_.front(); }

View File

@ -727,6 +727,12 @@ void InlinePass::AnalyzeReturns(Function* func) {
bool InlinePass::IsInlinableFunction(Function* func) {
// We can only inline a function if it has blocks.
if (func->cbegin() == func->cend()) return false;
// Do not inline functions with DontInline flag.
if (func->control_mask() & SpvFunctionControlDontInlineMask) {
return false;
}
// Do not inline functions with returns in loops. Currently early return
// functions are inlined by wrapping them in a one trip loop and implementing
// the returns as a branch to the loop's merge block. However, this can only

View File

@ -2405,6 +2405,38 @@ OpFunctionEnd
SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true);
}
TEST_F(InlineTest, DontInlineFuncWithDontInline) {
// Check that the function with DontInline flag is not inlined.
const std::string text = R"(
; CHECK: %foo = OpFunction %int DontInline
; CHECK: OpReturnValue %int_0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
OpSource HLSL 600
OpName %main "main"
OpName %foo "foo"
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%void = OpTypeVoid
%6 = OpTypeFunction %void
%7 = OpTypeFunction %int
%main = OpFunction %void None %6
%8 = OpLabel
%9 = OpFunctionCall %int %foo
OpReturn
OpFunctionEnd
%foo = OpFunction %int DontInline %7
%10 = OpLabel
OpReturnValue %int_0
OpFunctionEnd
)";
SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
}
TEST_F(InlineTest, InlineFuncWithOpKillNotInContinue) {
const std::string before =
R"(OpCapability Shader