[Mesa-dev] [PATCH 10/11] glsl_to_tgsi: handle reladdr as TEMP in rename_temp_registers and dead_code

Marek Olšák maraeo at gmail.com
Fri Sep 29 12:25:33 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 60 ++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 16 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index b2345b8..e9d98ed 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -4599,53 +4599,61 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
 
          inst->op = TGSI_OPCODE_MOV;
          inst->info = tgsi_get_opcode_info(inst->op);
          inst->src[0] = inst->src[1];
       }
    }
 
    free(tempWrites);
 }
 
+static void
+rename_temp_handle_src(struct rename_reg_pair *renames,
+                           struct st_src_reg *src)
+{
+   if (src && src->file == PROGRAM_TEMPORARY) {
+      int old_idx = src->index;
+      if (renames[old_idx].valid)
+         src->index = renames[old_idx].new_reg;
+   }
+}
+
 /* Replaces all references to a temporary register index with another index. */
 void
 glsl_to_tgsi_visitor::rename_temp_registers(struct rename_reg_pair *renames)
 {
    foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
       unsigned j;
       for (j = 0; j < num_inst_src_regs(inst); j++) {
-         if (inst->src[j].file == PROGRAM_TEMPORARY) {
-            int old_idx = inst->src[j].index;
-            if (renames[old_idx].valid)
-               inst->src[j].index = renames[old_idx].new_reg;
-         }
+         rename_temp_handle_src(renames, &inst->src[j]);
+         rename_temp_handle_src(renames, inst->src[j].reladdr);
+         rename_temp_handle_src(renames, inst->src[j].reladdr2);
       }
 
       for (j = 0; j < inst->tex_offset_num_offset; j++) {
-         if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY) {
-            int old_idx = inst->tex_offsets[j].index;
-            if (renames[old_idx].valid)
-               inst->tex_offsets[j].index = renames[old_idx].new_reg;
-         }
+         rename_temp_handle_src(renames, &inst->tex_offsets[j]);
+         rename_temp_handle_src(renames, inst->tex_offsets[j].reladdr);
+         rename_temp_handle_src(renames, inst->tex_offsets[j].reladdr2);
       }
 
-      if (inst->resource.file == PROGRAM_TEMPORARY) {
-         int old_idx = inst->resource.index;
-         if (renames[old_idx].valid)
-            inst->resource.index = renames[old_idx].new_reg;
-      }
+      rename_temp_handle_src(renames, &inst->resource);
+      rename_temp_handle_src(renames, inst->resource.reladdr);
+      rename_temp_handle_src(renames, inst->resource.reladdr2);
 
       for (j = 0; j < num_inst_dst_regs(inst); j++) {
          if (inst->dst[j].file == PROGRAM_TEMPORARY) {
             int old_idx = inst->dst[j].index;
             if (renames[old_idx].valid)
-               inst->dst[j].index = renames[old_idx].new_reg;}
+               inst->dst[j].index = renames[old_idx].new_reg;
+         }
+         rename_temp_handle_src(renames, inst->dst[j].reladdr);
+         rename_temp_handle_src(renames, inst->dst[j].reladdr2);
       }
    }
 }
 
 void
 glsl_to_tgsi_visitor::get_first_temp_write(int *first_writes)
 {
    int depth = 0; /* loop depth */
    int loop_start = -1; /* index of the first active BGNLOOP (if any) */
    unsigned i = 0, j;
@@ -4968,20 +4976,30 @@ glsl_to_tgsi_visitor::copy_propagate(void)
                acp_level[4 * inst->dst[0].index + i] = level;
             }
          }
       }
    }
 
    ralloc_free(acp_level);
    ralloc_free(acp);
 }
 
+static void
+dead_code_handle_reladdr(glsl_to_tgsi_instruction **writes, st_src_reg *reladdr)
+{
+   if (reladdr && reladdr->file == PROGRAM_TEMPORARY) {
+      /* Clear where it's used as src. */
+      int swz = GET_SWZ(reladdr->swizzle, 0);
+      writes[4 * reladdr->index + swz] = NULL;
+   }
+}
+
 /*
  * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead
  * code elimination.
  *
  * The glsl_to_tgsi_visitor lazily produces code assuming that this pass
  * will occur.  As an example, a TXP production after copy propagation but
  * before this pass:
  *
  * 0: MOV TEMP[1], INPUT[4].xyyy;
  * 1: MOV TEMP[1].w, INPUT[4].wwww;
@@ -5058,55 +5076,65 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void)
                int src_chans = 1 << GET_SWZ(inst->src[i].swizzle, 0);
                src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 1);
                src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 2);
                src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 3);
 
                for (int c = 0; c < 4; c++) {
                   if (src_chans & (1 << c))
                      writes[4 * inst->src[i].index + c] = NULL;
                }
             }
+            dead_code_handle_reladdr(writes, inst->src[i].reladdr);
+            dead_code_handle_reladdr(writes, inst->src[i].reladdr2);
          }
          for (unsigned i = 0; i < inst->tex_offset_num_offset; i++) {
             if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY && inst->tex_offsets[i].reladdr){
                /* Any temporary might be read, so no dead code elimination
                 * across this instruction.
                 */
                memset(writes, 0, sizeof(*writes) * this->next_temp * 4);
             } else if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY) {
                /* Clear where it's used as src. */
                int src_chans = 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 0);
                src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 1);
                src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 2);
                src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 3);
 
                for (int c = 0; c < 4; c++) {
                   if (src_chans & (1 << c))
                      writes[4 * inst->tex_offsets[i].index + c] = NULL;
                }
             }
+            dead_code_handle_reladdr(writes, inst->tex_offsets[i].reladdr);
+            dead_code_handle_reladdr(writes, inst->tex_offsets[i].reladdr2);
          }
 
          if (inst->resource.file == PROGRAM_TEMPORARY) {
             int src_chans;
 
             src_chans  = 1 << GET_SWZ(inst->resource.swizzle, 0);
             src_chans |= 1 << GET_SWZ(inst->resource.swizzle, 1);
             src_chans |= 1 << GET_SWZ(inst->resource.swizzle, 2);
             src_chans |= 1 << GET_SWZ(inst->resource.swizzle, 3);
 
             for (int c = 0; c < 4; c++) {
                if (src_chans & (1 << c))
                   writes[4 * inst->resource.index + c] = NULL;
             }
          }
+         dead_code_handle_reladdr(writes, inst->resource.reladdr);
+         dead_code_handle_reladdr(writes, inst->resource.reladdr2);
 
+         for (unsigned i = 0; i < ARRAY_SIZE(inst->dst); i++) {
+            dead_code_handle_reladdr(writes, inst->dst[i].reladdr);
+            dead_code_handle_reladdr(writes, inst->dst[i].reladdr2);
+         }
          break;
       }
 
       /* If this instruction writes to a temporary, add it to the write array.
        * If there is already an instruction in the write array for one or more
        * of the channels, flag that channel write as dead.
        */
       for (unsigned i = 0; i < ARRAY_SIZE(inst->dst); i++) {
          if (inst->dst[i].file == PROGRAM_TEMPORARY &&
              !inst->dst[i].reladdr) {
-- 
2.7.4



More information about the mesa-dev mailing list