Mesa (staging/21.3): nir/dce: fix DCE of loops with a halt or return instruction in the pre-header

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Dec 1 00:23:45 UTC 2021


Module: Mesa
Branch: staging/21.3
Commit: a9cf12851830b015e3bcfb632521ff6a61cf9af4
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a9cf12851830b015e3bcfb632521ff6a61cf9af4

Author: Rhys Perry <pendingchaos02 at gmail.com>
Date:   Fri Apr 16 13:18:33 2021 +0100

nir/dce: fix DCE of loops with a halt or return instruction in the pre-header

If there is a halt or return instruction right before a loop with a single
continue, we would have taken the fast path intended for loops without
continues.

Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Tested-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Fixes: 71a985d80b1 ("nir/dce: perform DCE for unlooped instructions in a single pass")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10284>
(cherry picked from commit 2fe13aa2ad7367d83a19da2332d9ec55cb3a3a6f)

---

 .pick_status.json              |  2 +-
 src/compiler/nir/nir_opt_dce.c | 11 +++++++----
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 4ab8f9b21cb..497a43be020 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -193,7 +193,7 @@
         "description": "nir/dce: fix DCE of loops with a halt or return instruction in the pre-header",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": "71a985d80b1c29cced979b3c8d16f74463d1170b"
     },
diff --git a/src/compiler/nir/nir_opt_dce.c b/src/compiler/nir/nir_opt_dce.c
index 532ad4ff95d..49e7ac015c2 100644
--- a/src/compiler/nir/nir_opt_dce.c
+++ b/src/compiler/nir/nir_opt_dce.c
@@ -166,18 +166,21 @@ dce_cf_list(struct exec_list *cf_list, BITSET_WORD *defs_live,
       case nir_cf_node_loop: {
          nir_loop *loop = nir_cf_node_as_loop(cf_node);
 
+         struct loop_state inner_state;
+         inner_state.preheader = nir_cf_node_as_block(nir_cf_node_prev(cf_node));
+         inner_state.header_phis_changed = false;
+
          /* Fast path if the loop has no continues: we can remove instructions
           * as we mark the others live.
           */
-         if (nir_loop_first_block(loop)->predecessors->entries == 1) {
+         struct set *predecessors = nir_loop_first_block(loop)->predecessors;
+         if (predecessors->entries == 1 &&
+             _mesa_set_next_entry(predecessors, NULL)->key == inner_state.preheader) {
             progress |= dce_cf_list(&loop->body, defs_live, parent_loop);
             break;
          }
 
          /* Mark instructions as live until there is no more progress. */
-         struct loop_state inner_state;
-         inner_state.preheader = nir_cf_node_as_block(nir_cf_node_prev(cf_node));
-         inner_state.header_phis_changed = false;
          do {
             /* dce_cf_list() resets inner_state.header_phis_changed itself, so
              * it doesn't have to be done here.



More information about the mesa-commit mailing list