Patches 1 & 5:

Reviewed-by: Nicolai Hähnle <nicolai.haeh...@amd.com>


On 04.10.2017 11:45, Gert Wollny wrote:
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



--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to