[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