From 4c2c49f7bcdf0686b1f7689624b813784aedf4bd Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 12 Apr 2024 15:41:34 -0700 Subject: [PATCH] intel/brw: Add builder helpers that allocate temporary destinations In many cases, we calculate an expression by generating a series of instructions. We'd either overwrite the same register repeatedly, or call vgrf(BRW_TYPE_X) repeatedly to allocate temporaries for each intermediate step. In many cases, we overwrote the same register simply because allocating and naming temporaries for each step was annoying. This commit adds new builder helpers that will allocate a temporary destination for you, using simple type interference: unary operations use the source type, and binary operations require a matching base type and return the largest of the two types. The helpers return the destination register, allowing us to write in an expression-tree style, chaining together builder operations to produce whole values. Sort of like nir_builder. We still optionally will write out the fs_inst pointer in case the caller wants to do things like set predicates or saturation. Reviewed-by: Lionel Landwerlin Part-of: --- src/intel/compiler/brw_fs_builder.h | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/intel/compiler/brw_fs_builder.h b/src/intel/compiler/brw_fs_builder.h index afad15a24a8..a83a82775b6 100644 --- a/src/intel/compiler/brw_fs_builder.h +++ b/src/intel/compiler/brw_fs_builder.h @@ -553,15 +553,30 @@ namespace brw { (dst.file >= VGRF && dst.stride != 0) || \ (dst.file < VGRF && dst.hstride != 0)); \ return emit(prefix##op, dst, src0); \ + } \ + fs_reg \ + op(const fs_reg &src0, fs_inst **out = NULL) const \ + { \ + fs_inst *inst = op(vgrf(src0.type), src0); \ + if (out) *out = inst; \ + return inst->dst; \ } #define ALU1(op) _ALU1(BRW_OPCODE_, op) #define VIRT1(op) _ALU1(SHADER_OPCODE_, op) -#define _ALU2(prefix, op) \ - fs_inst * \ - op(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1) const \ - { \ - return emit(prefix##op, dst, src0, src1); \ +#define _ALU2(prefix, op) \ + fs_inst * \ + op(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1) const \ + { \ + return emit(prefix##op, dst, src0, src1); \ + } \ + fs_reg \ + op(const fs_reg &src0, const fs_reg &src1, fs_inst **out = NULL) const \ + { \ + assert(src0.type == src1.type); \ + fs_inst *inst = op(vgrf(src0.type), src0, src1); \ + if (out) *out = inst; \ + return inst->dst; \ } #define ALU2(op) _ALU2(BRW_OPCODE_, op) #define VIRT2(op) _ALU2(SHADER_OPCODE_, op)