[Mesa-dev] [PATCH 5/6] mesa/st/glsl_to_tgsi: Add tracking of indirect addressing registers

Gert Wollny gw.fossdev at gmail.com
Wed Oct 4 09:45:29 UTC 2017


So far indirect addressing was not tracked to estimate the temporary
life time, and it was not needed, because code to load the address
registers was always emitted eliminating the reladdr* handles in the
past glsl-to.tgsi stages.
Now, with Mareks proposed patch this may change, and hence the tracking
becomes necessary.

Because the registers have no direct indication on whether the reladdr* was
already loaded into an address register, the temporaries in reladdr* are
always tracked as reads. This may result in a slight over-estimation of the
lifetime in the cases when the load to the address register was emitted.
---
 .../state_tracker/st_glsl_to_tgsi_temprename.cpp   | 108 ++++++++++++++-------
 1 file changed, 74 insertions(+), 34 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp
index 0828927457..34b5b8d498 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp
@@ -796,6 +796,69 @@ public:
    }
 };
 
+class access_recorder {
+public:
+   access_recorder(int _ntemps);
+   ~access_recorder();
+
+   void record_read(const st_src_reg& src, int line, prog_scope *scope);
+   void record_write(const st_dst_reg& src, int line, prog_scope *scope);
+
+   void get_required_lifetimes(struct lifetime *lifetimes);
+private:
+
+   int ntemps;
+   temp_access *acc;
+
+};
+
+access_recorder::access_recorder(int _ntemps):
+   ntemps(_ntemps)
+{
+   acc = new temp_access[ntemps];
+}
+
+access_recorder::~access_recorder()
+{
+   delete[] acc;
+}
+
+void access_recorder::record_read(const st_src_reg& src, int line,
+                                  prog_scope *scope)
+{
+   if (src.file == PROGRAM_TEMPORARY)
+      acc[src.index].record_read(line, scope, src.swizzle);
+
+   if (src.reladdr)
+      record_read(*src.reladdr, line, scope);
+   if (src.reladdr2)
+      record_read(*src.reladdr2, line, scope);
+}
+
+void access_recorder::record_write(const st_dst_reg& dst, int line,
+                                   prog_scope *scope)
+{
+   if (dst.file == PROGRAM_TEMPORARY)
+      acc[dst.index].record_write(line, scope, dst.writemask);
+
+   if (dst.reladdr)
+      record_read(*dst.reladdr, line, scope);
+   if (dst.reladdr2)
+      record_read(*dst.reladdr2, line, scope);
+}
+
+void access_recorder::get_required_lifetimes(struct lifetime *lifetimes)
+{
+   RENAME_DEBUG(cerr << "========= lifetimes ==============\n");
+   for(int i = 0; i < ntemps; ++i) {
+      RENAME_DEBUG(cerr << setw(4) << i);
+      lifetimes[i] = acc[i].get_required_lifetime();
+      RENAME_DEBUG(cerr << ": [" << lifetimes[i].begin << ", "
+                        << lifetimes[i].end << "]\n");
+   }
+   RENAME_DEBUG(cerr << "==================================\n\n");
+}
+
 }
 
 #ifndef NDEBUG
@@ -816,7 +879,6 @@ get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
    int if_id = 1;
    int switch_id = 0;
    bool is_at_end = false;
-   bool ok = true;
    int n_scopes = 1;
 
    /* Count scopes to allocate the needed space without the need for
@@ -834,7 +896,8 @@ get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
    }
 
    prog_scope_storage scopes(mem_ctx, n_scopes);
-   temp_access *acc = new temp_access[ntemps];
+
+   access_recorder access(ntemps);
 
    prog_scope *cur_scope = scopes.create(nullptr, outer_scope, 0, 0, line);
 
@@ -863,9 +926,7 @@ get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
       case TGSI_OPCODE_IF:
       case TGSI_OPCODE_UIF: {
          assert(num_inst_src_regs(inst) == 1);
-         const st_src_reg& src = inst->src[0];
-         if (src.file == PROGRAM_TEMPORARY)
-            acc[src.index].record_read(line, cur_scope, src.swizzle);
+         access.record_read(inst->src[0], line, cur_scope);
          cur_scope = scopes.create(cur_scope, if_branch, if_id++,
                                    cur_scope->nesting_depth() + 1, line + 1);
          break;
@@ -891,14 +952,12 @@ get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
       }
       case TGSI_OPCODE_SWITCH: {
          assert(num_inst_src_regs(inst) == 1);
-         const st_src_reg& src = inst->src[0];
          prog_scope *scope = scopes.create(cur_scope, switch_body, switch_id++,
                                            cur_scope->nesting_depth() + 1, line);
          /* We record the read only for the SWITCH statement itself, like it
           * is used by the only consumer of TGSI_OPCODE_SWITCH in tgsi_exec.c.
           */
-         if (src.file == PROGRAM_TEMPORARY)
-            acc[src.index].record_read(line, cur_scope, src.swizzle);
+         access.record_read(inst->src[0], line, cur_scope);
          cur_scope = scope;
          break;
       }
@@ -920,9 +979,7 @@ get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
                                        cur_scope : cur_scope->parent();
 
          assert(num_inst_src_regs(inst) == 1);
-         const st_src_reg& src = inst->src[0];
-         if (src.file == PROGRAM_TEMPORARY)
-            acc[src.index].record_read(line, switch_scope, src.swizzle);
+         access.record_read(inst->src[0], line, switch_scope);
 
          /* Fall through to allocate the scope. */
       }
@@ -958,23 +1015,16 @@ get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
           * Since this is not done, we have to bail out here and signal
           * that no register merge will take place.
           */
-         ok = false;
-         goto out;
+         return false;
       default: {
          for (unsigned j = 0; j < num_inst_src_regs(inst); j++) {
-            const st_src_reg& src = inst->src[j];
-            if (src.file == PROGRAM_TEMPORARY)
-               acc[src.index].record_read(line, cur_scope, src.swizzle);
+            access.record_read(inst->src[j], line, cur_scope);
          }
          for (unsigned j = 0; j < inst->tex_offset_num_offset; j++) {
-            const st_src_reg& src = inst->tex_offsets[j];
-            if (src.file == PROGRAM_TEMPORARY)
-               acc[src.index].record_read(line, cur_scope, src.swizzle);
+            access.record_read(inst->tex_offsets[j], line, cur_scope);
          }
          for (unsigned j = 0; j < num_inst_dst_regs(inst); j++) {
-            const st_dst_reg& dst = inst->dst[j];
-            if (dst.file == PROGRAM_TEMPORARY)
-               acc[dst.index].record_write(line, cur_scope, dst.writemask);
+            access.record_write(inst->dst[j], line, cur_scope);
          }
       }
       }
@@ -989,18 +1039,8 @@ get_temp_registers_required_lifetimes(void *mem_ctx, exec_list *instructions,
    if (cur_scope->end() < 0)
       cur_scope->set_end(line - 1);
 
-   RENAME_DEBUG(cerr << "========= lifetimes ==============\n");
-   for(int i = 0; i < ntemps; ++i) {
-      RENAME_DEBUG(cerr << setw(4) << i);
-      lifetimes[i] = acc[i].get_required_lifetime();
-      RENAME_DEBUG(cerr << ": [" << lifetimes[i].begin << ", "
-                        << lifetimes[i].end << "]\n");
-   }
-   RENAME_DEBUG(cerr << "==================================\n\n");
-
-out:
-   delete[] acc;
-   return ok;
+   access.get_required_lifetimes(lifetimes);
+   return true;
 }
 
 /* Find the next register between [start, end) that has a life time starting
-- 
2.13.6



More information about the mesa-dev mailing list