Skip to content

Commit b5ed706

Browse files
Hoist out variable scope analysis.
1 parent c26c41b commit b5ed706

File tree

7 files changed

+47
-49
lines changed

7 files changed

+47
-49
lines changed

spirv_common.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,6 @@ struct SPIRFunction : IVariant
764764
bool active = false;
765765
bool flush_undeclared = true;
766766
bool do_combined_parameters = true;
767-
bool analyzed_variable_scope = false;
768767
};
769768

770769
struct SPIRAccessChain : IVariant

spirv_cpp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ string CompilerCPP::compile()
300300
backend.explicit_struct_type = true;
301301
backend.use_initializer_list = true;
302302

303-
build_function_control_flow_graphs();
303+
build_function_control_flow_graphs_and_analyze();
304304
update_active_builtins();
305305

306306
uint32_t pass_count = 0;

spirv_cross.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

44254459
Compiler::CFGBuilder::CFGBuilder(spirv_cross::Compiler &compiler_)

spirv_cross.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ class Compiler
869869
bool need_subpass_input = false;
870870
};
871871

872-
void build_function_control_flow_graphs();
872+
void build_function_control_flow_graphs_and_analyze();
873873
std::unordered_map<uint32_t, std::unique_ptr<CFG>> function_cfgs;
874874
struct CFGBuilder : OpcodeHandler
875875
{

spirv_glsl.cpp

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ string CompilerGLSL::compile()
418418
backend.supports_extensions = true;
419419

420420
// Scan the SPIR-V to find trivial uses of extensions.
421-
build_function_control_flow_graphs();
421+
build_function_control_flow_graphs_and_analyze();
422422
find_static_extensions();
423423
fixup_image_load_store_access();
424424
update_active_builtins();
@@ -8909,41 +8909,6 @@ void CompilerGLSL::emit_function(SPIRFunction &func, const Bitset &return_flags)
89098909
current_function = &func;
89108910
auto &entry_block = get<SPIRBlock>(func.entry_block);
89118911

8912-
if (!func.analyzed_variable_scope)
8913-
{
8914-
analyze_variable_scope(func);
8915-
8916-
// Check if we can actually use the loop variables we found in analyze_variable_scope.
8917-
// To use multiple initializers, we need the same type and qualifiers.
8918-
for (auto block : func.blocks)
8919-
{
8920-
auto &b = get<SPIRBlock>(block);
8921-
if (b.loop_variables.size() < 2)
8922-
continue;
8923-
8924-
auto &flags = get_decoration_bitset(b.loop_variables.front());
8925-
uint32_t type = get<SPIRVariable>(b.loop_variables.front()).basetype;
8926-
bool invalid_initializers = false;
8927-
for (auto loop_variable : b.loop_variables)
8928-
{
8929-
if (flags != get_decoration_bitset(loop_variable) ||
8930-
type != get<SPIRVariable>(b.loop_variables.front()).basetype)
8931-
{
8932-
invalid_initializers = true;
8933-
break;
8934-
}
8935-
}
8936-
8937-
if (invalid_initializers)
8938-
{
8939-
for (auto loop_variable : b.loop_variables)
8940-
get<SPIRVariable>(loop_variable).loop_variable = false;
8941-
b.loop_variables.clear();
8942-
}
8943-
}
8944-
func.analyzed_variable_scope = true;
8945-
}
8946-
89478912
for (auto &v : func.local_variables)
89488913
{
89498914
auto &var = get<SPIRVariable>(v);

spirv_hlsl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4572,7 +4572,7 @@ string CompilerHLSL::compile()
45724572
backend.can_declare_arrays_inline = false;
45734573
backend.can_return_array = false;
45744574

4575-
build_function_control_flow_graphs();
4575+
build_function_control_flow_graphs_and_analyze();
45764576
update_active_builtins();
45774577
analyze_image_and_sampler_usage();
45784578

spirv_msl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ string CompilerMSL::compile()
280280

281281
struct_member_padding.clear();
282282

283-
build_function_control_flow_graphs();
283+
build_function_control_flow_graphs_and_analyze();
284284
update_active_builtins();
285285
analyze_image_and_sampler_usage();
286286
build_implicit_builtins();

0 commit comments

Comments
 (0)