mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 08:50:13 +01:00
pan/bi: Add FAU update helper
This comes in destructive and nondestructive flavours, to be used to insert an instruction into a tuple and check if an instruction is insertable respectively. It is responsible for FAU slot matching. It's annoying this sort of logic is duplicated in 3 places (bi_lower_fau, here, and packing) but they each work with different sets of assumptions... Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8354>
This commit is contained in:
parent
e5607c8745
commit
93c82c6fac
1 changed files with 83 additions and 0 deletions
|
|
@ -475,6 +475,89 @@ bi_space_for_more_constants(struct bi_clause_state *clause)
|
|||
return (bi_nconstants(clause) < 13 - (clause->tuple_count + 1));
|
||||
}
|
||||
|
||||
/* Updates the FAU assignment for a tuple. A valid FAU assignment must be
|
||||
* possible (as a precondition); this is gauranteed per-instruction by
|
||||
* bi_lower_fau and per-tuple by bi_instr_schedulable */
|
||||
|
||||
static bool
|
||||
bi_update_fau(struct bi_clause_state *clause,
|
||||
struct bi_tuple_state *tuple,
|
||||
bi_instr *instr, bool fma, bool destructive)
|
||||
{
|
||||
/* Maintain our own constants, for nondestructive mode */
|
||||
uint32_t copied_constants[2], copied_count;
|
||||
unsigned *constant_count = &tuple->constant_count;
|
||||
uint32_t *constants = tuple->constants;
|
||||
|
||||
if (!destructive) {
|
||||
memcpy(copied_constants, tuple->constants,
|
||||
(*constant_count) * sizeof(constants[0]));
|
||||
copied_count = tuple->constant_count;
|
||||
|
||||
constant_count = &copied_count;
|
||||
constants = copied_constants;
|
||||
}
|
||||
|
||||
bi_foreach_src(instr, s) {
|
||||
bi_index src = instr->src[s];
|
||||
|
||||
if (src.type == BI_INDEX_FAU) {
|
||||
bool no_constants = *constant_count == 0;
|
||||
bool no_other_fau = (tuple->fau == src.value) || !tuple->fau;
|
||||
bool mergable = no_constants && no_other_fau;
|
||||
|
||||
if (destructive) {
|
||||
assert(mergable);
|
||||
tuple->fau = src.value;
|
||||
} else if (!mergable) {
|
||||
return false;
|
||||
}
|
||||
} else if (src.type == BI_INDEX_CONSTANT) {
|
||||
/* No need to reserve space if we have a fast 0 */
|
||||
if (src.value == 0 && fma && bi_reads_zero(instr))
|
||||
continue;
|
||||
|
||||
/* If there is a branch target, #0 by convention is the
|
||||
* PC-relative offset to the target */
|
||||
bool pcrel = instr->branch_target && src.value == 0;
|
||||
bool found = false;
|
||||
|
||||
for (unsigned i = 0; i < *constant_count; ++i) {
|
||||
found |= (constants[i] == src.value) &&
|
||||
(i != tuple->pcrel_idx);
|
||||
}
|
||||
|
||||
/* pcrel constants are unique, so don't match */
|
||||
if (found && !pcrel)
|
||||
continue;
|
||||
|
||||
bool no_fau = (*constant_count > 0) || !tuple->fau;
|
||||
bool mergable = no_fau && ((*constant_count) < 2);
|
||||
|
||||
if (destructive) {
|
||||
assert(mergable);
|
||||
|
||||
if (pcrel)
|
||||
tuple->pcrel_idx = *constant_count;
|
||||
} else if (!mergable)
|
||||
return false;
|
||||
|
||||
constants[(*constant_count)++] = src.value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Constants per clause may be limited by tuple count */
|
||||
bool room_for_constants = (*constant_count == 0) ||
|
||||
bi_space_for_more_constants(clause);
|
||||
|
||||
if (destructive)
|
||||
assert(room_for_constants);
|
||||
else if (!room_for_constants)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
static bi_builder *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue