Take the following simple example loop: void __show_backtrace(void *rw) { while(rw); } We get invalid warnings in the tree dumps about profiling info being wrong: __show_backtrace (rw) { <L3>:; if (rw_1 != 0B) goto <L0>; else goto <L2>; Invalid sum of incoming frequencies 9879, should be 8900 <L0>:; goto <bb 1> (<L0>); Invalid sum of incoming frequencies 121, should be 1100 <L2>:; return; } I am filing this because for 4.2, I hear that the rtl level profiling info will be coming from the tree level (after loop.c is removed).
DOM seems to be innocent here. Before DOM the header is copied and DOM notice that loop is infinite when entered. There is no sane way to represent infinite loop in profile (ie it's frequency would have to be either infinity or 0) so without rescaling the rest we can't really do much.
(In reply to comment #1) > DOM seems to be innocent here. Hmm, VRP gets it correct, in that there are no warnings for the following code: void __show_backtrace(void *rw) { if (rw == 0) return; L0:; if (rw != 0) goto L0; } Which is equivalent to the what the trees look when it gets to DOM but then again VRP happens before profile happens.
This will be worth rechecking after Teresa checks in her fixes for updating profiling information in the jump threading code.
This is a dup of bug 25623. It is cfgcleanup after jump threading which is causing it. *** This bug has been marked as a duplicate of bug 25623 ***
This is now threaded by threadfull2: Checking profitability of path (backwards): bb:3 (2 insns) bb:2 Control statement insns: 2 Overall: 0 insns path: 2->3->xx REJECTED Checking profitability of path (backwards): bb:3 (2 insns) bb:5 (latch) Control statement insns: 2 Overall: 0 insns Checking profitability of path (backwards): [1] Registering jump thread: (5, 3) incoming edge; (3, 5) nocopy; path: 5->3->5 SUCCESS Merging blocks 2 and 3 Merging blocks 5 and 6 fix_loop_structure: fixing up loops for function fix_loop_structure: removing loop 1 flow_loops_find: discovered new loop 2 with header 3 and we get correct profile: void __show_backtrace (void * rw) { ;; basic block 2, loop depth 0, count 118111600 (estimated locally), maybe hot ;; prev block 0, next block 3, flags: (NEW, REACHABLE, VISITED) ;; pred: ENTRY [always] count:118111600 (estimated locally) (FALLTHRU,EXECUTABLE) if (rw_1(D) != 0B) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] ;; succ: 3 [never (guessed)] count:0 (estimated locally) (TRUE_VALUE,EXECUTABLE) ;; 4 [always (guessed)] count:118111600 (estimated locally) (FALSE_VALUE,EXECUTABLE) ;; basic block 3, loop depth 1, count 955630224 (estimated locally), maybe hot ;; prev block 2, next block 4, flags: (NEW, REACHABLE, VISITED) ;; pred: 2 [never (guessed)] count:0 (estimated locally) (TRUE_VALUE,EXECUTABLE) ;; 3 [always] count:955630224 (estimated locally) (FALLTHRU,DFS_BACK) goto <bb 3>; [100.00%] ;; succ: 3 [always] count:955630224 (estimated locally) (FALLTHRU,DFS_BACK) ;; basic block 4, loop depth 0, count 118111600 (estimated locally), maybe hot ;; prev block 3, next block 1, flags: (NEW, REACHABLE, VISITED) ;; pred: 2 [always (guessed)] count:118111600 (estimated locally) (FALSE_VALUE,EXECUTABLE) return; ;; succ: EXIT [always] count:118111600 (estimated locally) (EXECUTABLE) q.c:4:1 }