Hi, this patch fixes PR65511.
For the testcase, before transform_to_exit_first_loop the back-edge probability is 99%:
... ;; basic block 5, loop depth 1, count 0, freq 7920, maybe hot ;; prev block 11, next block 6, flags: (NEW) ;; pred: 11 [100.0%] (FALLTHRU) ;; 7 [100.0%] (FALLTHRU,EXECUTABLE) # .MEM_15 = PHI <.MEM_3(D)(11), .MEM_9(7)> # ivtmp_22 = PHI <0(11), ivtmp_23(7)> # RANGE [0, 1000] NONZERO 1023 i_14 = ivtmp_22; # VUSE <.MEM_15> _6 = aD.1830[i_14]; # VUSE <.MEM_15> _7 = bD.1831[i_14]; # RANGE [0, 4294967295] _8 = _6 + _7; # .MEM_9 = VDEF <.MEM_15> cD.1832[i_14] = _8; # RANGE [1, 1001] NONZERO 1023 i_10 = i_14 + 1; # RANGE [0, 1000] NONZERO 1023 i.0_4 = (unsigned intD.9) i_10; if (ivtmp_22 < _12) goto <bb 7>; else goto <bb 6>; ;; succ: 7 [99.0%] (TRUE_VALUE,EXECUTABLE) ;; 6 [1.0%] (FALSE_VALUE,EXECUTABLE) ... But after transform_to_exit_first_loop, the back-edge has a probability of 100%: ... ;; basic block 5, loop depth 1, count 0, freq 7920, maybe hot ;; prev block 11, next block 13, flags: (NEW) ;; pred: 11 [100.0%] (FALLTHRU) ;; 7 [100.0%] (FALLTHRU,EXECUTABLE) # .MEM_24 = PHI <.MEM_3(D)(11), .MEM_9(7)> # ivtmp_25 = PHI <0(11), ivtmp_23(7)> if (ivtmp_25 < _12) goto <bb 13>; else goto <bb 14>; ;; succ: 13 [100.0%] (TRUE_VALUE,EXECUTABLE) ;; 14 (FALSE_VALUE,EXECUTABLE) ... This patch fixes that: ... ;; basic block 5, loop depth 1, count 0, freq 7920, maybe hot ;; prev block 11, next block 13, flags: (NEW) ;; pred: 11 [100.0%] (FALLTHRU) ;; 7 [100.0%] (FALLTHRU,EXECUTABLE) # .MEM_24 = PHI <.MEM_3(D)(11), .MEM_9(7)> # ivtmp_25 = PHI <0(11), ivtmp_23(7)> if (ivtmp_25 < _12) goto <bb 13>; else goto <bb 14>; ;; succ: 13 [99.0%] (TRUE_VALUE,EXECUTABLE) ;; 14 [1.0%] (FALSE_VALUE,EXECUTABLE) ... Bootstrapped and reg-tested on x86_64. OK for, I'd guess, stage1? Thanks, - Tom
Fix edge probabilities in gimple_duplicate_sese_tail 2015-03-27 Tom de Vries <t...@codesourcery.com> PR tree-optimization/65511 * tree-cfg.c (gimple_duplicate_sese_tail): Fix edge probabilities. * gcc.dg/parloops-prob.c: New test. --- gcc/testsuite/gcc.dg/parloops-prob.c | 21 +++++++++++++++++++++ gcc/tree-cfg.c | 3 +++ 2 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/parloops-prob.c diff --git a/gcc/testsuite/gcc.dg/parloops-prob.c b/gcc/testsuite/gcc.dg/parloops-prob.c new file mode 100644 index 0000000..a3e767c --- /dev/null +++ b/gcc/testsuite/gcc.dg/parloops-prob.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target pthread } */ +/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-fixup_cfg4-all" } */ + +#define N 1000 + +unsigned int a[N]; +unsigned int b[N]; +unsigned int c[N]; + +void +f (unsigned int n) +{ + int i; + + for (i = 0; i < n; ++i) + c[i] = a[i] + b[i]; +} + +/* { dg-final { scan-tree-dump-not "freq 0" "fixup_cfg4" } } */ +/* { dg-final { cleanup-tree-dump "fixup_cfg4" } } */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 64bdc92..c7a7c4d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -6177,6 +6177,7 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU gphi *phi; tree def; struct loop *target, *aloop, *cloop; + int exit_prob = exit->probability; gcc_assert (EDGE_COUNT (exit->src->succs) == 2); exits[0] = exit; @@ -6268,6 +6269,8 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU sorig = single_succ_edge (switch_bb); sorig->flags = exits[1]->flags; snew = make_edge (switch_bb, nentry_bb, exits[0]->flags); + snew->probability = exit_prob; + sorig->probability = REG_BR_PROB_BASE - exit_prob; /* Register the new edge from SWITCH_BB in loop exit lists. */ rescan_loop_exit (snew, true, false); -- 1.9.1