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

Nicolai Hähnle nhaehnle at gmail.com
Mon Oct 9 15:02:42 UTC 2017


Patches 1 & 5:

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at 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.


More information about the mesa-dev mailing list