[Mesa-dev] [PATCH v3 02/13] mesa/st: glsl_to_tgsi: Split arrays who's elements are only accessed directly
Nicolai Hähnle
nhaehnle at gmail.com
Tue May 1 09:57:08 UTC 2018
So the GLSL transforms don't already do this? Interesting... anyway,
seems a nice improvement, I just have some stylistic nitpicks below.
On 28.04.2018 21:30, Gert Wollny wrote:
> Array who's elements are only accessed directly are replaced by the
> according number of temporary registers. By doing so the otherwise
> reserved register range becomes subject to further optimizations like
> copy propagation and register merging.
>
> Thanks to the resulting reduced register pressure this patch makes
> the piglits
>
> spec/glsl-1.50/execution -
> variable-indexing/vs-output-array-vec3-index-wr-before-gs
> geometry/max-input-components
>
> pass on r600 (barts) where they would fail before with a "GPR limit exceeded"
> error.
>
> v3: * enable this optimization only if the driver requests register merge
>
> v2: * rename method dissolve_arrays to split_arrays
> * unify the tracking and remapping methods for src and st registers
> * also track access to arrays via reladdr*
>
> Signed-off-by: Gert Wollny <gw.fossdev at gmail.com>
> ---
> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 117 ++++++++++++++++++++++++++++-
> 1 file changed, 116 insertions(+), 1 deletion(-)
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 1614367a01..e778807b7c 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -369,6 +369,7 @@ public:
> void copy_propagate(void);
> int eliminate_dead_code(void);
>
> + void split_arrays(void);
> void merge_two_dsts(void);
> void merge_registers(void);
> void renumber_registers(void);
> @@ -5400,6 +5401,110 @@ glsl_to_tgsi_visitor::merge_two_dsts(void)
> }
> }
>
> +
> +
> +/* One-dimensional arrays who's elements are only accessed directly are
*whose
Also, the placement of this comment is odd, floating like this in empty
space. It looks like it should be a comment on split_arrays.
> + * replaced by an according set of temporary registers that then can become
> + * subject to further optimization steps like copy propagation and
> + * register merging.
> + */
> +
> +template <typename st_reg>
> +void test_indirect_access(const st_reg& reg, bool *has_indirect_access)
> +{
> + if (reg.file == PROGRAM_ARRAY) {
> + if (reg.reladdr || reg.reladdr2 || reg.has_index2) {
> + has_indirect_access[reg.array_id] = true;
> + if (reg.reladdr)
> + test_indirect_access(*reg.reladdr, has_indirect_access);
> + if (reg.reladdr2)
> + test_indirect_access(*reg.reladdr, has_indirect_access);
> + }
> + }
> +}
> +
> +template <typename st_reg>
> +void remap_array(st_reg& reg, const int *array_remap_info,
> + const bool *has_indirect_access)
> +{
> + if (reg.file == PROGRAM_ARRAY) {
> + if (!has_indirect_access[reg.array_id]) {
> + reg.file = PROGRAM_TEMPORARY;
> + reg.index = reg.index + array_remap_info[reg.array_id];
> + reg.array_id = 0;
> + } else {
> + reg.array_id = array_remap_info[reg.array_id];
> + }
> +
> + if (reg.reladdr)
> + remap_array(*reg.reladdr, array_remap_info, has_indirect_access);
> +
> + if (reg.reladdr2)
> + remap_array(*reg.reladdr2, array_remap_info, has_indirect_access);
> + }
> +}
> +
> +void
> +glsl_to_tgsi_visitor::split_arrays(void)
> +{
> + if (!next_array)
> + return;
> +
> + bool *has_indirect_access = rzalloc_array(mem_ctx, bool, next_array + 1);
> +
> + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
> + for (unsigned j = 0; j < num_inst_src_regs(inst); j++)
> + test_indirect_access(inst->src[j], has_indirect_access);
> +
> + for (unsigned j = 0; j < inst->tex_offset_num_offset; j++)
> + test_indirect_access(inst->tex_offsets[j], has_indirect_access);
> +
> + for (unsigned j = 0; j < num_inst_dst_regs(inst); j++)
> + test_indirect_access(inst->dst[j], has_indirect_access);
> + }
> +
> + unsigned array_offset = 0;
> + unsigned n_remaining_arrays = 0;
> +
> + /* Double use: For arrays that get disolved this value will contain
*dissolved
> + * the base index of the temporary registers this array is replaced
> + * with. For arrays that remain it contains the new array ID.
> + */
> + int *array_remap_info = rzalloc_array(has_indirect_access, int,
> + next_array + 1);
> +
> + for (unsigned i = 1; i <= next_array; ++i) {
> + if (!has_indirect_access[i]) {
> + array_remap_info[i] = this->next_temp + array_offset;
> + array_offset += array_sizes[i-1];
Spaces around operators are generally preferred.
> + } else {
> + array_sizes[n_remaining_arrays] = array_sizes[i-1];
> + array_remap_info[i] = ++n_remaining_arrays;
> + }
> + }
> +
> + if (next_array != n_remaining_arrays) {
> +
Excessive whitespace: both the empty line and after the !=. Also twice
below.
Cheers,
Nicolai
> + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
> +
> + for (unsigned j = 0; j < num_inst_src_regs(inst); j++)
> + remap_array(inst->src[j], array_remap_info, has_indirect_access);
> +
> + for (unsigned j = 0; j < inst->tex_offset_num_offset; j++)
> + remap_array(inst->tex_offsets[j], array_remap_info, has_indirect_access);
> +
> + for (unsigned j = 0; j < num_inst_dst_regs(inst); j++) {
> + remap_array(inst->dst[j], array_remap_info, has_indirect_access);
> + }
> + }
> + }
> +
> + ralloc_free(has_indirect_access);
> +
> + this->next_temp += array_offset;
> + next_array = n_remaining_arrays;
> +}
> +
> /* Merges temporary registers together where possible to reduce the number of
> * registers needed to run a program.
> *
> @@ -6892,8 +6997,18 @@ get_mesa_program_tgsi(struct gl_context *ctx,
> while (v->eliminate_dead_code());
>
> v->merge_two_dsts();
> - if (!skip_merge_registers)
> +
> + if (!skip_merge_registers) {
> +
> + v->split_arrays();
> + v->copy_propagate();
> + while (v->eliminate_dead_code());
> +
> v->merge_registers();
> + v->copy_propagate();
> + while (v->eliminate_dead_code());
> + }
> +
> v->renumber_registers();
>
> /* Write the END instruction. */
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list