diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2023-06-12 12:33:58 +0200 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2023-06-12 12:33:58 +0200 |
commit | 0e1ce21d75886aa53295464304ff3adec92d461a (patch) | |
tree | 8a9432e3516fbf73cde1ed81c9cf0e72349d1744 | |
parent | 030d0be28c35bafebd20660c112852b1d8c8c6ca (diff) | |
download | SPIRV-Cross-0e1ce21d75886aa53295464304ff3adec92d461a.tar.gz SPIRV-Cross-0e1ce21d75886aa53295464304ff3adec92d461a.tar.bz2 SPIRV-Cross-0e1ce21d75886aa53295464304ff3adec92d461a.zip |
Skip line directives when emitting loop condition blocks.
Avoids problem where enabling line directives breaks loop optimizations
since it thinks there are legitimate statements in the block.
-rw-r--r-- | spirv_glsl.cpp | 20 | ||||
-rw-r--r-- | spirv_glsl.hpp | 2 |
2 files changed, 20 insertions, 2 deletions
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index f2104ff8..d7ee9356 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -16426,6 +16426,17 @@ bool CompilerGLSL::for_loop_initializers_are_same_type(const SPIRBlock &block) return true; } +void CompilerGLSL::emit_block_instructions_with_masked_debug(SPIRBlock &block) +{ + // Have to block debug instructions such as OpLine here, since it will be treated as a statement otherwise, + // which breaks loop optimizations. + // Any line directive would be declared outside the loop body, which would just be confusing either way. + bool old_block_debug_directives = block_debug_directives; + block_debug_directives = true; + emit_block_instructions(block); + block_debug_directives = old_block_debug_directives; +} + bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method method) { SPIRBlock::ContinueBlockType continue_type = continue_block_type(get<SPIRBlock>(block.continue_block)); @@ -16436,7 +16447,7 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method // If we're trying to create a true for loop, // we need to make sure that all opcodes before branch statement do not actually emit any code. // We can then take the condition expression and create a for (; cond ; ) { body; } structure instead. - emit_block_instructions(block); + emit_block_instructions_with_masked_debug(block); bool condition_is_temporary = forced_temporaries.find(block.condition) == end(forced_temporaries); @@ -16516,7 +16527,7 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method // If we're trying to create a true for loop, // we need to make sure that all opcodes before branch statement do not actually emit any code. // We can then take the condition expression and create a for (; cond ; ) { body; } structure instead. - emit_block_instructions(child); + emit_block_instructions_with_masked_debug(child); bool condition_is_temporary = forced_temporaries.find(child.condition) == end(forced_temporaries); @@ -17895,6 +17906,11 @@ void CompilerGLSL::emit_line_directive(uint32_t file_id, uint32_t line_literal) if (redirect_statement) return; + // If we're emitting code in a sensitive context such as condition blocks in for loops, don't emit + // any line directives, because it's not possible. + if (block_debug_directives) + return; + if (options.emit_line_directives) { require_extension_internal("GL_GOOGLE_cpp_style_line_directive"); diff --git a/spirv_glsl.hpp b/spirv_glsl.hpp index 66b23cbe..8a841f34 100644 --- a/spirv_glsl.hpp +++ b/spirv_glsl.hpp @@ -397,6 +397,7 @@ protected: }; TemporaryCopy handle_instruction_precision(const Instruction &instr); void emit_block_instructions(SPIRBlock &block); + void emit_block_instructions_with_masked_debug(SPIRBlock &block); // For relax_nan_checks. GLSLstd450 get_remapped_glsl_op(GLSLstd450 std450_op) const; @@ -545,6 +546,7 @@ protected: SmallVector<std::string> *redirect_statement = nullptr; const SPIRBlock *current_continue_block = nullptr; bool block_temporary_hoisting = false; + bool block_debug_directives = false; void begin_scope(); void end_scope(); |