aco: copy-propagate constants through p_extract_vector/p_split_vector
authorRhys Perry <pendingchaos02@gmail.com>
Mon, 18 May 2020 18:42:40 +0000 (19:42 +0100)
committerMarge Bot <eric+marge@anholt.net>
Mon, 15 Jun 2020 18:24:22 +0000 (18:24 +0000)
fossil-db (Navi, fp16 enabled):
Totals from 1 (0.00% of 127638) affected shaders:
CodeSize: 4388 -> 4392 (+0.09%)
VMEM: 465 -> 458 (-1.51%)
Copies: 54 -> 55 (+1.85%)

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5245>

src/amd/compiler/aco_optimizer.cpp

index 58d22910150a2ee1456796c19e326994b3c63382..82b9cb771853e859538910d6966b6e37601081cf 100644 (file)
@@ -1034,8 +1034,20 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr<Instruction>& instr)
       break;
    }
    case aco_opcode::p_split_vector: {
-      if (!ctx.info[instr->operands[0].tempId()].is_vec())
+      ssa_info& info = ctx.info[instr->operands[0].tempId()];
+
+      if (info.is_constant_or_literal(32)) {
+         uint32_t val = info.val;
+         for (Definition def : instr->definitions) {
+            uint32_t mask = u_bit_consecutive(0, def.bytes() * 8u);
+            ctx.info[def.tempId()].set_constant(ctx.program->chip_class, val & mask);
+            val >>= def.bytes() * 8u;
+         }
+         break;
+      } else if (!info.is_vec()) {
          break;
+      }
+
       Instruction* vec = ctx.info[instr->operands[0].tempId()].instr;
       unsigned split_offset = 0;
       unsigned vec_offset = 0;
@@ -1060,13 +1072,20 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr<Instruction>& instr)
       break;
    }
    case aco_opcode::p_extract_vector: { /* mov */
-      if (!ctx.info[instr->operands[0].tempId()].is_vec())
+      ssa_info& info = ctx.info[instr->operands[0].tempId()];
+      const unsigned index = instr->operands[1].constantValue();
+      const unsigned dst_offset = index * instr->definitions[0].bytes();
+
+      if (info.is_constant_or_literal(32)) {
+         uint32_t mask = u_bit_consecutive(0, instr->definitions[0].bytes() * 8u);
+         ctx.info[instr->definitions[0].tempId()].set_constant(ctx.program->chip_class, (info.val >> (dst_offset * 8u)) & mask);
+         break;
+      } else if (!info.is_vec()) {
          break;
+      }
 
       /* check if we index directly into a vector element */
-      Instruction* vec = ctx.info[instr->operands[0].tempId()].instr;
-      const unsigned index = instr->operands[1].constantValue();
-      const unsigned dst_offset = index * instr->definitions[0].bytes();
+      Instruction* vec = info.instr;
       unsigned offset = 0;
 
       for (const Operand& op : vec->operands) {