Re: [Mesa-dev] [PATCH 4/6] nir: Add a local variable-based copy propagation pass
On Wed, Jan 4, 2017 at 9:31 PM, Timothy Arceriwrote: > There was a bit to take in here but it seems ok to me. I've made a > bunch of trivial suggestions/comments below otherwise: > > Reviewed-by: Timothy Arceri > > On Mon, 2016-12-12 at 19:39 -0800, Jason Ekstrand wrote: > > --- > > src/compiler/Makefile.sources | 1 + > > src/compiler/nir/nir.h| 2 + > > src/compiler/nir/nir_opt_copy_prop_vars.c | 799 > > ++ > > 3 files changed, 802 insertions(+) > > create mode 100644 src/compiler/nir/nir_opt_copy_prop_vars.c > > > > diff --git a/src/compiler/Makefile.sources > > b/src/compiler/Makefile.sources > > index 17b15de..09b4105 100644 > > --- a/src/compiler/Makefile.sources > > +++ b/src/compiler/Makefile.sources > > @@ -231,6 +231,7 @@ NIR_FILES = \ > > nir/nir_normalize_cubemap_coords.c \ > > nir/nir_opt_conditional_discard.c \ > > nir/nir_opt_constant_folding.c \ > > + nir/nir_opt_copy_prop_vars.c \ > > nir/nir_opt_copy_propagate.c \ > > nir/nir_opt_cse.c \ > > nir/nir_opt_dce.c \ > > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h > > index 544d4ba..27ef633 100644 > > --- a/src/compiler/nir/nir.h > > +++ b/src/compiler/nir/nir.h > > @@ -2489,6 +2489,8 @@ bool nir_opt_global_to_local(nir_shader > > *shader); > > > > bool nir_copy_prop(nir_shader *shader); > > > > +bool nir_opt_copy_prop_vars(nir_shader *shader); > > + > > bool nir_opt_cse(nir_shader *shader); > > > > bool nir_opt_dce(nir_shader *shader); > > diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c > > b/src/compiler/nir/nir_opt_copy_prop_vars.c > > new file mode 100644 > > index 000..728e476 > > --- /dev/null > > +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c > > @@ -0,0 +1,799 @@ > > +/* > > + * Copyright © 2016 Intel Corporation > > + * > > + * Permission is hereby granted, free of charge, to any person > > obtaining a > > + * copy of this software and associated documentation files (the > > "Software"), > > + * to deal in the Software without restriction, including without > > limitation > > + * the rights to use, copy, modify, merge, publish, distribute, > > sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom > > the > > + * Software is furnished to do so, subject to the following > > conditions: > > + * > > + * The above copyright notice and this permission notice (including > > the next > > + * paragraph) shall be included in all copies or substantial > > portions of the > > + * Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > > EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > > MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO > > EVENT SHALL > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES > > OR OTHER > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > ARISING > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > > OTHER DEALINGS > > + * IN THE SOFTWARE. > > + */ > > + > > +#include "nir.h" > > +#include "nir_builder.h" > > + > > +/** > > + * Variable-based copy propagation > > + * > > + * Normally, NIR trusts in SSA form for most of its copy-propagation > > needs. > > + * However, there are cases, especially when dealing with indirects, > > where SSA > > + * won't help you. This pass is for those times. Specifically, it > > handles > > + * the following things that the rest of NIR can't: > > + * > > + * 1) Copy-propagation on variables that have indirect > > access. This includes > > + * propagating from indirect stores into indirect loads. > > + * > > + * 2) Dead code elimination of store_var and copy_var intrinsics > > based on > > + * killed destination values. > > + * > > + * 3) Removal of redundant load_var intrinsics. We can't trust > > regular CSE > > + * to do this because it isn't aware of variable writes that may > > alias the > > + * value and make the former load invalid. > > + * > > + * Unfortunately, properly handling all of those cases makes this > > path rather > > + * complex. In order to avoid additional complexity, this pass is > > entirely > > + * block-local. If we tried to make it local the data-flow analysis > > would > > + * rapidly get out of hand. Fortunately, for anything that is only > > ever > > + * accessed directly, we get SSA based copy-propagation which is > > extremely > > + * powerful so this isn't that great a loss. > > + */ > > + > > +struct value { > > + bool is_ssa; > > + union { > > + nir_ssa_def *ssa[4]; > > + nir_deref_var *deref; > > + }; > > +}; > > + > > +struct copy_entry { > > + struct list_head link; > > + > > + nir_instr *store_instr[4]; > > + > > + unsigned comps_may_be_read; > > + struct value src; > > + > > + nir_deref_var *dst; > > +};
Re: [Mesa-dev] [PATCH 4/6] nir: Add a local variable-based copy propagation pass
There was a bit to take in here but it seems ok to me. I've made a bunch of trivial suggestions/comments below otherwise: Reviewed-by: Timothy ArceriOn Mon, 2016-12-12 at 19:39 -0800, Jason Ekstrand wrote: > --- > src/compiler/Makefile.sources | 1 + > src/compiler/nir/nir.h| 2 + > src/compiler/nir/nir_opt_copy_prop_vars.c | 799 > ++ > 3 files changed, 802 insertions(+) > create mode 100644 src/compiler/nir/nir_opt_copy_prop_vars.c > > diff --git a/src/compiler/Makefile.sources > b/src/compiler/Makefile.sources > index 17b15de..09b4105 100644 > --- a/src/compiler/Makefile.sources > +++ b/src/compiler/Makefile.sources > @@ -231,6 +231,7 @@ NIR_FILES = \ > nir/nir_normalize_cubemap_coords.c \ > nir/nir_opt_conditional_discard.c \ > nir/nir_opt_constant_folding.c \ > + nir/nir_opt_copy_prop_vars.c \ > nir/nir_opt_copy_propagate.c \ > nir/nir_opt_cse.c \ > nir/nir_opt_dce.c \ > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h > index 544d4ba..27ef633 100644 > --- a/src/compiler/nir/nir.h > +++ b/src/compiler/nir/nir.h > @@ -2489,6 +2489,8 @@ bool nir_opt_global_to_local(nir_shader > *shader); > > bool nir_copy_prop(nir_shader *shader); > > +bool nir_opt_copy_prop_vars(nir_shader *shader); > + > bool nir_opt_cse(nir_shader *shader); > > bool nir_opt_dce(nir_shader *shader); > diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c > b/src/compiler/nir/nir_opt_copy_prop_vars.c > new file mode 100644 > index 000..728e476 > --- /dev/null > +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c > @@ -0,0 +1,799 @@ > +/* > + * Copyright © 2016 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person > obtaining a > + * copy of this software and associated documentation files (the > "Software"), > + * to deal in the Software without restriction, including without > limitation > + * the rights to use, copy, modify, merge, publish, distribute, > sublicense, > + * and/or sell copies of the Software, and to permit persons to whom > the > + * Software is furnished to do so, subject to the following > conditions: > + * > + * The above copyright notice and this permission notice (including > the next > + * paragraph) shall be included in all copies or substantial > portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO > EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES > OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > OTHER DEALINGS > + * IN THE SOFTWARE. > + */ > + > +#include "nir.h" > +#include "nir_builder.h" > + > +/** > + * Variable-based copy propagation > + * > + * Normally, NIR trusts in SSA form for most of its copy-propagation > needs. > + * However, there are cases, especially when dealing with indirects, > where SSA > + * won't help you. This pass is for those times. Specifically, it > handles > + * the following things that the rest of NIR can't: > + * > + * 1) Copy-propagation on variables that have indirect > access. This includes > + * propagating from indirect stores into indirect loads. > + * > + * 2) Dead code elimination of store_var and copy_var intrinsics > based on > + * killed destination values. > + * > + * 3) Removal of redundant load_var intrinsics. We can't trust > regular CSE > + * to do this because it isn't aware of variable writes that may > alias the > + * value and make the former load invalid. > + * > + * Unfortunately, properly handling all of those cases makes this > path rather > + * complex. In order to avoid additional complexity, this pass is > entirely > + * block-local. If we tried to make it local the data-flow analysis > would > + * rapidly get out of hand. Fortunately, for anything that is only > ever > + * accessed directly, we get SSA based copy-propagation which is > extremely > + * powerful so this isn't that great a loss. > + */ > + > +struct value { > + bool is_ssa; > + union { > + nir_ssa_def *ssa[4]; > + nir_deref_var *deref; > + }; > +}; > + > +struct copy_entry { > + struct list_head link; > + > + nir_instr *store_instr[4]; > + > + unsigned comps_may_be_read; > + struct value src; > + > + nir_deref_var *dst; > +}; > + > +struct copy_prop_var_state { > + nir_shader *shader; > + > + void *mem_ctx; > + > + struct list_head copies; > + > + /* We're going to be allocating and deleting a lot of copy > entries so we'll > +* keep a free list to avoid thrashing malloc too badly. > +*/ > + struct list_head copy_free_list; > + > + bool progress; > +}; > + >
Re: [Mesa-dev] [PATCH 4/6] nir: Add a local variable-based copy propagation pass
Ping? On Dec 12, 2016 21:39, "Jason Ekstrand"wrote: > --- > src/compiler/Makefile.sources | 1 + > src/compiler/nir/nir.h| 2 + > src/compiler/nir/nir_opt_copy_prop_vars.c | 799 > ++ > 3 files changed, 802 insertions(+) > create mode 100644 src/compiler/nir/nir_opt_copy_prop_vars.c > > diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources > index 17b15de..09b4105 100644 > --- a/src/compiler/Makefile.sources > +++ b/src/compiler/Makefile.sources > @@ -231,6 +231,7 @@ NIR_FILES = \ > nir/nir_normalize_cubemap_coords.c \ > nir/nir_opt_conditional_discard.c \ > nir/nir_opt_constant_folding.c \ > + nir/nir_opt_copy_prop_vars.c \ > nir/nir_opt_copy_propagate.c \ > nir/nir_opt_cse.c \ > nir/nir_opt_dce.c \ > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h > index 544d4ba..27ef633 100644 > --- a/src/compiler/nir/nir.h > +++ b/src/compiler/nir/nir.h > @@ -2489,6 +2489,8 @@ bool nir_opt_global_to_local(nir_shader *shader); > > bool nir_copy_prop(nir_shader *shader); > > +bool nir_opt_copy_prop_vars(nir_shader *shader); > + > bool nir_opt_cse(nir_shader *shader); > > bool nir_opt_dce(nir_shader *shader); > diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c > b/src/compiler/nir/nir_opt_copy_prop_vars.c > new file mode 100644 > index 000..728e476 > --- /dev/null > +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c > @@ -0,0 +1,799 @@ > +/* > + * Copyright © 2016 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the > "Software"), > + * to deal in the Software without restriction, including without > limitation > + * the rights to use, copy, modify, merge, publish, distribute, > sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the > next > + * paragraph) shall be included in all copies or substantial portions of > the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT > SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > DEALINGS > + * IN THE SOFTWARE. > + */ > + > +#include "nir.h" > +#include "nir_builder.h" > + > +/** > + * Variable-based copy propagation > + * > + * Normally, NIR trusts in SSA form for most of its copy-propagation > needs. > + * However, there are cases, especially when dealing with indirects, > where SSA > + * won't help you. This pass is for those times. Specifically, it > handles > + * the following things that the rest of NIR can't: > + * > + * 1) Copy-propagation on variables that have indirect access. This > includes > + * propagating from indirect stores into indirect loads. > + * > + * 2) Dead code elimination of store_var and copy_var intrinsics based on > + * killed destination values. > + * > + * 3) Removal of redundant load_var intrinsics. We can't trust regular > CSE > + * to do this because it isn't aware of variable writes that may > alias the > + * value and make the former load invalid. > + * > + * Unfortunately, properly handling all of those cases makes this path > rather > + * complex. In order to avoid additional complexity, this pass is > entirely > + * block-local. If we tried to make it local the data-flow analysis would > + * rapidly get out of hand. Fortunately, for anything that is only ever > + * accessed directly, we get SSA based copy-propagation which is extremely > + * powerful so this isn't that great a loss. > + */ > + > +struct value { > + bool is_ssa; > + union { > + nir_ssa_def *ssa[4]; > + nir_deref_var *deref; > + }; > +}; > + > +struct copy_entry { > + struct list_head link; > + > + nir_instr *store_instr[4]; > + > + unsigned comps_may_be_read; > + struct value src; > + > + nir_deref_var *dst; > +}; > + > +struct copy_prop_var_state { > + nir_shader *shader; > + > + void *mem_ctx; > + > + struct list_head copies; > + > + /* We're going to be allocating and deleting a lot of copy entries so > we'll > +* keep a free list to avoid thrashing malloc too badly. > +*/ > + struct list_head copy_free_list; > + > + bool progress; > +}; > + > +static struct copy_entry * > +copy_entry_create(struct copy_prop_var_state *state, > + nir_deref_var *dst_deref) > +{ > + struct copy_entry *entry; > + if
Re: [Mesa-dev] [PATCH 4/6] nir: Add a local variable-based copy propagation pass
On Tue, Dec 13, 2016 at 9:43 AM, Eric Anholtwrote: > Jason Ekstrand writes: > > > diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c > b/src/compiler/nir/nir_opt_copy_prop_vars.c > > new file mode 100644 > > index 000..728e476 > > --- /dev/null > > +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c > > @@ -0,0 +1,799 @@ > > +/* > > + * Copyright © 2016 Intel Corporation > > + * > > + * Permission is hereby granted, free of charge, to any person > obtaining a > > + * copy of this software and associated documentation files (the > "Software"), > > + * to deal in the Software without restriction, including without > limitation > > + * the rights to use, copy, modify, merge, publish, distribute, > sublicense, > > + * and/or sell copies of the Software, and to permit persons to whom the > > + * Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice (including the > next > > + * paragraph) shall be included in all copies or substantial portions > of the > > + * Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT > SHALL > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > OTHER > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > ARISING > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > DEALINGS > > + * IN THE SOFTWARE. > > + */ > > + > > +#include "nir.h" > > +#include "nir_builder.h" > > + > > +/** > > + * Variable-based copy propagation > > + * > > + * Normally, NIR trusts in SSA form for most of its copy-propagation > needs. > > + * However, there are cases, especially when dealing with indirects, > where SSA > > + * won't help you. This pass is for those times. Specifically, it > handles > > + * the following things that the rest of NIR can't: > > + * > > + * 1) Copy-propagation on variables that have indirect access. This > includes > > + * propagating from indirect stores into indirect loads. > > + * > > + * 2) Dead code elimination of store_var and copy_var intrinsics based > on > > + * killed destination values. > > + * > > + * 3) Removal of redundant load_var intrinsics. We can't trust > regular CSE > > + * to do this because it isn't aware of variable writes that may > alias the > > + * value and make the former load invalid. > > + * > > + * Unfortunately, properly handling all of those cases makes this path > rather > > + * complex. In order to avoid additional complexity, this pass is > entirely > > + * block-local. If we tried to make it local the data-flow analysis > would > > I think here you wanted to say "make it global." > Thanks. Fixed locally. > I haven't reviewed the rest, I was just skimming to see what you were up > to. > > > + * rapidly get out of hand. Fortunately, for anything that is only ever > > + * accessed directly, we get SSA based copy-propagation which is > extremely > > + * powerful so this isn't that great a loss. > > + */ > ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 4/6] nir: Add a local variable-based copy propagation pass
Jason Ekstrandwrites: > diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c > b/src/compiler/nir/nir_opt_copy_prop_vars.c > new file mode 100644 > index 000..728e476 > --- /dev/null > +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c > @@ -0,0 +1,799 @@ > +/* > + * Copyright © 2016 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > DEALINGS > + * IN THE SOFTWARE. > + */ > + > +#include "nir.h" > +#include "nir_builder.h" > + > +/** > + * Variable-based copy propagation > + * > + * Normally, NIR trusts in SSA form for most of its copy-propagation needs. > + * However, there are cases, especially when dealing with indirects, where > SSA > + * won't help you. This pass is for those times. Specifically, it handles > + * the following things that the rest of NIR can't: > + * > + * 1) Copy-propagation on variables that have indirect access. This > includes > + * propagating from indirect stores into indirect loads. > + * > + * 2) Dead code elimination of store_var and copy_var intrinsics based on > + * killed destination values. > + * > + * 3) Removal of redundant load_var intrinsics. We can't trust regular CSE > + * to do this because it isn't aware of variable writes that may alias > the > + * value and make the former load invalid. > + * > + * Unfortunately, properly handling all of those cases makes this path rather > + * complex. In order to avoid additional complexity, this pass is entirely > + * block-local. If we tried to make it local the data-flow analysis would I think here you wanted to say "make it global." I haven't reviewed the rest, I was just skimming to see what you were up to. > + * rapidly get out of hand. Fortunately, for anything that is only ever > + * accessed directly, we get SSA based copy-propagation which is extremely > + * powerful so this isn't that great a loss. > + */ signature.asc Description: PGP signature ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 4/6] nir: Add a local variable-based copy propagation pass
--- src/compiler/Makefile.sources | 1 + src/compiler/nir/nir.h| 2 + src/compiler/nir/nir_opt_copy_prop_vars.c | 799 ++ 3 files changed, 802 insertions(+) create mode 100644 src/compiler/nir/nir_opt_copy_prop_vars.c diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources index 17b15de..09b4105 100644 --- a/src/compiler/Makefile.sources +++ b/src/compiler/Makefile.sources @@ -231,6 +231,7 @@ NIR_FILES = \ nir/nir_normalize_cubemap_coords.c \ nir/nir_opt_conditional_discard.c \ nir/nir_opt_constant_folding.c \ + nir/nir_opt_copy_prop_vars.c \ nir/nir_opt_copy_propagate.c \ nir/nir_opt_cse.c \ nir/nir_opt_dce.c \ diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 544d4ba..27ef633 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2489,6 +2489,8 @@ bool nir_opt_global_to_local(nir_shader *shader); bool nir_copy_prop(nir_shader *shader); +bool nir_opt_copy_prop_vars(nir_shader *shader); + bool nir_opt_cse(nir_shader *shader); bool nir_opt_dce(nir_shader *shader); diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c new file mode 100644 index 000..728e476 --- /dev/null +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c @@ -0,0 +1,799 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "nir.h" +#include "nir_builder.h" + +/** + * Variable-based copy propagation + * + * Normally, NIR trusts in SSA form for most of its copy-propagation needs. + * However, there are cases, especially when dealing with indirects, where SSA + * won't help you. This pass is for those times. Specifically, it handles + * the following things that the rest of NIR can't: + * + * 1) Copy-propagation on variables that have indirect access. This includes + * propagating from indirect stores into indirect loads. + * + * 2) Dead code elimination of store_var and copy_var intrinsics based on + * killed destination values. + * + * 3) Removal of redundant load_var intrinsics. We can't trust regular CSE + * to do this because it isn't aware of variable writes that may alias the + * value and make the former load invalid. + * + * Unfortunately, properly handling all of those cases makes this path rather + * complex. In order to avoid additional complexity, this pass is entirely + * block-local. If we tried to make it local the data-flow analysis would + * rapidly get out of hand. Fortunately, for anything that is only ever + * accessed directly, we get SSA based copy-propagation which is extremely + * powerful so this isn't that great a loss. + */ + +struct value { + bool is_ssa; + union { + nir_ssa_def *ssa[4]; + nir_deref_var *deref; + }; +}; + +struct copy_entry { + struct list_head link; + + nir_instr *store_instr[4]; + + unsigned comps_may_be_read; + struct value src; + + nir_deref_var *dst; +}; + +struct copy_prop_var_state { + nir_shader *shader; + + void *mem_ctx; + + struct list_head copies; + + /* We're going to be allocating and deleting a lot of copy entries so we'll +* keep a free list to avoid thrashing malloc too badly. +*/ + struct list_head copy_free_list; + + bool progress; +}; + +static struct copy_entry * +copy_entry_create(struct copy_prop_var_state *state, + nir_deref_var *dst_deref) +{ + struct copy_entry *entry; + if (!list_empty(>copy_free_list)) { + struct list_head *item = state->copy_free_list.next; + list_del(item); + entry = LIST_ENTRY(struct copy_entry, item, link); + memset(entry, 0, sizeof(*entry)); + } else { + entry = rzalloc(state->mem_ctx, struct copy_entry); + } + + entry->dst = dst_deref; + list_add(>link, >copies); + + return entry; +} +