On Wed, 9 Feb 2022, Martin Sebor wrote: > On 2/9/22 00:12, Richard Biener wrote: > > On Tue, 8 Feb 2022, Jeff Law wrote: > > > >> > >> > >> On 2/8/2022 12:03 AM, Richard Biener via Gcc-patches wrote: > >>> The following improves early uninit diagnostics by computing edge > >>> reachability using our value-numbering framework in its cheapest > >>> mode and ignoring unreachable blocks when looking > >>> for uninitialized uses. To not ICE with -fdump-tree-all the > >>> early uninit pass needs a dumpfile since VN tries to dump statistics. > >>> > >>> For gimple-match.c at -O0 -g this causes a 2% increase in compile-time. > >>> > >>> In theory all early diagnostic passes could benefit from a VN run but > >>> that would require more refactoring that's not appropriate at this stage. > >>> This patch addresses a GCC 12 diagnostic regression and also happens to > >>> fix one XFAIL in gcc.dg/uninit-pr20644-O0.c > >>> > >>> Bootstrapped and tested on x86_64-unknown-linux-gnu, OK for trunk? > >>> > >>> Thanks, > >>> Richard. > >>> > >>> 2022-02-04 Richard Biener <rguent...@suse.de> > >>> > >>> PR tree-optimization/104373 > >>> * tree-ssa-sccvn.h (do_rpo_vn): New export exposing the > >>> walk kind. > >>> * tree-ssa-sccvn.cc (do_rpo_vn): Export, get the default > >>> walk kind as argument. > >>> (run_rpo_vn): Adjust. > >>> (pass_fre::execute): Likewise. > >>> * tree-ssa-uninit.cc (warn_uninitialized_vars): Skip > >>> blocks not reachable. > >>> (execute_late_warn_uninitialized): Mark all edges as > >>> executable. > >>> (execute_early_warn_uninitialized): Use VN to compute > >>> executable edges. > >>> (pass_data_early_warn_uninitialized): Enable a dump file, > >>> change dump name to warn_uninit. > >>> > >>> * g++.dg/warn/Wuninitialized-32.C: New testcase. > >>> * gcc.dg/uninit-pr20644-O0.c: Remove XFAIL. > >> I'm conflicted on this ;-) > >> > >> I generally lean on the side of eliminating false positives in these > >> diagnostics. So identifying unreachable blocks and using that to prune the > >> set of warnings we generate, even at -O0 is good from that point of view. > >> > >> But doing something like this has many of the problems that relying on > >> optimizations does, even if we don't optimize away the unreachable code. > >> Right now the warning should be fairly stable at -O0 -- the set of > >> diagnostics > >> you get isn't going to change a lot release to release which is important > >> to > >> some users. Second, at -O0 whether or not you get a warning isn't a > >> function > >> of how good our unreachable code analysis might be. > >> > >> This was quite a contentious topic many years ago. So much that I dropped > >> some work on Wuninit on the floor as I just couldn't take the arguing. So > >> be > >> aware that you might be opening a can of worms. > >> > >> So the question comes down to a design decision. What's more important to > >> the end users? Fewer false positives or better stability in the warning? > >> I > >> think the former, but there's certainly been a vocal group that prefers the > >> latter. > > > > I see - I didn't think of this aspect at all but that means I have no > > idea on whether it is important or not ... > > > > In our own setup we're running into "instabilities" with optimization > > when building packages that enable -Werror, so I can see shops doing > > dev builds at -O0 with warnings and -Werror but drop -Werror for > > optimized builds. > > > >> On the implementation side I have zero concerns. Looking further out, > >> ISTM > >> we could mark the blocks as unreachable (rather than deducing it from edge > >> flags). That would make it pretty easy to mark those blocks relatively > >> early > >> and allow us to suppress any middle end diagnostic occurring in an > >> unreachable > >> block. > > > > So what I had in mind is that for the set of early diagnostic passes > > > > PUSH_INSERT_PASSES_WITHIN (pass_build_ssa_passes) > > NEXT_PASS (pass_fixup_cfg); > > NEXT_PASS (pass_build_ssa); > > NEXT_PASS (pass_warn_printf); > > NEXT_PASS (pass_warn_nonnull_compare); > > NEXT_PASS (pass_early_warn_uninitialized); > > NEXT_PASS (pass_warn_access, /*early=*/true); > > > > we'd run VN and keep it's lattice around (and not just the > > EDGE_EXECUTABLE flags). That would for example allow > > pass_warn_nonnull_compare to see that in > > > > void foo (void *p __attribute__((nonnull))) > > { > > void *q = p; > > if (q) > > bar (q); > > } > > > > we are comparing a never NULL pointer. Currently the q = p copy > > makes it not realize this. Likewise some constants can be > > propagated this way. > > > > Of course using the VN lattice means quite some changes in those > > passes. Even without the VN lattice having unreachable edges > > marked could improve diagnostics for, say PHI nodes, if only > > a single executable edge remains. > > > > Martin, do you have any thoughts here? Any opinion on the patch > > that for now just marks (not) executable edges to prune diagnostics at > > -O0? > > Many middle end warnings now run at -O0. Thanks to Ranger (and > the pointer_query solution), they can identify many of the same > problem statements as with optimization. But for the same reason > they're also more prone to false positives for unreachable code > because DCE doesn't run at -O0. So in my mind, identifying at > least some of it then, is a step in the right direction. > > So for the avoidance of doubt, I'm in favor of both the patch and > extending the approach to other warnings.
Thanks, I'm going to push the patch then. Richard.