From 36bc5f06dd22cde0ba572c00ae7548fe8cb7c731 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Sun, 26 Oct 2014 22:07:06 -0700 Subject: [PATCH] i965/fs: Allow immediates in MAD and LRP instructions. And then the opt_combine_constants() pass will pull them out into registers. This will allow us to do some algebraic optimizations on MAD and LRP. total instructions in shared programs: 5946656 -> 5931320 (-0.26%) instructions in affected programs: 778247 -> 762911 (-1.97%) helped: 3780 HURT: 6 GAINED: 12 LOST: 12 Reviewed-by: Kenneth Graunke --- .../drivers/dri/i965/brw_fs_combine_constants.cpp | 30 +++++++++++++++++++--- .../drivers/dri/i965/brw_fs_copy_propagation.cpp | 6 +++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp b/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp index c389908fda4..6acd3fef95c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp @@ -58,6 +58,21 @@ could_coissue(const struct brw_context *brw, const fs_inst *inst) } } +/** + * Returns true for instructions that don't support immediate sources. + */ +static bool +must_promote_imm(const fs_inst *inst) +{ + switch (inst->opcode) { + case BRW_OPCODE_MAD: + case BRW_OPCODE_LRP: + return true; + default: + return false; + } +} + /** A box for putting fs_regs in a linked list. */ struct reg_link { DECLARE_RALLOC_CXX_OPERATORS(reg_link) @@ -107,6 +122,12 @@ struct imm { /** The number of coissuable instructions using this immediate. */ uint16_t uses_by_coissue; + /** + * Whether this constant is used by an instruction that can't handle an + * immediate source (and already has to be promoted to a GRF). + */ + bool must_promote; + uint16_t first_use_ip; uint16_t last_use_ip; }; @@ -180,12 +201,13 @@ fs_visitor::opt_combine_constants() unsigned ip = -1; /* Make a pass through all instructions and count the number of times each - * constant is used by coissueable instructions. + * constant is used by coissueable instructions or instructions that cannot + * take immediate arguments. */ foreach_block_and_inst(block, fs_inst, inst, cfg) { ip++; - if (!could_coissue(brw, inst)) + if (!could_coissue(brw, inst) && !must_promote_imm(inst)) continue; for (int i = 0; i < inst->sources; i++) { @@ -203,6 +225,7 @@ fs_visitor::opt_combine_constants() imm->block = intersection; imm->uses->push_tail(link(const_ctx, &inst->src[i])); imm->uses_by_coissue += could_coissue(brw, inst); + imm->must_promote = imm->must_promote || must_promote_imm(inst); imm->last_use_ip = ip; } else { imm = new_imm(&table, const_ctx); @@ -212,6 +235,7 @@ fs_visitor::opt_combine_constants() imm->uses->push_tail(link(const_ctx, &inst->src[i])); imm->val = val; imm->uses_by_coissue = could_coissue(brw, inst); + imm->must_promote = must_promote_imm(inst); imm->first_use_ip = ip; imm->last_use_ip = ip; } @@ -224,7 +248,7 @@ fs_visitor::opt_combine_constants() for (int i = 0; i < table.len;) { struct imm *imm = &table.imm[i]; - if (imm->uses_by_coissue < 4) { + if (!imm->must_promote && imm->uses_by_coissue < 4) { table.imm[i] = table.imm[table.len - 1]; table.len--; continue; diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp index 3bc4435ac92..e265ce0fd8c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp @@ -576,6 +576,12 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry) progress = true; break; + case BRW_OPCODE_MAD: + case BRW_OPCODE_LRP: + inst->src[i] = val; + progress = true; + break; + default: break; } -- 2.11.0