[Mesa-dev] [PATCH 16/57] i965/fs: Take into account trailing padding in regs_written() and regs_read().
Iago Toral
itoral at igalia.com
Fri Sep 9 07:21:47 UTC 2016
On Wed, 2016-09-07 at 18:48 -0700, Francisco Jerez wrote:
> This fixes regs_written() and regs_read() to return a more accurate
> value when the padding left between components due to a stride value
> greater than one causes the region bounds given by size_written or
> size_read to overflow into the next register. This could become a
> problem in optimization passes that keep track of dataflow using
> fixed-size arrays with register granularity, because the overflow
> register (not actually accessed by the region) may not have been
> allocated at all which could lead to undefined memory access.
ah, nice catch! I am curious: did you find any cases where this was
creating a real problem or just something you noticed by inspection?
> An alternative to this would be to subtract the trailing padding
> already during the calculation of fs_inst::size_read and
> ::size_written, but that would break code that currently assumes that
> ::size_read and _written are whole multiples of the component size,
> and would be hard to maintain looking forward because size_written is
> assigned from a bunch of different places.
Yeah, this would be a more problematic solution.
> ---
> src/mesa/drivers/dri/i965/brw_ir_fs.h | 22 ++++++++++++++++++++--
> 1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_ir_fs.h
> b/src/mesa/drivers/dri/i965/brw_ir_fs.h
> index 4ac9baa..0be67b7 100644
> --- a/src/mesa/drivers/dri/i965/brw_ir_fs.h
> +++ b/src/mesa/drivers/dri/i965/brw_ir_fs.h
> @@ -192,6 +192,20 @@ reg_offset(const fs_reg &r)
> }
>
> /**
> + * Return the amount of padding in bytes left unused between
> individual
> + * components of register \p r due to a (horizontal) stride value
> greater than
> + * one, or zero if components are tightly packed in the register
> file.
> + */
> +static inline unsigned
> +reg_padding(const fs_reg &r)
> +{
> + const unsigned stride = ((r.file != ARF && r.file != FIXED_GRF) ?
> r.stride :
> + r.hstride == 0 ? 0 :
> + 1 << (r.hstride - 1));
> + return (MAX2(1, stride) - 1) * type_sz(r.type);
> +}
> +
> +/**
> * Return whether the register region starting at \p r and spanning
> \p dr
> * bytes could potentially overlap the register region starting at
> \p s and
> * spanning \p ds bytes.
> @@ -423,7 +437,9 @@ regs_written(const fs_inst *inst)
> {
> /* XXX - Take into account register-misaligned offsets correctly.
> */
> assert(inst->dst.file != UNIFORM && inst->dst.file != IMM);
> - return DIV_ROUND_UP(inst->size_written, REG_SIZE);
> + return DIV_ROUND_UP(inst->size_written -
> + MIN2(inst->size_written, reg_padding(inst-
> >dst)),
> + REG_SIZE);
> }
>
> /**
> @@ -438,7 +454,9 @@ regs_read(const fs_inst *inst, unsigned i)
> /* XXX - Take into account register-misaligned offsets correctly.
> */
> const unsigned reg_size =
> inst->src[i].file == UNIFORM || inst->src[i].file == IMM ? 4 :
> REG_SIZE;
> - return DIV_ROUND_UP(inst->size_read(i), reg_size);
> + return DIV_ROUND_UP(inst->size_read(i) -
> + MIN2(inst->size_read(i), reg_padding(inst-
> >src[i])),
> + reg_size);
> }
>
> #endif
More information about the mesa-dev
mailing list