summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2019-08-30 11:35:26 -0500
committerDylan Baker <dylan@pnwbakers.com>2019-09-09 09:14:48 -0700
commit7635b74acf229341b636aaa6f7bc3abed65146e0 (patch)
tree0f7b7cd2b9c01fcbd1f0be5a1393870a1ef669e0
parent2012c4a75cb5ce87a17e0cc6238d6363a2ef6c30 (diff)
nir/dead_cf: Repair SSA if the pass makes progress
The dead_cf pass calls into the CF manipulation helpers which attempt to keep NIR's SSA form sane. However, when the only break is removed from a loop, dominance gets messed up anyway because the CF SSA clean-up code only looks at phis and doesn't consider the case of code becoming unreachable. One solution to this would be to put the loop into LCSSA form before we modify any of its contents. Another (and the approach taken by this pass) is to just run the repair_ssa pass afterwards because the CF manipulation helpers are smart enough to keep all the use/def stuff sane; they just don't always preserve dominance properties. While we're here, we clean up some bogus indentation. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111405 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111069 Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com> (cherry picked from commit c832820ce959ae7c2b4971befceae634d800330f)
-rw-r--r--src/compiler/nir/nir_opt_dead_cf.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/compiler/nir/nir_opt_dead_cf.c b/src/compiler/nir/nir_opt_dead_cf.c
index 33f3565c564..0a5c4a5de3c 100644
--- a/src/compiler/nir/nir_opt_dead_cf.c
+++ b/src/compiler/nir/nir_opt_dead_cf.c
@@ -355,11 +355,22 @@ opt_dead_cf_impl(nir_function_impl *impl)
if (progress) {
nir_metadata_preserve(impl, nir_metadata_none);
- } else {
+
+ /* The CF manipulation code called by this pass is smart enough to keep
+ * from breaking any SSA use/def chains by replacing any uses of removed
+ * instructions with SSA undefs. However, it's not quite smart enough
+ * to always preserve the dominance properties. In particular, if you
+ * remove the one break from a loop, stuff in the loop may still be used
+ * outside the loop even though there's no path between the two. We can
+ * easily fix these issues by calling nir_repair_ssa which will ensure
+ * that the dominance properties hold.
+ */
+ nir_repair_ssa_impl(impl);
+ } else {
#ifndef NDEBUG
impl->valid_metadata &= ~nir_metadata_not_properly_reset;
#endif
- }
+ }
return progress;
}