i965/vec4: Add wrapper functions for vec4_instruction::regs_read and ::regs_written.
authorFrancisco Jerez <currojerez@riseup.net>
Thu, 1 Sep 2016 23:55:46 +0000 (16:55 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Wed, 14 Sep 2016 21:50:53 +0000 (14:50 -0700)
This is in preparation for dropping vec4_instruction::regs_read and
::regs_written in favor of more accurate alternatives expressed in
byte units.  The main reason these wrappers are useful is that a
number of optimization passes implement dataflow analysis with
register granularity, so these helpers will come in handy once we've
switched register offsets and sizes to the byte representation.  The
wrapper functions will also make sure that GRF misalignment (currently
neglected by most of the back-end) is taken into account correctly in
the calculation of regs_read and regs_written.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
src/mesa/drivers/dri/i965/brw_ir_vec4.h
src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
src/mesa/drivers/dri/i965/brw_vec4.cpp
src/mesa/drivers/dri/i965/brw_vec4_cse.cpp
src/mesa/drivers/dri/i965/brw_vec4_dead_code_eliminate.cpp
src/mesa/drivers/dri/i965/brw_vec4_live_variables.cpp

index 4f49428ef3f82b5f905eae54b26dab1b66646ac9..a1a201b8b5f2f98d3670e3308b95f412b87e086a 100644 (file)
@@ -254,6 +254,32 @@ set_saturate(bool saturate, vec4_instruction *inst)
    return inst;
 }
 
+/**
+ * Return the number of dataflow registers written by the instruction (either
+ * fully or partially) counted from 'floor(reg_offset(inst->dst) /
+ * register_size)'.  The somewhat arbitrary register size unit is 16B for the
+ * UNIFORM and IMM files and 32B for all other files.
+ */
+inline unsigned
+regs_written(const vec4_instruction *inst)
+{
+   /* XXX - Take into account register-misaligned offsets correctly. */
+   return inst->regs_written;
+}
+
+/**
+ * Return the number of dataflow registers read by the instruction (either
+ * fully or partially) counted from 'floor(reg_offset(inst->src[i]) /
+ * register_size)'.  The somewhat arbitrary register size unit is 16B for the
+ * UNIFORM and IMM files and 32B for all other files.
+ */
+inline unsigned
+regs_read(const vec4_instruction *inst, unsigned i)
+{
+   /* XXX - Take into account register-misaligned offsets correctly. */
+   return inst->regs_read(i);
+}
+
 } /* namespace brw */
 
 #endif
index 0d3a07cad5b5b419655422164b1529c2e81f96e1..c12bf09e8359ff748e120b18cf0e294f2c6de439 100644 (file)
@@ -1269,7 +1269,7 @@ vec4_instruction_scheduler::calculate_deps()
       /* read-after-write deps. */
       for (int i = 0; i < 3; i++) {
          if (inst->src[i].file == VGRF) {
-            for (unsigned j = 0; j < inst->regs_read(i); ++j)
+            for (unsigned j = 0; j < regs_read(inst, i); ++j)
                add_dep(last_grf_write[inst->src[i].nr + j], n);
          } else if (inst->src[i].file == FIXED_GRF) {
             add_dep(last_fixed_grf_write, n);
@@ -1303,7 +1303,7 @@ vec4_instruction_scheduler::calculate_deps()
 
       /* write-after-write deps. */
       if (inst->dst.file == VGRF) {
-         for (unsigned j = 0; j < inst->regs_written; ++j) {
+         for (unsigned j = 0; j < regs_written(inst); ++j) {
             add_dep(last_grf_write[inst->dst.nr + j], n);
             last_grf_write[inst->dst.nr + j] = n;
          }
@@ -1351,7 +1351,7 @@ vec4_instruction_scheduler::calculate_deps()
       /* write-after-read deps. */
       for (int i = 0; i < 3; i++) {
          if (inst->src[i].file == VGRF) {
-            for (unsigned j = 0; j < inst->regs_read(i); ++j)
+            for (unsigned j = 0; j < regs_read(inst, i); ++j)
                add_dep(n, last_grf_write[inst->src[i].nr + j]);
          } else if (inst->src[i].file == FIXED_GRF) {
             add_dep(n, last_fixed_grf_write);
@@ -1384,7 +1384,7 @@ vec4_instruction_scheduler::calculate_deps()
        * can mark this as WAR dependency.
        */
       if (inst->dst.file == VGRF) {
-         for (unsigned j = 0; j < inst->regs_written; ++j)
+         for (unsigned j = 0; j < regs_written(inst); ++j)
             last_grf_write[inst->dst.nr + j] = n;
       } else if (inst->dst.file == MRF) {
          last_mrf_write[inst->dst.nr] = n;
index de5b5d6c838d4b33bfc2c57e07e9897dfafc917f..3e57addb7a4688a460dec1ecaeac158cace7257c 100644 (file)
@@ -1335,11 +1335,11 @@ vec4_visitor::split_virtual_grfs()
     * to split.
     */
    foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
-      if (inst->dst.file == VGRF && inst->regs_written > 1)
+      if (inst->dst.file == VGRF && regs_written(inst) > 1)
          split_grf[inst->dst.nr] = false;
 
       for (int i = 0; i < 3; i++) {
-         if (inst->src[i].file == VGRF && inst->regs_read(i) > 1)
+         if (inst->src[i].file == VGRF && regs_read(inst, i) > 1)
             split_grf[inst->src[i].nr] = false;
       }
    }
index 10898a5917d84400d32b1ad781aa58769a4a1a30..f0908b93fc957b4fb32dd3d60c1ab9e163a657ac 100644 (file)
@@ -178,10 +178,10 @@ vec4_visitor::opt_cse_local(bblock_t *block)
             bool no_existing_temp = entry->tmp.file == BAD_FILE;
             if (no_existing_temp && !entry->generator->dst.is_null()) {
                entry->tmp = retype(src_reg(VGRF, alloc.allocate(
-                                              entry->generator->regs_written),
+                                              regs_written(entry->generator)),
                                            NULL), inst->dst.type);
 
-               for (unsigned i = 0; i < entry->generator->regs_written; ++i) {
+               for (unsigned i = 0; i < regs_written(entry->generator); ++i) {
                   vec4_instruction *copy = MOV(offset(entry->generator->dst, i),
                                                offset(entry->tmp, i));
                   copy->force_writemask_all =
@@ -196,7 +196,7 @@ vec4_visitor::opt_cse_local(bblock_t *block)
             if (!inst->dst.is_null()) {
                assert(inst->dst.type == entry->tmp.type);
 
-               for (unsigned i = 0; i < inst->regs_written; ++i) {
+               for (unsigned i = 0; i < regs_written(inst); ++i) {
                   vec4_instruction *copy = MOV(offset(inst->dst, i),
                                                offset(entry->tmp, i));
                   copy->force_writemask_all = inst->force_writemask_all;
index c643212494b24b841772aef4d7443996431dd4ee..50706a977cb64ac33fa9829577a965cc3385c231 100644 (file)
@@ -59,7 +59,7 @@ vec4_visitor::dead_code_eliminate()
             bool result_live[4] = { false };
 
             if (inst->dst.file == VGRF) {
-               for (unsigned i = 0; i < inst->regs_written; i++) {
+               for (unsigned i = 0; i < regs_written(inst); i++) {
                   for (int c = 0; c < 4; c++)
                      result_live[c] |= BITSET_TEST(
                         live, var_from_reg(alloc, offset(inst->dst, i), c));
@@ -110,7 +110,7 @@ vec4_visitor::dead_code_eliminate()
          }
 
          if (inst->dst.file == VGRF && !inst->predicate) {
-            for (unsigned i = 0; i < inst->regs_written; i++) {
+            for (unsigned i = 0; i < regs_written(inst); i++) {
                for (int c = 0; c < 4; c++) {
                   if (inst->dst.writemask & (1 << c)) {
                      BITSET_CLEAR(live, var_from_reg(alloc,
@@ -132,7 +132,7 @@ vec4_visitor::dead_code_eliminate()
 
          for (int i = 0; i < 3; i++) {
             if (inst->src[i].file == VGRF) {
-               for (unsigned j = 0; j < inst->regs_read(i); j++) {
+               for (unsigned j = 0; j < regs_read(inst, i); j++) {
                   for (int c = 0; c < 4; c++) {
                      BITSET_SET(live, var_from_reg(alloc,
                                                    offset(inst->src[i], j), c));
index 57d5fbb75dd648c045903830ccc7b89b51c395a1..20344ed17708586afc96247f993b7170cb2717b9 100644 (file)
@@ -76,7 +76,7 @@ vec4_live_variables::setup_def_use()
         /* Set use[] for this instruction */
         for (unsigned int i = 0; i < 3; i++) {
            if (inst->src[i].file == VGRF) {
-               for (unsigned j = 0; j < inst->regs_read(i); j++) {
+               for (unsigned j = 0; j < regs_read(inst, i); j++) {
                   for (int c = 0; c < 4; c++) {
                      const unsigned v =
                         var_from_reg(alloc, offset(inst->src[i], j), c);
@@ -99,7 +99,7 @@ vec4_live_variables::setup_def_use()
          */
         if (inst->dst.file == VGRF &&
             (!inst->predicate || inst->opcode == BRW_OPCODE_SEL)) {
-            for (unsigned i = 0; i < inst->regs_written; i++) {
+            for (unsigned i = 0; i < regs_written(inst); i++) {
                for (int c = 0; c < 4; c++) {
                   if (inst->dst.writemask & (1 << c)) {
                      const unsigned v =
@@ -257,7 +257,7 @@ vec4_visitor::calculate_live_intervals()
    foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
       for (unsigned int i = 0; i < 3; i++) {
         if (inst->src[i].file == VGRF) {
-            for (unsigned j = 0; j < inst->regs_read(i); j++) {
+            for (unsigned j = 0; j < regs_read(inst, i); j++) {
                for (int c = 0; c < 4; c++) {
                   const unsigned v =
                      var_from_reg(alloc, offset(inst->src[i], j), c);
@@ -269,7 +269,7 @@ vec4_visitor::calculate_live_intervals()
       }
 
       if (inst->dst.file == VGRF) {
-         for (unsigned i = 0; i < inst->regs_written; i++) {
+         for (unsigned i = 0; i < regs_written(inst); i++) {
             for (int c = 0; c < 4; c++) {
                if (inst->dst.writemask & (1 << c)) {
                   const unsigned v =