[Mesa-dev] [PATCH] nir/phi_builder: Don't recurse in value_get_block_def
Thomas Helland
thomashelland90 at gmail.com
Thu Aug 25 05:56:17 UTC 2016
2016-08-25 7:49 GMT+02:00 Jason Ekstrand <jason at jlekstrand.net>:
> In some programs, we can have very deep dominance trees and the recursion
> can cause us to risk stack overflows. Instead, we replace the recursion
> with a pair of loops, one at the start and one at the end. This is
> functionally equivalent to what we had before and it's actually a bit
> easier to read in the new form without the recursion.
>
> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97225
> Cc: mesa-stable at lists.freedesktop.org
> ---
> src/compiler/nir/nir_phi_builder.c | 65 +++++++++++++++++++++-----------------
> 1 file changed, 36 insertions(+), 29 deletions(-)
>
> diff --git a/src/compiler/nir/nir_phi_builder.c b/src/compiler/nir/nir_phi_builder.c
> index dd48975..24a3a7f 100644
> --- a/src/compiler/nir/nir_phi_builder.c
> +++ b/src/compiler/nir/nir_phi_builder.c
> @@ -172,31 +172,27 @@ nir_ssa_def *
> nir_phi_builder_value_get_block_def(struct nir_phi_builder_value *val,
> nir_block *block)
> {
> - /* For each block, we have one of three types of values */
> - if (val->defs[block->index] == NULL) {
> - /* NULL indicates that we have no SSA def for this block. */
> - if (block->imm_dom) {
> - /* Grab it from our immediate dominator. We'll stash it here for
> - * easy access later.
> - */
> - val->defs[block->index] =
> - nir_phi_builder_value_get_block_def(val, block->imm_dom);
> - return val->defs[block->index];
> - } else {
> - /* No immediate dominator means that this block is either the
> - * start block or unreachable. In either case, the value is
> - * undefined so we need an SSA undef.
> - */
> - nir_ssa_undef_instr *undef =
> - nir_ssa_undef_instr_create(val->builder->shader,
> - val->num_components,
> - val->bit_size);
> - nir_instr_insert(nir_before_cf_list(&val->builder->impl->body),
> - &undef->instr);
> - val->defs[block->index] = &undef->def;
> - return &undef->def;
> - }
> - } else if (val->defs[block->index] == NEEDS_PHI) {
> + /* Crawl up the dominance tree and find the highest dominator for which we
> + * have a valid ssa_def, if any.
> + */
> + nir_block *dom = block;
> + while (dom && val->defs[dom->index] == NULL)
> + dom = dom->imm_dom;
> +
> + nir_ssa_def *def;
> + if (dom == NULL) {
> + /* No dominator means that this we either that we crawled to the top
This doesn't parse at all.
> + * without ever finding a definition or that this block is unreachable.
> + * In either case, the value is undefined so we need an SSA undef.
> + */
> + nir_ssa_undef_instr *undef =
> + nir_ssa_undef_instr_create(val->builder->shader,
> + val->num_components,
> + val->bit_size);
> + nir_instr_insert(nir_before_cf_list(&val->builder->impl->body),
> + &undef->instr);
> + def = &undef->def;
> + } else if (val->defs[dom->index] == NEEDS_PHI) {
> /* The magic value NEEDS_PHI indicates that the block needs a phi node
> * but none has been created. We need to create one now so we can
> * return it to the caller.
> @@ -218,17 +214,28 @@ nir_phi_builder_value_get_block_def(struct nir_phi_builder_value *val,
> nir_phi_instr *phi = nir_phi_instr_create(val->builder->shader);
> nir_ssa_dest_init(&phi->instr, &phi->dest, val->num_components,
> val->bit_size, NULL);
> - phi->instr.block = block;
> + phi->instr.block = dom;
> exec_list_push_tail(&val->phis, &phi->instr.node);
> - val->defs[block->index] = &phi->dest.ssa;
> - return &phi->dest.ssa;
> + def = &phi->dest.ssa;
> } else {
> /* In this case, we have an actual SSA def. It's either the result of a
> * phi node created by the case above or one passed to us through
> * nir_phi_builder_value_set_block_def().
> */
> - return val->defs[block->index];
> + def = val->defs[dom->index];
> }
> +
> + /* Walk the chain and stash the def in all of the applicable blocks. We do
> + * this for two reasons:
> + *
> + * 1) To speed up lookup next time even if the next time is called from a
> + * block that is not dominated by this one.
> + * 2) To avoid unneeded recreation of phi nodes and undefs.
> + */
> + for (dom = block; dom && val->defs[dom->index] == NULL; dom = dom->imm_dom)
> + val->defs[dom->index] = def;
> +
> + return def;
> }
>
> static int
> --
> 2.5.0.400.gff86faf
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list