[Mesa-dev] [PATCH] i965/fs: Extend the live ranges of VGRFs which leave loops
Jason Ekstrand
jason at jlekstrand.net
Thu Oct 5 05:13:31 UTC 2017
Bah! This one's bogus too. I think it messes up register coalesce but I'm
not 100% sure...
On Wed, Oct 4, 2017 at 8:22 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> Cc: mesa-stable at lists.freedesktop.org
> ---
> src/intel/compiler/brw_fs_live_variables.cpp | 55
> ++++++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/src/intel/compiler/brw_fs_live_variables.cpp
> b/src/intel/compiler/brw_fs_live_variables.cpp
> index c449672..23ec280 100644
> --- a/src/intel/compiler/brw_fs_live_variables.cpp
> +++ b/src/intel/compiler/brw_fs_live_variables.cpp
> @@ -223,6 +223,61 @@ fs_live_variables::compute_start_end()
> }
> }
> }
> +
> + /* Due to the explicit way the SIMD data is handled on GEN, we need to
> be a
> + * bit more careful with live ranges and loops. Consider the following
> + * example:
> + *
> + * vec4 color2;
> + * while (1) {
> + * vec4 color = texture();
> + * if (...) {
> + * color2 = color * 2;
> + * break;
> + * }
> + * }
> + * gl_FragColor = color2;
> + *
> + * In this case, the definition of color2 dominates the use because the
> + * loop only has the one exit. This means that the live range
> interval for
> + * color2 goes from the statement in the if to it's use below the loop.
> + * Now suppose that the texture operation has a header register that
> gets
> + * assigned one of the registers used for color2. If the loop
> condition is
> + * non-uniform and some of the threads will take the and others will
> + * continue. In this case, the next pass through the loop, the WE_all
> + * setup of the header register will stomp the disabled channels of
> color2
> + * and corrupt the value.
> + *
> + * This same problem can occur if you have a mix of 64, 32, and 16-bit
> + * registers because the channels do not line up or if you have a
> SIMD16
> + * program and the first half of one value overlaps the second half of
> the
> + * other.
> + *
> + * To solve this problem, we take any VGRFs whose live ranges cross the
> + * while instruction of a loop and extend their live ranges to the top
> of
> + * the loop. This more accurately models the hardware because the
> value in
> + * the VGRF needs to be carried through subsequent loop iterations in
> order
> + * to remain valid when we finally do break.
> + */
> + foreach_block (block, cfg) {
> + if (block->end()->opcode != BRW_OPCODE_WHILE)
> + continue;
> +
> + /* This is a WHILE instrution. Find the DO block. */
> + bblock_t *do_block = NULL;
> + foreach_list_typed(bblock_link, child_link, link,
> &block->children) {
> + if (child_link->block->start_ip < block->end_ip) {
> + assert(do_block == NULL);
> + do_block = child_link->block;
> + }
> + }
> + assert(do_block);
> +
> + for (int i = 0; i < num_vars; i++) {
> + if (start[i] < block->end_ip && end[i] > block->end_ip)
> + start[i] = do_block->start_ip;
> + }
> + }
> }
>
> fs_live_variables::fs_live_variables(fs_visitor *v, const cfg_t *cfg)
> --
> 2.5.0.400.gff86faf
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20171004/98a43301/attachment.html>
More information about the mesa-dev
mailing list