The result of an AccessChain intrinsic in SPIRV can be referenced by multiple blocks but when they are loops that can result in compilation problems because the source variables might not be declared early enough. This forces us to hoist those variables high enough to make it work.

This commit is contained in:
Mark Satterthwaite 2019-08-14 11:06:21 -04:00 committed by Lukas Hermanns
parent a80c74b40e
commit 869d628521
2 changed files with 18 additions and 0 deletions

View File

@ -2730,6 +2730,13 @@ void Compiler::AnalyzeVariableScopeAccessHandler::notify_variable_access(uint32_
{
if (id == 0)
return;
/* UE Change Begin: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
for (auto child_id : access_chain_children[id])
{
notify_variable_access(child_id, block);
}
/* UE Change End: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
if (id_is_phi_variable(id))
accessed_variables_to_block[id].insert(block);
@ -2795,14 +2802,22 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
if (length < 3)
return false;
/* UE Change Begin: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
uint32_t ptr = args[2];
auto *var = compiler.maybe_get<SPIRVariable>(ptr);
if (var)
{
accessed_variables_to_block[var->self].insert(current_block->self);
access_chain_children[args[1]].insert(var->self);
}
// args[2] might be another access chain we have to track use of.
for (uint32_t i = 2; i < length; i++)
{
notify_variable_access(args[i], current_block->self);
access_chain_children[args[1]].insert(args[i]);
}
/* UE Change End: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
// Also keep track of the access chain pointer itself.
// In exceptionally rare cases, we can end up with a case where

View File

@ -919,6 +919,9 @@ protected:
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> complete_write_variables_to_block;
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> partial_write_variables_to_block;
std::unordered_set<uint32_t> access_chain_expressions;
/* UE Change Begin: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> access_chain_children;
/* UE Change End: Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. */
const SPIRBlock *current_block = nullptr;
};