mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 09:18:04 +02:00
ir3/cp: support propagating const vecs
Some instructions (e.g., cat6) support using a const vec (i.e., multiple consecutive const registers) as src. Add support for cp'ing collects of consecutive const registers. Signed-off-by: Job Noorman <jnoorman@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41365>
This commit is contained in:
parent
c67118a6eb
commit
8bd0212874
1 changed files with 51 additions and 20 deletions
|
|
@ -287,6 +287,34 @@ try_swap_cat3_two_srcs(struct ir3_instruction *instr, unsigned n,
|
||||||
return is_sad(instr->opc) && try_swap_two_srcs(instr, n, new_flags, 1);
|
return is_sad(instr->opc) && try_swap_two_srcs(instr, n, new_flags, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Is this a collect of only consecutive const srcs? Some instructions (e.g.,
|
||||||
|
* cat6) can directly use consecutive const registers as a src so the collect
|
||||||
|
* can be cp'ed like a mov.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
is_const_vec(struct ir3_instruction *collect)
|
||||||
|
{
|
||||||
|
if (collect->opc != OPC_META_COLLECT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned first_num;
|
||||||
|
|
||||||
|
foreach_src_n (src, src_n, collect) {
|
||||||
|
if (!(src->flags & IR3_REG_CONST)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_n == 0) {
|
||||||
|
first_num = src->num;
|
||||||
|
} else if (src->num != first_num + src_n) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle cp for a given src register. This additionally handles
|
* Handle cp for a given src register. This additionally handles
|
||||||
* the cases of collapsing immedate/const (which replace the src
|
* the cases of collapsing immedate/const (which replace the src
|
||||||
|
|
@ -341,7 +369,7 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
|
||||||
} else if (try_swap_cat3_two_srcs(instr, n, new_flags)) {
|
} else if (try_swap_cat3_two_srcs(instr, n, new_flags)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if ((is_same_type_mov(src) || is_const_mov(src)) &&
|
} else if ((is_same_type_mov(src) || is_const_mov(src) || is_const_vec(src)) &&
|
||||||
/* cannot collapse const/immed/etc into control flow: */
|
/* cannot collapse const/immed/etc into control flow: */
|
||||||
opc_cat(instr->opc) != 0) {
|
opc_cat(instr->opc) != 0) {
|
||||||
/* immed/const/etc cases, which require some special handling: */
|
/* immed/const/etc cases, which require some special handling: */
|
||||||
|
|
@ -406,25 +434,28 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
|
||||||
* to work only for float. So we should do this only with
|
* to work only for float. So we should do this only with
|
||||||
* float opcodes.
|
* float opcodes.
|
||||||
*/
|
*/
|
||||||
if (src->cat1.dst_type == TYPE_F16) {
|
if (src->opc == OPC_MOV) {
|
||||||
/* TODO: should we have a way to tell phi/collect to use a
|
if (src->cat1.dst_type == TYPE_F16) {
|
||||||
* float move so that this is legal?
|
/* TODO: should we have a way to tell phi/collect to use a
|
||||||
*/
|
* float move so that this is legal?
|
||||||
if (is_meta(instr))
|
*/
|
||||||
return false;
|
if (is_meta(instr))
|
||||||
if (instr->opc == OPC_MOV && !type_float(instr->cat1.src_type))
|
return false;
|
||||||
return false;
|
if (instr->opc == OPC_MOV && !type_float(instr->cat1.src_type))
|
||||||
if (!is_cat2_float(instr->opc) && !is_cat3_float(instr->opc))
|
return false;
|
||||||
return false;
|
if (!is_cat2_float(instr->opc) && !is_cat3_float(instr->opc))
|
||||||
} else if (src->cat1.dst_type == TYPE_U16 || src->cat1.dst_type == TYPE_S16) {
|
return false;
|
||||||
/* Since we set CONSTANT_DEMOTION_ENABLE, a float reference of
|
} else if (src->cat1.dst_type == TYPE_U16 ||
|
||||||
* what was a U16 value read from the constbuf would incorrectly
|
src->cat1.dst_type == TYPE_S16) {
|
||||||
* do 32f->16f conversion, when we want to read a 16f value.
|
/* Since we set CONSTANT_DEMOTION_ENABLE, a float reference of
|
||||||
*/
|
* what was a U16 value read from the constbuf would incorrectly
|
||||||
if (is_cat2_float(instr->opc) || is_cat3_float(instr->opc))
|
* do 32f->16f conversion, when we want to read a 16f value.
|
||||||
return false;
|
*/
|
||||||
if (instr->opc == OPC_MOV && type_float(instr->cat1.src_type))
|
if (is_cat2_float(instr->opc) || is_cat3_float(instr->opc))
|
||||||
return false;
|
return false;
|
||||||
|
if (instr->opc == OPC_MOV && type_float(instr->cat1.src_type))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
src_reg = ir3_reg_clone(instr->block->shader, src_reg);
|
src_reg = ir3_reg_clone(instr->block->shader, src_reg);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue