Implement workaround to deal with older glslang loop output.
The problem case is when continue block == loop header block. Add some special cases to deal with this scenario.
This commit is contained in:
Родитель
e50e04c247
Коммит
97f81ba1e2
|
@ -451,7 +451,7 @@ namespace spir2cross
|
|||
inline uint32_t vector_size() const { return m.c[0].vecsize; }
|
||||
inline uint32_t columns() const { return m.columns; }
|
||||
|
||||
SPIRConstant(uint32_t constant_type, const uint32_t *elements, uint32_t num_elements) :
|
||||
SPIRConstant(uint32_t constant_type, const uint32_t *elements, uint32_t num_elements) :
|
||||
constant_type(constant_type)
|
||||
{
|
||||
subconstants.insert(end(subconstants), elements, elements + num_elements);
|
||||
|
@ -539,8 +539,8 @@ namespace spir2cross
|
|||
ConstantMatrix m;
|
||||
bool specialization = false; // If the constant is a specialization constant.
|
||||
|
||||
// For composites which are constant arrays, etc.
|
||||
std::vector<uint32_t> subconstants;
|
||||
// For composites which are constant arrays, etc.
|
||||
std::vector<uint32_t> subconstants;
|
||||
};
|
||||
|
||||
class Variant
|
||||
|
|
|
@ -1438,7 +1438,12 @@ void Compiler::parse(const Instruction &i)
|
|||
|
||||
loop_block.insert(block->self);
|
||||
loop_merge_target.insert(block->merge_block);
|
||||
continue_block.insert(block->continue_block);
|
||||
|
||||
// Don't add loop headers to continue blocks,
|
||||
// which would make it impossible branch into the loop header since
|
||||
// they are treated as continues.
|
||||
if (block->continue_block != block->self)
|
||||
continue_block.insert(block->continue_block);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1606,12 +1611,17 @@ bool Compiler::execution_is_branchless(const SPIRBlock &from, const SPIRBlock &t
|
|||
|
||||
SPIRBlock::ContinueBlockType Compiler::continue_block_type(const SPIRBlock &continue_block) const
|
||||
{
|
||||
auto &dominator = get<SPIRBlock>(continue_block.loop_dominator);
|
||||
|
||||
// The block was deemed too complex during code emit, pick conservative fallback paths.
|
||||
if (continue_block.complex_continue)
|
||||
return SPIRBlock::ComplexLoop;
|
||||
|
||||
// In older glslang output continue block can be equal to the loop header.
|
||||
// In this case, execution is clearly branchless, so just assume a while loop header here.
|
||||
if (continue_block.merge == SPIRBlock::MergeLoop)
|
||||
return SPIRBlock::WhileLoop;
|
||||
|
||||
auto &dominator = get<SPIRBlock>(continue_block.loop_dominator);
|
||||
|
||||
if (execution_is_noop(continue_block, dominator))
|
||||
return SPIRBlock::WhileLoop;
|
||||
else if (execution_is_branchless(continue_block, dominator))
|
||||
|
|
Загрузка…
Ссылка в новой задаче