i965/vec4: track and use independently each flag channel
authorAlejandro Piñeiro <apinheiro@igalia.com>
Wed, 14 Oct 2015 18:26:43 +0000 (20:26 +0200)
committerAlejandro Piñeiro <apinheiro@igalia.com>
Thu, 22 Oct 2015 19:58:03 +0000 (21:58 +0200)
vec4_live_variables tracks now each flag channel independently, so
vec4_dead_code_eliminate can update the writemask of null registers,
based on which component are alive at the moment. This would allow
vec4_cmod_propagation to optimize out several movs involving null
registers.

v2: added support to track each flag channel independently at vec4
    live_variables, as v1 assumed that it was already doing it, as
    pointed by Francisco Jerez
v3: general cleaningn after Matt Turner's review

Reviewed-by: Matt Turner <mattst88@gmail.com>
src/mesa/drivers/dri/i965/brw_ir_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp
src/mesa/drivers/dri/i965/brw_vec4_live_variables.cpp

index 1b57b65db27613275e4390f9ca1cf78155175fc8..74e9733bd4423fba4e81e0a7808d16e3fdfed842 100644 (file)
@@ -186,6 +186,27 @@ public:
       return predicate || opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2;
    }
 
+   bool reads_flag(unsigned c)
+   {
+      if (!reads_flag())
+         return false;
+
+      switch (predicate) {
+      case BRW_PREDICATE_NONE:
+         return false;
+      case BRW_PREDICATE_ALIGN16_REPLICATE_X:
+         return c == 0;
+      case BRW_PREDICATE_ALIGN16_REPLICATE_Y:
+         return c == 1;
+      case BRW_PREDICATE_ALIGN16_REPLICATE_Z:
+         return c == 2;
+      case BRW_PREDICATE_ALIGN16_REPLICATE_W:
+         return c == 3;
+      default:
+         return true;
+      }
+   }
+
    bool writes_flag()
    {
       return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
index 8fc7a365bfca28a7b5f5698e6e4091aa6dc5fd49..284e0a8d0a5b569187eeb2919f144fae27d9b118 100644 (file)
@@ -78,13 +78,19 @@ vec4_visitor::dead_code_eliminate()
              sizeof(BITSET_WORD));
 
       foreach_inst_in_block_reverse(vec4_instruction, inst, block) {
-         if (inst->dst.file == GRF && !inst->has_side_effects()) {
+         if ((inst->dst.file == GRF && !inst->has_side_effects()) ||
+             (inst->dst.is_null() && inst->writes_flag())){
             bool result_live[4] = { false };
 
-            for (unsigned i = 0; i < inst->regs_written; i++) {
-               for (int c = 0; c < 4; c++)
-                  result_live[c] |= BITSET_TEST(
-                     live, var_from_reg(alloc, offset(inst->dst, i), c));
+            if (inst->dst.file == GRF) {
+               for (unsigned i = 0; i < inst->regs_written; i++) {
+                  for (int c = 0; c < 4; c++)
+                     result_live[c] |= BITSET_TEST(
+                        live, var_from_reg(alloc, offset(inst->dst, i), c));
+               }
+            } else {
+               for (unsigned c = 0; c < 4; c++)
+                  result_live[c] = BITSET_TEST(flag_live, c);
             }
 
             /* If the instruction can't do writemasking, then it's all or
@@ -117,7 +123,11 @@ vec4_visitor::dead_code_eliminate()
          }
 
          if (inst->dst.is_null() && inst->writes_flag()) {
-            if (!BITSET_TEST(flag_live, 0)) {
+            bool combined_live = false;
+            for (unsigned c = 0; c < 4; c++)
+               combined_live |= BITSET_TEST(flag_live, c);
+
+            if (!combined_live) {
                inst->opcode = BRW_OPCODE_NOP;
                progress = true;
                continue;
@@ -136,7 +146,8 @@ vec4_visitor::dead_code_eliminate()
          }
 
          if (inst->writes_flag()) {
-            BITSET_CLEAR(flag_live, 0);
+            for (unsigned c = 0; c < 4; c++)
+               BITSET_CLEAR(flag_live, c);
          }
 
          for (int i = 0; i < 3; i++) {
@@ -150,8 +161,10 @@ vec4_visitor::dead_code_eliminate()
             }
          }
 
-         if (inst->reads_flag()) {
-            BITSET_SET(flag_live, 0);
+         for (unsigned c = 0; c < 4; c++) {
+            if (inst->reads_flag(c)) {
+               BITSET_SET(flag_live, c);
+            }
          }
       }
    }
index 678237901f23cb35692ee0d613e53fc830eaf9e5..aa9a6572eee36e02aaedad63108d8c09ac3ed55f 100644 (file)
@@ -86,9 +86,10 @@ vec4_live_variables::setup_def_use()
                }
            }
         }
-         if (inst->reads_flag()) {
-            if (!BITSET_TEST(bd->flag_def, 0)) {
-               BITSET_SET(bd->flag_use, 0);
+         for (unsigned c = 0; c < 4; c++) {
+            if (inst->reads_flag(c) &&
+                !BITSET_TEST(bd->flag_def, c)) {
+               BITSET_SET(bd->flag_use, c);
             }
          }
 
@@ -110,8 +111,11 @@ vec4_live_variables::setup_def_use()
             }
          }
          if (inst->writes_flag()) {
-            if (!BITSET_TEST(bd->flag_use, 0)) {
-               BITSET_SET(bd->flag_def, 0);
+            for (unsigned c = 0; c < 4; c++) {
+               if ((inst->dst.writemask & (1 << c)) &&
+                   !BITSET_TEST(bd->flag_use, c)) {
+                  BITSET_SET(bd->flag_def, c);
+               }
             }
          }