aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2023-08-23 11:17:20 +0200
committerJan Hubicka <jh@suse.cz>2023-08-23 11:17:20 +0200
commit936a12331a2bd95e9003221e292719b7ffcf07d0 (patch)
tree361e3311595ebc3b99506a8af574dc8672357955 /gcc
parent7a2e232fa6e0ce2120dedcb340d683f6ac9b3f19 (diff)
downloadgcc-936a12331a2bd95e9003221e292719b7ffcf07d0.zip
gcc-936a12331a2bd95e9003221e292719b7ffcf07d0.tar.gz
gcc-936a12331a2bd95e9003221e292719b7ffcf07d0.tar.bz2
Fix handling of static exists in loop_ch
This patch fixes wrong return value in should_duplicate_loop_header_p. Doing so uncovered suboptimal decisions on some jump threading testcases where we choose to stop duplicating just before basic block that has zero cost and duplicating so would be always a win. This is because the heuristics trying to choose right point to duplicate all winning blocks and to get loop to be do_while did not account zero_cost blocks in all cases. The patch simplifies the logic by simply remembering zero cost blocks and handling them last after the right stopping point is chosen. gcc/ChangeLog: * tree-ssa-loop-ch.cc (enum ch_decision): Fix comment. (should_duplicate_loop_header_p): Fix return value for static exits. (ch_base::copy_headers): Improve handling of ch_possible_zero_cost. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/copy-headers-9.c: Update template.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c3
-rw-r--r--gcc/tree-ssa-loop-ch.cc30
2 files changed, 15 insertions, 18 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c
index b49d1fc..11ee294 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-9.c
@@ -13,7 +13,6 @@ void test (int m, int n)
}
while (i<10);
}
-/* { dg-final { scan-tree-dump-times "Duplicating bb . is a win" 2 "ch2" } } */
-/* { dg-final { scan-tree-dump-times "Duplicating bb . is a win. it has zero" 1 "ch2" } } */
+/* { dg-final { scan-tree-dump-times "Duplicating bb . is a win" 1 "ch2" } } */
/* { dg-final { scan-tree-dump-times "Will duplicate bb" 2 "ch2" } } */
/* { dg-final { scan-tree-dump "is now do-while loop" "ch2" } } */
diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 6cdb87a..461416e 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -176,7 +176,7 @@ enum ch_decision
ch_impossible,
/* We can copy it if it enables wins. */
ch_possible,
- /* We can "cop" it if it enables wins and doing
+ /* We can "copy" it if it enables wins and doing
so will introduce no new code. */
ch_possible_zero_cost,
/* We want to copy. */
@@ -464,7 +464,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop,
TODO: Even if duplication costs some size we may opt to do so in case
exit probability is significant enough (do partial peeling). */
if (static_exit)
- return code_size_cost ? ch_possible_zero_cost : ch_win;
+ return !code_size_cost ? ch_possible_zero_cost : ch_possible;
/* We was not able to prove that conditional will be eliminated. */
int insns = estimate_num_insns (last, &eni_size_weights);
@@ -824,6 +824,7 @@ ch_base::copy_headers (function *fun)
int last_win_nheaders = 0;
bool last_win_invariant_exit = false;
ch_decision ret;
+ auto_vec <ch_decision, 32> decision;
hash_set <edge> *invariant_exits = new hash_set <edge>;
hash_set <edge> *static_exits = new hash_set <edge>;
while ((ret = should_duplicate_loop_header_p (header, loop, ranger,
@@ -833,6 +834,7 @@ ch_base::copy_headers (function *fun)
!= ch_impossible)
{
nheaders++;
+ decision.safe_push (ret);
if (ret >= ch_win)
{
last_win_nheaders = nheaders;
@@ -841,20 +843,6 @@ ch_base::copy_headers (function *fun)
fprintf (dump_file, " Duplicating bb %i is a win\n",
header->index);
}
- /* Duplicate BB if has zero cost but be sure it will not
- imply duplication of other BBs. */
- else if (ret == ch_possible_zero_cost
- && (last_win_nheaders == nheaders - 1
- || (last_win_nheaders == nheaders - 2
- && last_win_invariant_exit)))
- {
- last_win_nheaders = nheaders;
- last_win_invariant_exit = false;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- " Duplicating bb %i is a win; it has zero cost\n",
- header->index);
- }
else
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " May duplicate bb %i\n", header->index);
@@ -884,6 +872,16 @@ ch_base::copy_headers (function *fun)
fprintf (dump_file,
" Duplicating header BB to obtain do-while loop\n");
}
+ /* "Duplicate" all BBs with zero cost following last basic blocks we
+ decided to copy. */
+ while (last_win_nheaders < (int)decision.length ()
+ && decision[last_win_nheaders] == ch_possible_zero_cost)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ " Duplicating extra bb is a win; it has zero cost\n");
+ last_win_nheaders++;
+ }
if (last_win_nheaders)
candidates.safe_push ({loop, last_win_nheaders,