summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2019-02-10 22:23:01 -0600
committerDylan Baker <[email protected]>2019-02-11 16:24:42 -0800
commitad2b712a56ef1ef85bf5b892092754cfa1727eae (patch)
tree324f3bcfb94ddb69b5dbdd889f3e6cf857a75815
parent07e299a0a071c9880f3f7eb9e97a28a34bf16891 (diff)
nir/deref: Rematerialize parents in rematerialize_derefs_in_use_blocks
When nir_rematerialize_derefs_in_use_blocks_impl was first written, I attempted to optimize things a bit by not bothering to re-materialize the sources of deref instructions figuring that the final caller would take care of that. However, in the case of more complex deref chains where the first link or two lives in block A and then another link and the load/store_deref intrinsic live in block B it doesn't work. The code in rematerialize_deref_in_block looks at the tail of the chain, sees that it's already in block B and skips it, not realizing that part of the chain also lives in block A. The easy solution here is to just rematerialize deref sources of deref instructions as well. This may potentially lead to a few more deref instructions being created by the conditions required for that to actually happen are fairly unlikely and, thanks to the caching, it's all linear time regardless. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109603 Fixes: 7d1d1208c2b "nir: Add a small pass to rematerialize derefs per-block" Reviewed-by: Alejandro PiƱeiro <[email protected]> (cherry picked from commit 9e6a6ef0d45a5bb61a541c495fe12e54e646ecfe)
-rw-r--r--src/compiler/nir/nir_deref.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index 2f5fda643ca..1af45a45deb 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -574,10 +574,9 @@ nir_rematerialize_derefs_in_use_blocks_impl(nir_function_impl *impl)
_mesa_hash_table_clear(state.cache, NULL);
nir_foreach_instr_safe(instr, block) {
- if (instr->type == nir_instr_type_deref) {
- nir_deref_instr_remove_if_unused(nir_instr_as_deref(instr));
+ if (instr->type == nir_instr_type_deref &&
+ nir_deref_instr_remove_if_unused(nir_instr_as_deref(instr)))
continue;
- }
state.builder.cursor = nir_before_instr(instr);
nir_foreach_src(instr, rematerialize_deref_src, &state);