fix: Restore previous version of divergence PR.
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions

This commit is contained in:
squidbus 2025-02-02 15:37:08 -08:00
parent 831903799b
commit 460c266e04

View file

@ -148,47 +148,46 @@ void CFG::EmitDivergenceLabels() {
const size_t end_index = GetIndex(end);
s32 curr_begin = -1;
s32 last_exec_idx = -1;
for (size_t index = GetIndex(start); index < end_index; index++) {
const auto& inst = inst_list[index];
const bool is_close = is_close_scope(inst);
if ((is_close || index == end_index - 1) && curr_begin != -1) {
// If there are no instructions inside scope don't do anything.
if (index - curr_begin == 1) {
if (curr_begin != -1) {
// Keep note of the last instruction that does not ignore exec, so we know where
// to end the divergence block without impacting trailing instructions that do.
if (!IgnoresExecMask(inst)) {
last_exec_idx = index;
}
// Consider a close scope on certain instruction types or at the last instruction
// before the next label.
if (is_close_scope(inst) || index == end_index - 1) {
// Only insert a scope if, since the open-scope instruction, there is at least
// one instruction that does not ignore exec.
if (index - curr_begin > 1 && last_exec_idx != -1) {
// Add a label to the instruction right after the open scope call.
// It is the start of a new basic block.
const auto& save_inst = inst_list[curr_begin];
AddLabel(index_to_pc[curr_begin] + save_inst.length);
// Add a label to the close scope instruction.
// There are 3 cases where we need to close a scope.
// * Close scope instruction inside the block
// * Close scope instruction at the end of the block (cbranch or endpgm)
// * Normal instruction at the end of the block
// If the instruction we want to close the scope at is at the end of the
// block, we do not need to insert a new label.
if (last_exec_idx != end_index - 1) {
// Add the label after the last instruction affected by exec.
const auto& last_exec_inst = inst_list[last_exec_idx];
AddLabel(index_to_pc[last_exec_idx] + last_exec_inst.length);
}
}
// Reset scope begin.
curr_begin = -1;
continue;
}
// If all instructions in the scope ignore exec masking, we shouldn't insert a
// scope.
const auto start = inst_list.begin() + curr_begin + 1;
if (!std::ranges::all_of(start, inst_list.begin() + index, IgnoresExecMask)) {
// Determine the last instruction affected by the exec mask, so that any
// trailing instructions not affected can be excluded from the scope.
s32 curr_end = index;
while (IgnoresExecMask(inst_list[curr_end - 1])) {
--curr_end;
}
// Add a label to the instruction right after the open scope call.
// It is the start of a new basic block.
const auto& save_inst = inst_list[curr_begin];
const Label label = index_to_pc[curr_begin] + save_inst.length;
AddLabel(label);
// Add a label to the close scope instruction.
// There are 3 cases where we need to close a scope.
// * Close scope instruction inside the block
// * Close scope instruction at the end of the block (cbranch or endpgm)
// * Normal instruction at the end of the block
// For the last case we must NOT add a label as that would cause
// the instruction to be separated into its own basic block.
if (curr_end != end_index - 1) {
AddLabel(index_to_pc[curr_end]);
}
}
// Reset scope begin.
curr_begin = -1;
}
// Mark a potential start of an exec scope.
if (is_open_scope(inst)) {
curr_begin = index;
last_exec_idx = -1;
}
}
}