mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-23 20:05:01 +00:00
fix: Restore previous version of divergence PR.
This commit is contained in:
parent
831903799b
commit
460c266e04
1 changed files with 32 additions and 33 deletions
|
@ -148,47 +148,46 @@ void CFG::EmitDivergenceLabels() {
|
||||||
const size_t end_index = GetIndex(end);
|
const size_t end_index = GetIndex(end);
|
||||||
|
|
||||||
s32 curr_begin = -1;
|
s32 curr_begin = -1;
|
||||||
|
s32 last_exec_idx = -1;
|
||||||
for (size_t index = GetIndex(start); index < end_index; index++) {
|
for (size_t index = GetIndex(start); index < end_index; index++) {
|
||||||
const auto& inst = inst_list[index];
|
const auto& inst = inst_list[index];
|
||||||
const bool is_close = is_close_scope(inst);
|
if (curr_begin != -1) {
|
||||||
if ((is_close || index == end_index - 1) && curr_begin != -1) {
|
// Keep note of the last instruction that does not ignore exec, so we know where
|
||||||
// If there are no instructions inside scope don't do anything.
|
// to end the divergence block without impacting trailing instructions that do.
|
||||||
if (index - curr_begin == 1) {
|
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;
|
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.
|
// Mark a potential start of an exec scope.
|
||||||
if (is_open_scope(inst)) {
|
if (is_open_scope(inst)) {
|
||||||
curr_begin = index;
|
curr_begin = index;
|
||||||
|
last_exec_idx = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue