mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-29 17:10:46 +02:00
freedreno/ir3/ra: use register_allocate
Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
parent
694beb8b83
commit
d52fb2f5ad
6 changed files with 616 additions and 507 deletions
|
|
@ -83,7 +83,6 @@ struct ir3_register {
|
|||
*/
|
||||
IR3_REG_SSA = 0x2000, /* 'instr' is ptr to assigning instr */
|
||||
IR3_REG_IA = 0x4000, /* meta-input dst is "assigned" */
|
||||
IR3_REG_ADDR = 0x8000, /* register is a0.x */
|
||||
} flags;
|
||||
union {
|
||||
/* normal registers:
|
||||
|
|
@ -245,6 +244,13 @@ struct ir3_instruction {
|
|||
*/
|
||||
#define DEPTH_UNUSED ~0
|
||||
unsigned depth;
|
||||
/* When we get to the RA stage, we no longer need depth, but
|
||||
* we do need instruction's position/name:
|
||||
*/
|
||||
struct {
|
||||
uint16_t ip;
|
||||
uint16_t name;
|
||||
};
|
||||
};
|
||||
|
||||
/* Used during CP and RA stages. For fanin and shader inputs/
|
||||
|
|
@ -503,6 +509,28 @@ static inline bool is_mem(struct ir3_instruction *instr)
|
|||
return (instr->category == 6);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_store(struct ir3_instruction *instr)
|
||||
{
|
||||
if (is_mem(instr)) {
|
||||
/* these instructions, the "destination" register is
|
||||
* actually a source, the address to store to.
|
||||
*/
|
||||
switch (instr->opc) {
|
||||
case OPC_STG:
|
||||
case OPC_STP:
|
||||
case OPC_STL:
|
||||
case OPC_STLW:
|
||||
case OPC_L2G:
|
||||
case OPC_G2L:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_input(struct ir3_instruction *instr)
|
||||
{
|
||||
/* in some cases, ldlv is used to fetch varying without
|
||||
|
|
@ -527,7 +555,7 @@ static inline bool writes_addr(struct ir3_instruction *instr)
|
|||
{
|
||||
if (instr->regs_count > 0) {
|
||||
struct ir3_register *dst = instr->regs[0];
|
||||
return !!(dst->flags & IR3_REG_ADDR);
|
||||
return reg_num(dst) == REG_A0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -558,7 +586,7 @@ static inline bool conflicts(struct ir3_instruction *a,
|
|||
|
||||
static inline bool reg_gpr(struct ir3_register *r)
|
||||
{
|
||||
if (r->flags & (IR3_REG_CONST | IR3_REG_IMMED | IR3_REG_ADDR))
|
||||
if (r->flags & (IR3_REG_CONST | IR3_REG_IMMED))
|
||||
return false;
|
||||
if ((reg_num(r) == REG_A0) || (reg_num(r) == REG_P0))
|
||||
return false;
|
||||
|
|
@ -771,6 +799,7 @@ void ir3_block_group(struct ir3_block *block);
|
|||
int ir3_block_sched(struct ir3_block *block);
|
||||
|
||||
/* register assignment: */
|
||||
struct ir3_ra_reg_set * ir3_ra_alloc_reg_set(void *memctx);
|
||||
int ir3_block_ra(struct ir3_block *block, enum shader_t type,
|
||||
bool frag_coord, bool frag_face);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ struct ir3_compiler * ir3_compiler_create(uint32_t gpu_id)
|
|||
{
|
||||
struct ir3_compiler *compiler = rzalloc(NULL, struct ir3_compiler);
|
||||
compiler->gpu_id = gpu_id;
|
||||
compiler->set = ir3_ra_alloc_reg_set(compiler);
|
||||
return compiler;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,11 @@
|
|||
|
||||
#include "ir3_shader.h"
|
||||
|
||||
struct ir3_ra_reg_set;
|
||||
|
||||
struct ir3_compiler {
|
||||
uint32_t gpu_id;
|
||||
struct ir3_ra_reg_set *set;
|
||||
};
|
||||
|
||||
struct ir3_compiler * ir3_compiler_create(uint32_t gpu_id);
|
||||
|
|
|
|||
|
|
@ -385,7 +385,8 @@ create_addr(struct ir3_block *block, struct ir3_instruction *src)
|
|||
instr->regs[1]->flags |= IR3_REG_HALF;
|
||||
|
||||
instr = ir3_MOV(block, instr, TYPE_S16);
|
||||
instr->regs[0]->flags |= IR3_REG_ADDR | IR3_REG_HALF;
|
||||
instr->regs[0]->num = regid(REG_A0, 0);
|
||||
instr->regs[0]->flags |= IR3_REG_HALF;
|
||||
instr->regs[1]->flags |= IR3_REG_HALF;
|
||||
|
||||
return instr;
|
||||
|
|
@ -589,6 +590,7 @@ create_frag_face(struct ir3_compile *ctx, unsigned comp)
|
|||
compile_assert(ctx, !ctx->frag_face);
|
||||
|
||||
ctx->frag_face = create_input(block, NULL, 0);
|
||||
ctx->frag_face->regs[0]->flags |= IR3_REG_HALF;
|
||||
|
||||
/* for faceness, we always get -1 or 0 (int).. but TGSI expects
|
||||
* positive vs negative float.. and piglit further seems to
|
||||
|
|
@ -1981,9 +1983,18 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
|
|||
*/
|
||||
if (key.half_precision) {
|
||||
for (i = 0; i < block->noutputs; i++) {
|
||||
if (!block->outputs[i])
|
||||
struct ir3_instruction *out = block->outputs[i];
|
||||
if (!out)
|
||||
continue;
|
||||
block->outputs[i]->regs[0]->flags |= IR3_REG_HALF;
|
||||
out->regs[0]->flags |= IR3_REG_HALF;
|
||||
/* output could be a fanout (ie. texture fetch output)
|
||||
* in which case we need to propagate the half-reg flag
|
||||
* up to the definer so that RA sees it:
|
||||
*/
|
||||
if (is_meta(out) && (out->opc == OPC_META_FO)) {
|
||||
out = out->regs[1]->instr;
|
||||
out->regs[0]->flags |= IR3_REG_HALF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ static bool is_eligible_mov(struct ir3_instruction *instr, bool allow_flags)
|
|||
struct ir3_register *dst = instr->regs[0];
|
||||
struct ir3_register *src = instr->regs[1];
|
||||
struct ir3_instruction *src_instr = ssa(src);
|
||||
if (dst->flags & (IR3_REG_ADDR | IR3_REG_RELATIV))
|
||||
if (dst->flags & IR3_REG_RELATIV)
|
||||
return false;
|
||||
if (src->flags & IR3_REG_RELATIV)
|
||||
return false;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue