summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2023-06-12 12:33:58 +0200
committerHans-Kristian Arntzen <post@arntzen-software.no>2023-06-12 12:33:58 +0200
commit0e1ce21d75886aa53295464304ff3adec92d461a (patch)
tree8a9432e3516fbf73cde1ed81c9cf0e72349d1744
parent030d0be28c35bafebd20660c112852b1d8c8c6ca (diff)
downloadSPIRV-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.cpp20
-rw-r--r--spirv_glsl.hpp2
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();