Support cases of LUTs which are not function local.

Prevent cases where arrays that are globally defined constants are redeclared
on stack. On Intel macs, declaring a large, statically initialized
spvUnsafeArray on stack may cause an internal compiler error.
This commit is contained in:
Jan Sikorski 2024-03-15 16:20:27 +01:00 committed by Jan Sikorski
parent 2a7c818492
commit 8465ec8109
2 changed files with 30 additions and 2 deletions

View File

@ -1121,6 +1121,9 @@ struct SPIRVariable : IVariant
// Set to true while we're inside the for loop.
bool loop_variable_enable = false;
// Used to find global LUTs
bool is_written_to = false;
SPIRFunction::Parameter *parameter = nullptr;
SPIRV_CROSS_DECLARE_CLONE(SPIRVariable)

View File

@ -3736,6 +3736,11 @@ void Compiler::find_function_local_luts(SPIRFunction &entry, const AnalyzeVariab
auto &var = get<SPIRVariable>(accessed_var.first);
auto &type = expression_type(accessed_var.first);
// First check if there are writes to the variable. Later, if there are none, we'll
// reconsider it as globally accessed LUT.
var.is_written_to |= handler.complete_write_variables_to_block.count(var.self) != 0 ||
handler.partial_write_variables_to_block.count(var.self) != 0;
// Only consider function local variables here.
// If we only have a single function in our CFG, private storage is also fine,
// since it behaves like a function local variable.
@ -3760,8 +3765,7 @@ void Compiler::find_function_local_luts(SPIRFunction &entry, const AnalyzeVariab
static_constant_expression = var.initializer;
// There can be no stores to this variable, we have now proved we have a LUT.
if (handler.complete_write_variables_to_block.count(var.self) != 0 ||
handler.partial_write_variables_to_block.count(var.self) != 0)
if (var.is_written_to)
continue;
}
else
@ -4618,6 +4622,27 @@ void Compiler::build_function_control_flow_graphs_and_analyze()
}
}
}
// Find LUTs which are not function local.
for (auto id: global_variables)
{
auto &var = get<SPIRVariable>(id);
auto &type = get_variable_data_type(var);
if (!is_array(type))
continue;
if (var.storage != StorageClassPrivate || !var.initializer || var.is_written_to)
continue;
if (ir.ids[var.initializer].get_type() != TypeConstant)
continue;
get<SPIRConstant>(var.initializer).is_used_as_lut = true;
var.static_expression = var.initializer;
var.statically_assigned = true;
var.remapped_variable = true;
}
}
Compiler::CFGBuilder::CFGBuilder(Compiler &compiler_)