mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-27 02:10:15 +00:00
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:
parent
56d0f50357
commit
82b378d671
@ -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(); }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user