From aa43ac4e7cfadecb23cca02e2de209e6f7c3d736 Mon Sep 17 00:00:00 2001 From: Christoph Pillmayer Date: Tue, 19 Aug 2025 11:09:27 +0000 Subject: [PATCH] pan/bi: Move some constants into FAU entries Following on the previous commit, this commit adds support for selecting and reporting constants to pull from the FAU instead of loading them into registers first with ADD_IMM. This is beneficial because we can then use them as a source directly and save ourselves one instruction to move them into the register first. Reviewed-by: Mary Guillemard Part-of: --- src/panfrost/compiler/bifrost_compile.c | 4 +++ src/panfrost/compiler/compiler.h | 3 ++ .../compiler/valhall/va_lower_constants.c | 34 ++++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/panfrost/compiler/bifrost_compile.c b/src/panfrost/compiler/bifrost_compile.c index 3e51e49703f..ef04834f22b 100644 --- a/src/panfrost/compiler/bifrost_compile.c +++ b/src/panfrost/compiler/bifrost_compile.c @@ -6111,6 +6111,7 @@ bi_compile_variant_nir(nir_shader *nir, ctx->info = info; ctx->idvs = idvs; ctx->malloc_idvs = (ctx->arch >= 9) && !inputs->no_idvs; + ctx->fau_consts_count = info.init_fau_consts_count; unsigned execution_mode = nir->info.float_controls_execution_mode; ctx->rtz_fp16 = nir_is_rounding_mode_rtz(execution_mode, 16); @@ -6377,6 +6378,7 @@ bi_compile_variant(nir_shader *nir, .bifrost = &info->bifrost, .tls_size = info->tls_size, .push_offset = info->push.count, + .init_fau_consts_count = info->fau_consts_count, }; unsigned offset = binary->size; @@ -6399,6 +6401,8 @@ bi_compile_variant(nir_shader *nir, bi_context *ctx = bi_compile_variant_nir(nir, inputs, binary, local_info, stats, idvs); + info->fau_consts_count = ctx->fau_consts_count; + /* A register is preloaded <==> it is live before the first block */ bi_block *first_block = list_first_entry(&ctx->blocks, bi_block, link); uint64_t preload = first_block->reg_live_in; diff --git a/src/panfrost/compiler/compiler.h b/src/panfrost/compiler/compiler.h index d13551ca961..9c2c44e3750 100644 --- a/src/panfrost/compiler/compiler.h +++ b/src/panfrost/compiler/compiler.h @@ -981,6 +981,7 @@ struct bi_shader_info { unsigned tls_size; unsigned work_reg_count; unsigned push_offset; + unsigned init_fau_consts_count; bool has_ld_gclk_instr; }; @@ -1042,6 +1043,8 @@ typedef struct { */ bi_index preloaded[BI_MAX_REGS]; + uint32_t fau_consts_count; + /* For creating temporaries */ unsigned ssa_alloc; unsigned reg_alloc; diff --git a/src/panfrost/compiler/valhall/va_lower_constants.c b/src/panfrost/compiler/valhall/va_lower_constants.c index a6e6a9d546b..03cc0920c3e 100644 --- a/src/panfrost/compiler/valhall/va_lower_constants.c +++ b/src/panfrost/compiler/valhall/va_lower_constants.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2025 Arm Ltd. * Copyright (C) 2021 Collabora Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -108,6 +109,32 @@ is_extension_of_16(uint32_t x, bool is_signed) return (x <= UINT16_MAX); } +static bi_index +va_move_const_to_fau(bi_builder *b, uint32_t value) +{ + const unsigned push_base = b->shader->inputs->fau_consts.offset; + uint32_t *values = b->shader->inputs->fau_consts.values; + + assert(b->shader->inputs->fau_consts.max_amount == 0 || values != NULL); + assert(b->shader->fau_consts_count <= + b->shader->inputs->fau_consts.max_amount); + + for (unsigned i = 0; i < b->shader->fau_consts_count; ++i) { + if (values[i] == value) { + const unsigned idx = push_base + i; + return bi_fau((enum bir_fau)(BIR_FAU_UNIFORM | (idx >> 1)), idx & 1); + } + } + + if (b->shader->fau_consts_count < b->shader->inputs->fau_consts.max_amount) { + const unsigned int idx = push_base + b->shader->fau_consts_count; + values[b->shader->fau_consts_count++] = value; + return bi_fau((enum bir_fau)(BIR_FAU_UNIFORM | (idx >> 1)), idx & 1); + } + + return bi_null(); +} + static bi_index va_resolve_constant(bi_builder *b, uint32_t value, struct va_src_info info, bool is_signed, bool staging) @@ -179,7 +206,12 @@ va_resolve_constant(bi_builder *b, uint32_t value, struct va_src_info info, } } - /* TODO: Optimize to uniform */ + if (!staging) { + bi_index c = va_move_const_to_fau(b, value); + if (!bi_is_null(c)) + return c; + } + return va_mov_imm(b, value); }