summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-12-01 13:51:03 -0800
committerJason Ekstrand <[email protected]>2017-01-12 14:56:55 -0800
commit087e172179be3b9be89955cd012a26ea770ee9eb (patch)
tree6432bcfbb0921c2a8a2f6485adf2f40e6bd1dcc4
parente9a4ec4bd806107223b4e3f656071de3a08756a0 (diff)
nir/gcm: Rework the schedule late loop
This fixes a bug in code motion that occurred when the best block is the same as the schedule early block. In this case, because we're checking (lca != def->parent_instr->block) at the top of the loop, we never get to the check for loop depth so we wouldn't move it out of the loop. This commit reworks the loop to be a simple for loop up the dominator chain and we place the (lca != def->parent_instr->block) check at the end of the loop. Reviewed-by: Matt Turner <[email protected]>
-rw-r--r--src/compiler/nir/nir_opt_gcm.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/compiler/nir/nir_opt_gcm.c b/src/compiler/nir/nir_opt_gcm.c
index 77eb8e6da5a..9d7f59c8b33 100644
--- a/src/compiler/nir/nir_opt_gcm.c
+++ b/src/compiler/nir/nir_opt_gcm.c
@@ -326,12 +326,13 @@ gcm_schedule_late_def(nir_ssa_def *def, void *void_state)
* as far outside loops as we can get.
*/
nir_block *best = lca;
- while (lca != def->parent_instr->block) {
- assert(lca);
- if (state->blocks[lca->index].loop_depth <
+ for (nir_block *block = lca; block != NULL; block = block->imm_dom) {
+ if (state->blocks[block->index].loop_depth <
state->blocks[best->index].loop_depth)
- best = lca;
- lca = lca->imm_dom;
+ best = block;
+
+ if (block == def->parent_instr->block)
+ break;
}
def->parent_instr->block = best;