aco/insert_exec_mask: remove handling of loop continues

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40628>
This commit is contained in:
Daniel Schürmann 2026-02-17 13:34:25 +01:00 committed by Marge Bot
parent 495c7271a3
commit 16396f2ce6

View file

@ -30,11 +30,9 @@ struct loop_info {
Block* loop_header;
uint16_t num_exec_masks;
bool has_divergent_break;
bool has_divergent_continue;
bool has_discard; /* has a discard or demote */
loop_info(Block* b, uint16_t num, bool breaks, bool cont, bool discard)
: loop_header(b), num_exec_masks(num), has_divergent_break(breaks),
has_divergent_continue(cont), has_discard(discard)
loop_info(Block* b, uint16_t num, bool breaks, bool discard)
: loop_header(b), num_exec_masks(num), has_divergent_break(breaks), has_discard(discard)
{}
};
@ -183,7 +181,7 @@ add_coupling_code(exec_ctx& ctx, Block* block, std::vector<aco_ptr<Instruction>>
/* Create phi for global exact mask in case of demote. */
if (info.has_discard && preds.size() > 1 && info.num_exec_masks > 1) {
aco_ptr<Instruction> phi(
create_instruction(aco_opcode::p_linear_phi, Format::PSEUDO, preds.size(), 1));
create_instruction(aco_opcode::p_linear_phi, Format::PSEUDO, 2, 1));
phi->definitions[0] = bld.def(bld.lm);
phi->operands[0] = ctx.info[preds[0]].exec[0].op;
ctx.info[idx].exec[0].op = bld.insert(std::move(phi));
@ -191,19 +189,6 @@ add_coupling_code(exec_ctx& ctx, Block* block, std::vector<aco_ptr<Instruction>>
ctx.info[idx].exec.back().type |= mask_type_loop;
if (info.has_divergent_continue) {
/* create ssa name for loop active mask */
aco_ptr<Instruction> phi{
create_instruction(aco_opcode::p_linear_phi, Format::PSEUDO, preds.size(), 1)};
phi->definitions[0] = bld.def(bld.lm);
phi->operands[0] = ctx.info[preds[0]].exec.back().op;
ctx.info[idx].exec.back().op = bld.insert(std::move(phi));
restore_exec = true;
uint8_t mask_type = ctx.info[idx].exec.back().type & (mask_type_wqm | mask_type_exact);
ctx.info[idx].exec.emplace_back(ctx.info[idx].exec.back().op, mask_type);
}
} else if (block->kind & block_kind_loop_exit) {
Block* header = ctx.loop.back().loop_header;
loop_info& info = ctx.loop.back();
@ -217,16 +202,7 @@ add_coupling_code(exec_ctx& ctx, Block* block, std::vector<aco_ptr<Instruction>>
if (info.has_discard && header_preds.size() > 1 && info.num_exec_masks > 1) {
aco_ptr<Instruction>& phi = header->instructions[instr_idx++];
assert(phi->opcode == aco_opcode::p_linear_phi);
for (unsigned i = 1; i < phi->operands.size(); i++)
phi->operands[i] = ctx.info[header_preds[i]].exec[0].op;
}
if (info.has_divergent_continue) {
aco_ptr<Instruction>& phi = header->instructions[instr_idx++];
assert(phi->opcode == aco_opcode::p_linear_phi);
for (unsigned i = 1; i < phi->operands.size(); i++)
phi->operands[i] = ctx.info[header_preds[i]].exec[info.num_exec_masks - 1].op;
restore_exec = true;
phi->operands[1] = ctx.info[header_preds[1]].exec[0].op;
}
if (info.has_divergent_break) {
@ -266,7 +242,7 @@ add_coupling_code(exec_ctx& ctx, Block* block, std::vector<aco_ptr<Instruction>>
} else if (preds.size() == 1) {
ctx.info[idx].exec = ctx.info[preds[0]].exec;
/* After continue and break blocks, we implicitly set exec to zero.
/* After break blocks, we implicitly set exec to zero.
* This is so that parallelcopies can be inserted before the branch
* without being affected by the changed exec mask.
*/
@ -578,7 +554,6 @@ add_branch_code(exec_ctx& ctx, Block* block)
if (block->kind & block_kind_loop_preheader) {
/* collect information about the succeeding loop */
bool has_divergent_break = false;
bool has_divergent_continue = false;
bool has_discard = false;
unsigned loop_nest_depth = ctx.program->blocks[idx + 1].loop_nest_depth;
@ -594,8 +569,6 @@ add_branch_code(exec_ctx& ctx, Block* block)
continue;
else if (loop_block.kind & block_kind_break)
has_divergent_break = true;
else if (loop_block.kind & block_kind_continue)
has_divergent_continue = true;
}
if (has_divergent_break) {
@ -613,7 +586,7 @@ add_branch_code(exec_ctx& ctx, Block* block)
unsigned num_exec_masks = ctx.info[idx].exec.size();
ctx.loop.emplace_back(&ctx.program->blocks[block->linear_succs[0]], num_exec_masks,
has_divergent_break, has_divergent_continue, has_discard);
has_divergent_break, has_discard);
Pseudo_branch_instruction& branch = block->instructions.back()->branch();
branch.target[0] = block->linear_succs[0];
@ -683,26 +656,6 @@ add_branch_code(exec_ctx& ctx, Block* block)
break;
}
/* Implicitly set exec to zero and branch. */
ctx.info[idx].exec.back().op = Operand::zero(bld.lm.bytes());
bld.branch(aco_opcode::p_cbranch_nz, bld.scc(cond), block->linear_succs[1],
block->linear_succs[0]);
} else if (block->kind & block_kind_continue) {
assert(block->instructions.back()->opcode == aco_opcode::p_branch);
block->instructions.pop_back();
Temp cond = Temp();
for (int exec_idx = ctx.info[idx].exec.size() - 2; exec_idx >= 0; exec_idx--) {
if (ctx.info[idx].exec[exec_idx].type & mask_type_loop)
break;
cond = bld.tmp(s1);
Operand exec_mask = ctx.info[idx].exec[exec_idx].op;
exec_mask = bld.sop2(Builder::s_andn2, bld.def(bld.lm), bld.scc(Definition(cond)),
exec_mask, Operand(exec, bld.lm));
ctx.info[idx].exec[exec_idx].op = exec_mask;
}
assert(cond != Temp());
/* Implicitly set exec to zero and branch. */
ctx.info[idx].exec.back().op = Operand::zero(bld.lm.bytes());
bld.branch(aco_opcode::p_cbranch_nz, bld.scc(cond), block->linear_succs[1],