@@ -3647,20 +3647,20 @@ void Compiler::analyze_parameter_preservation(
36473647 }
36483648}
36493649
3650- Compiler::AnalyzeVariableScopeAccessHandler::AnalyzeVariableScopeAccessHandler (spirv_cross:: Compiler &compiler_,
3651- spirv_cross:: SPIRFunction &entry_)
3650+ Compiler::AnalyzeVariableScopeAccessHandler::AnalyzeVariableScopeAccessHandler (Compiler &compiler_,
3651+ SPIRFunction &entry_)
36523652 : compiler(compiler_)
36533653 , entry(entry_)
36543654{
36553655}
36563656
3657- bool Compiler::AnalyzeVariableScopeAccessHandler::follow_function_call (const spirv_cross:: SPIRFunction &)
3657+ bool Compiler::AnalyzeVariableScopeAccessHandler::follow_function_call (const SPIRFunction &)
36583658{
36593659 // Only analyze within this function.
36603660 return false ;
36613661}
36623662
3663- void Compiler::AnalyzeVariableScopeAccessHandler::set_current_block (const spirv_cross:: SPIRBlock &block)
3663+ void Compiler::AnalyzeVariableScopeAccessHandler::set_current_block (const SPIRBlock &block)
36643664{
36653665 current_block = █
36663666
@@ -3848,7 +3848,6 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
38483848 if (length < 3 )
38493849 return false ;
38503850
3851- bool is_pure = compiler.function_is_pure (compiler.get <SPIRFunction>(args[2 ]));
38523851 length -= 3 ;
38533852 args += 3 ;
38543853
@@ -3858,8 +3857,8 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
38583857 if (var)
38593858 {
38603859 accessed_variables_to_block[var->self ].insert (current_block->self );
3861- if (!is_pure) // Assume we can get partial writes to this variable.
3862- partial_write_variables_to_block[var->self ].insert (current_block->self );
3860+ // Assume we can get partial writes to this variable.
3861+ partial_write_variables_to_block[var->self ].insert (current_block->self );
38633862 }
38643863
38653864 // Cannot easily prove if argument we pass to a function is completely written.
@@ -4414,12 +4413,47 @@ bool Compiler::CombinedImageSamplerDrefHandler::handle(spv::Op opcode, const uin
44144413 return true ;
44154414}
44164415
4417- void Compiler::build_function_control_flow_graphs ()
4416+ void Compiler::build_function_control_flow_graphs_and_analyze ()
44184417{
44194418 CFGBuilder handler (*this );
44204419 handler.function_cfgs [entry_point].reset (new CFG (*this , get<SPIRFunction>(entry_point)));
44214420 traverse_all_reachable_opcodes (get<SPIRFunction>(entry_point), handler);
44224421 function_cfgs = move (handler.function_cfgs );
4422+
4423+ for (auto &f : function_cfgs)
4424+ {
4425+ auto &func = get<SPIRFunction>(f.first );
4426+ analyze_variable_scope (func);
4427+
4428+ // Check if we can actually use the loop variables we found in analyze_variable_scope.
4429+ // To use multiple initializers, we need the same type and qualifiers.
4430+ for (auto block : func.blocks )
4431+ {
4432+ auto &b = get<SPIRBlock>(block);
4433+ if (b.loop_variables .size () < 2 )
4434+ continue ;
4435+
4436+ auto &flags = get_decoration_bitset (b.loop_variables .front ());
4437+ uint32_t type = get<SPIRVariable>(b.loop_variables .front ()).basetype ;
4438+ bool invalid_initializers = false ;
4439+ for (auto loop_variable : b.loop_variables )
4440+ {
4441+ if (flags != get_decoration_bitset (loop_variable) ||
4442+ type != get<SPIRVariable>(b.loop_variables .front ()).basetype )
4443+ {
4444+ invalid_initializers = true ;
4445+ break ;
4446+ }
4447+ }
4448+
4449+ if (invalid_initializers)
4450+ {
4451+ for (auto loop_variable : b.loop_variables )
4452+ get<SPIRVariable>(loop_variable).loop_variable = false ;
4453+ b.loop_variables .clear ();
4454+ }
4455+ }
4456+ }
44234457}
44244458
44254459Compiler::CFGBuilder::CFGBuilder (spirv_cross::Compiler &compiler_)
0 commit comments