Skip to content

Commit

Permalink
Hoist out variable scope analysis.
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKristian-Work committed Jul 5, 2018
1 parent c26c41b commit b5ed706
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 49 deletions.
1 change: 0 additions & 1 deletion spirv_common.hpp
Expand Up @@ -764,7 +764,6 @@ struct SPIRFunction : IVariant
bool active = false;
bool flush_undeclared = true;
bool do_combined_parameters = true;
bool analyzed_variable_scope = false;
};

struct SPIRAccessChain : IVariant
Expand Down
2 changes: 1 addition & 1 deletion spirv_cpp.cpp
Expand Up @@ -300,7 +300,7 @@ string CompilerCPP::compile()
backend.explicit_struct_type = true;
backend.use_initializer_list = true;

build_function_control_flow_graphs();
build_function_control_flow_graphs_and_analyze();
update_active_builtins();

uint32_t pass_count = 0;
Expand Down
50 changes: 42 additions & 8 deletions spirv_cross.cpp
Expand Up @@ -3647,20 +3647,20 @@ void Compiler::analyze_parameter_preservation(
}
}

Compiler::AnalyzeVariableScopeAccessHandler::AnalyzeVariableScopeAccessHandler(spirv_cross::Compiler &compiler_,
spirv_cross::SPIRFunction &entry_)
Compiler::AnalyzeVariableScopeAccessHandler::AnalyzeVariableScopeAccessHandler(Compiler &compiler_,
SPIRFunction &entry_)
: compiler(compiler_)
, entry(entry_)
{
}

bool Compiler::AnalyzeVariableScopeAccessHandler::follow_function_call(const spirv_cross::SPIRFunction &)
bool Compiler::AnalyzeVariableScopeAccessHandler::follow_function_call(const SPIRFunction &)
{
// Only analyze within this function.
return false;
}

void Compiler::AnalyzeVariableScopeAccessHandler::set_current_block(const spirv_cross::SPIRBlock &block)
void Compiler::AnalyzeVariableScopeAccessHandler::set_current_block(const SPIRBlock &block)
{
current_block = █

Expand Down Expand Up @@ -3848,7 +3848,6 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
if (length < 3)
return false;

bool is_pure = compiler.function_is_pure(compiler.get<SPIRFunction>(args[2]));
length -= 3;
args += 3;

Expand All @@ -3858,8 +3857,8 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
if (var)
{
accessed_variables_to_block[var->self].insert(current_block->self);
if (!is_pure) // Assume we can get partial writes to this variable.
partial_write_variables_to_block[var->self].insert(current_block->self);
// Assume we can get partial writes to this variable.
partial_write_variables_to_block[var->self].insert(current_block->self);
}

// Cannot easily prove if argument we pass to a function is completely written.
Expand Down Expand Up @@ -4414,12 +4413,47 @@ bool Compiler::CombinedImageSamplerDrefHandler::handle(spv::Op opcode, const uin
return true;
}

void Compiler::build_function_control_flow_graphs()
void Compiler::build_function_control_flow_graphs_and_analyze()
{
CFGBuilder handler(*this);
handler.function_cfgs[entry_point].reset(new CFG(*this, get<SPIRFunction>(entry_point)));
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
function_cfgs = move(handler.function_cfgs);

for (auto &f : function_cfgs)
{
auto &func = get<SPIRFunction>(f.first);
analyze_variable_scope(func);

// Check if we can actually use the loop variables we found in analyze_variable_scope.
// To use multiple initializers, we need the same type and qualifiers.
for (auto block : func.blocks)
{
auto &b = get<SPIRBlock>(block);
if (b.loop_variables.size() < 2)
continue;

auto &flags = get_decoration_bitset(b.loop_variables.front());
uint32_t type = get<SPIRVariable>(b.loop_variables.front()).basetype;
bool invalid_initializers = false;
for (auto loop_variable : b.loop_variables)
{
if (flags != get_decoration_bitset(loop_variable) ||
type != get<SPIRVariable>(b.loop_variables.front()).basetype)
{
invalid_initializers = true;
break;
}
}

if (invalid_initializers)
{
for (auto loop_variable : b.loop_variables)
get<SPIRVariable>(loop_variable).loop_variable = false;
b.loop_variables.clear();
}
}
}
}

Compiler::CFGBuilder::CFGBuilder(spirv_cross::Compiler &compiler_)
Expand Down
2 changes: 1 addition & 1 deletion spirv_cross.hpp
Expand Up @@ -869,7 +869,7 @@ class Compiler
bool need_subpass_input = false;
};

void build_function_control_flow_graphs();
void build_function_control_flow_graphs_and_analyze();
std::unordered_map<uint32_t, std::unique_ptr<CFG>> function_cfgs;
struct CFGBuilder : OpcodeHandler
{
Expand Down
37 changes: 1 addition & 36 deletions spirv_glsl.cpp
Expand Up @@ -418,7 +418,7 @@ string CompilerGLSL::compile()
backend.supports_extensions = true;

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

if (!func.analyzed_variable_scope)
{
analyze_variable_scope(func);

// Check if we can actually use the loop variables we found in analyze_variable_scope.
// To use multiple initializers, we need the same type and qualifiers.
for (auto block : func.blocks)
{
auto &b = get<SPIRBlock>(block);
if (b.loop_variables.size() < 2)
continue;

auto &flags = get_decoration_bitset(b.loop_variables.front());
uint32_t type = get<SPIRVariable>(b.loop_variables.front()).basetype;
bool invalid_initializers = false;
for (auto loop_variable : b.loop_variables)
{
if (flags != get_decoration_bitset(loop_variable) ||
type != get<SPIRVariable>(b.loop_variables.front()).basetype)
{
invalid_initializers = true;
break;
}
}

if (invalid_initializers)
{
for (auto loop_variable : b.loop_variables)
get<SPIRVariable>(loop_variable).loop_variable = false;
b.loop_variables.clear();
}
}
func.analyzed_variable_scope = true;
}

for (auto &v : func.local_variables)
{
auto &var = get<SPIRVariable>(v);
Expand Down
2 changes: 1 addition & 1 deletion spirv_hlsl.cpp
Expand Up @@ -4572,7 +4572,7 @@ string CompilerHLSL::compile()
backend.can_declare_arrays_inline = false;
backend.can_return_array = false;

build_function_control_flow_graphs();
build_function_control_flow_graphs_and_analyze();
update_active_builtins();
analyze_image_and_sampler_usage();

Expand Down
2 changes: 1 addition & 1 deletion spirv_msl.cpp
Expand Up @@ -280,7 +280,7 @@ string CompilerMSL::compile()

struct_member_padding.clear();

build_function_control_flow_graphs();
build_function_control_flow_graphs_and_analyze();
update_active_builtins();
analyze_image_and_sampler_usage();
build_implicit_builtins();
Expand Down

0 comments on commit b5ed706

Please sign in to comment.