[Mesa-dev] [PATCH] mesa: Fix the Mesa IR copy propagation to not read past writes to the reg.

José Fonseca jfonseca at vmware.com
Tue Feb 8 02:45:38 PST 2011


Looks good to me FWIW.

When dst_reg.reladdr is set we could still restrict the reset to
dst_reg.writemask bits, but this was not done before either.

Jose

On Fri, 2011-02-04 at 12:50 -0800, Eric Anholt wrote:
> Fixes glsl-vs-post-increment-01.
> ---
>  src/mesa/program/ir_to_mesa.cpp |   47 +++++++++++++++++++++++++++++++++-----
>  1 files changed, 40 insertions(+), 7 deletions(-)
> 
> diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
> index 3794c0d..d0ec23f 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -2742,13 +2742,46 @@ ir_to_mesa_visitor::copy_propagate(void)
>  	 /* Continuing the block, clear any written channels from
>  	  * the ACP.
>  	  */
> -	 if (inst->dst_reg.file == PROGRAM_TEMPORARY) {
> -	    if (inst->dst_reg.reladdr) {
> -	       memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
> -	    } else {
> -	       for (int i = 0; i < 4; i++) {
> -		  if (inst->dst_reg.writemask & (1 << i)) {
> -		     acp[4 * inst->dst_reg.index + i] = NULL;
> +	 if (inst->dst_reg.file == PROGRAM_TEMPORARY && inst->dst_reg.reladdr) {
> +	    /* Any temporary might be written, so no copy propagation
> +	     * across this instruction.
> +	     */
> +	    memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
> +	 } else if (inst->dst_reg.file == PROGRAM_OUTPUT &&
> +		    inst->dst_reg.reladdr) {
> +	    /* Any output might be written, so no copy propagation
> +	     * from outputs across this instruction.
> +	     */
> +	    for (int r = 0; r < this->next_temp; r++) {
> +	       for (int c = 0; c < 4; c++) {
> +		  if (acp[4 * r + c]->src_reg[0].file == PROGRAM_OUTPUT)
> +		     acp[4 * r + c] = NULL;
> +	       }
> +	    }
> +	 } else if (inst->dst_reg.file == PROGRAM_TEMPORARY ||
> +		    inst->dst_reg.file == PROGRAM_OUTPUT) {
> +	    /* Clear where it's used as dst. */
> +	    if (inst->dst_reg.file == PROGRAM_TEMPORARY) {
> +	       for (int c = 0; c < 4; c++) {
> +		  if (inst->dst_reg.writemask & (1 << c)) {
> +		     acp[4 * inst->dst_reg.index + c] = NULL;
> +		  }
> +	       }
> +	    }
> +
> +	    /* Clear where it's used as src. */
> +	    for (int r = 0; r < this->next_temp; r++) {
> +	       for (int c = 0; c < 4; c++) {
> +		  if (!acp[4 * r + c])
> +		     continue;
> +
> +		  int src_chan = GET_SWZ(acp[4 * r + c]->src_reg[0].swizzle, c);
> +
> +		  if (acp[4 * r + c]->src_reg[0].file == inst->dst_reg.file &&
> +		      acp[4 * r + c]->src_reg[0].index == inst->dst_reg.index &&
> +		      inst->dst_reg.writemask & (1 << src_chan))
> +		  {
> +		     acp[4 * r + c] = NULL;
>  		  }
>  	       }
>  	    }




More information about the mesa-dev mailing list