agx: Preload vertex/instance ID only at start
This means we don't reserve the registers, which improves RA considerably. Using a special preload psuedo-op instead of a regular move allows us to constrain semantics and gaurantee coalescing. shader-db on glmark2 subset: total instructions in shared programs: 6448 -> 6442 (-0.09%) instructions in affected programs: 230 -> 224 (-2.61%) helped: 4 HURT: 0 total bytes in shared programs: 42232 -> 42196 (-0.09%) bytes in affected programs: 1530 -> 1494 (-2.35%) helped: 4 HURT: 0 total halfregs in shared programs: 2291 -> 1926 (-15.93%) halfregs in affected programs: 2185 -> 1820 (-16.70%) helped: 75 HURT: 0 Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18804>
This commit is contained in:

committed by
Marge Bot

parent
f665229d77
commit
c9a96d4615
@@ -396,6 +396,11 @@ typedef struct {
|
||||
* components, populated by a split. */
|
||||
struct hash_table_u64 *allocated_vec;
|
||||
|
||||
/* During instruction selection, preloaded values,
|
||||
* or NULL if it hasn't been preloaded
|
||||
*/
|
||||
agx_index vertex_id, instance_id;
|
||||
|
||||
/* Stats for shader-db */
|
||||
unsigned loop_count;
|
||||
unsigned spills;
|
||||
@@ -456,6 +461,20 @@ agx_vec_for_intr(agx_context *ctx, nir_intrinsic_instr *instr)
|
||||
return agx_vec_for_dest(ctx, &instr->dest);
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
agx_num_predecessors(agx_block *block)
|
||||
{
|
||||
return util_dynarray_num_elements(&block->predecessors, agx_block *);
|
||||
}
|
||||
|
||||
static inline agx_block *
|
||||
agx_start_block(agx_context *ctx)
|
||||
{
|
||||
agx_block *first = list_first_entry(&ctx->blocks, agx_block, link);
|
||||
assert(agx_num_predecessors(first) == 0);
|
||||
return first;
|
||||
}
|
||||
|
||||
/* Iterators for AGX IR */
|
||||
|
||||
#define agx_foreach_block(ctx, v) \
|
||||
@@ -650,6 +669,25 @@ agx_after_block_logical(agx_block *block)
|
||||
return agx_after_block(block);
|
||||
}
|
||||
|
||||
|
||||
static inline agx_cursor
|
||||
agx_before_nonempty_block(agx_block *block)
|
||||
{
|
||||
agx_instr *I = list_first_entry(&block->instructions, agx_instr, link);
|
||||
assert(I != NULL);
|
||||
|
||||
return agx_before_instr(I);
|
||||
}
|
||||
|
||||
static inline agx_cursor
|
||||
agx_before_block(agx_block *block)
|
||||
{
|
||||
if (list_is_empty(&block->instructions))
|
||||
return agx_after_block(block);
|
||||
else
|
||||
return agx_before_nonempty_block(block);
|
||||
}
|
||||
|
||||
/* IR builder in terms of cursor infrastructure */
|
||||
|
||||
typedef struct {
|
||||
|
Reference in New Issue
Block a user