r600/sfn: assert that group barrier is not emitted in divergent code flow
Also rename emit_barrier to emit_group_barrier Signed-off-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23272>
This commit is contained in:
@@ -724,6 +724,29 @@ child_block_empty(const exec_list& list)
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool value_has_non_const_source(VirtualValue *value)
|
||||
{
|
||||
auto reg = value->as_register();
|
||||
if (reg) {
|
||||
// Non-ssa registers are probably the result of some control flow
|
||||
// that makes the values non-uniform across the work group
|
||||
if (!reg->has_flag(Register::ssa))
|
||||
return true;
|
||||
|
||||
for (const auto& p : reg->parents()) {
|
||||
auto alu = p->as_alu();
|
||||
if (alu) {
|
||||
for (auto& s : p->as_alu()->sources()) {
|
||||
return value_has_non_const_source(s);
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Shader::process_if(nir_if *if_stmt)
|
||||
{
|
||||
@@ -731,6 +754,8 @@ Shader::process_if(nir_if *if_stmt)
|
||||
|
||||
auto value = value_factory().src(if_stmt->condition, 0);
|
||||
|
||||
bool non_const_cond = value_has_non_const_source(value);
|
||||
|
||||
EAluOp op = child_block_empty(if_stmt->then_list) ? op2_prede_int :
|
||||
op2_pred_setne_int;
|
||||
|
||||
@@ -745,6 +770,8 @@ Shader::process_if(nir_if *if_stmt)
|
||||
|
||||
IfInstr *ir = new IfInstr(pred);
|
||||
emit_instruction(ir);
|
||||
if (non_const_cond)
|
||||
++m_control_flow_depth;
|
||||
start_new_block(1);
|
||||
|
||||
if (!child_block_empty(if_stmt->then_list)) {
|
||||
@@ -775,6 +802,9 @@ Shader::process_if(nir_if *if_stmt)
|
||||
if (!emit_control_flow(ControlFlowInstr::cf_endif))
|
||||
return false;
|
||||
|
||||
if (non_const_cond)
|
||||
--m_control_flow_depth;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1268,8 +1298,9 @@ Shader::emit_shader_clock(nir_intrinsic_instr *instr)
|
||||
}
|
||||
|
||||
bool
|
||||
Shader::emit_barrier(nir_intrinsic_instr *intr)
|
||||
Shader::emit_group_barrier(nir_intrinsic_instr *intr)
|
||||
{
|
||||
assert(m_control_flow_depth == 0);
|
||||
(void)intr;
|
||||
/* Put barrier into it's own block, so that optimizers and the
|
||||
* scheduler don't move code */
|
||||
|
||||
@@ -317,7 +317,7 @@ private:
|
||||
bool emit_local_store(nir_intrinsic_instr *intr);
|
||||
bool emit_local_load(nir_intrinsic_instr *instr);
|
||||
bool emit_load_tcs_param_base(nir_intrinsic_instr *instr, int offset);
|
||||
bool emit_barrier(nir_intrinsic_instr *intr);
|
||||
bool emit_group_barrier(nir_intrinsic_instr *intr);
|
||||
bool emit_shader_clock(nir_intrinsic_instr *instr);
|
||||
bool emit_wait_ack();
|
||||
|
||||
@@ -396,6 +396,7 @@ private:
|
||||
|
||||
InstructionChain m_chain_instr;
|
||||
std::list<Instr *, Allocator<Instr *>> m_loops;
|
||||
int m_control_flow_depth{0};
|
||||
};
|
||||
|
||||
std::pair<unsigned, unsigned>
|
||||
|
||||
Reference in New Issue
Block a user