On Tue, 17 Nov 2020, Jan Hubicka wrote: > > On Tue, Nov 17, 2020 at 01:33:48AM -0500, Jason Merrill via Gcc-patches > > wrote: > > > > > Why doesn't the middle-end warning work for inline functions? > > > > > > > > It does but only when they're called (and, as usual, also unless > > > > the uninitialized use is eliminated). > > > > > > Yes, but why? I assume because we don't bother going through all the > > > phases > > > of compilation for unused inlines, but couldn't we change that when we're > > > asking for (certain) warnings? > > > > CCing Richard and Honza on this. > > > > I think for unused functions we don't even gimplify unused functions, the > > cgraph code just throws them away. Even trying just to run the first few > > passes (gimplification up to uninit1) would have several high costs, > Note that uninit1 is a late pass so it is not just few passes we speak > about. Late passes are run only on cocde that really lands in .s file > so enabling them would mean splitting the pass queue and running another > unreachable code somewhere. That would confuse inliner and other IPA > passes since they will have to somehow deal with dead code in their > program size estimate and also affect LTO. > > Even early passes are run only on reachable portion of program, since > functions are analyzed by cgraphunit on demand (only if they are > analyzed by someone else). Simlar logic is also done be C++ FE to decide > what templates. Changling this would also have quite some compile > time/memory use impact.
There's also impact on various IPA heuristics - we'd need to make sure to not account any doings to unreachable functions or effects of them still there (do we want to inline into them? do we want heuristics of inline into all functions affected?) So IMHO not a good idea. GCC isn't a static analysis engine ... Richard. > There is -fkeep-inline-functions. > > > the tree body of everything unneeded would be unshared, reemitted as GIMPLE, > > then cfg created for it and turned into SSA form only to get the > > uninitialized warnings (for that warning we could stop there and throw the > > bodies away). > > I think we would need to try that on some larger C++ codebases and see what > > the compile time memory and time hit would be. > > > > Anyway, taking e.g. Marek's Wuninitialized-17.C testcase, if I add > > S s; > > at the end to make the S::S() ctor used, uninit1 does warn > > (guess many of the warnings would be dependent on -flifetime-dse=2 > > inserted CLOBBERs, thankfully that is the default), but the warnings then > > look fairly cryptic: > > Wuninitialized-17.C: In constructor ?S::S()?: > > Wuninitialized-17.C:22:14: warning: ?*<unknown>.S::y? is used uninitialized > > [-Wuninitialized] > > 22 | S() : a{1, y} { } // { dg-warning "field .S::y. is used > > uninitialized" } > > | ^ > > Guess we should at least try to improve this special case's printing for > > C++, the IL > > is: > > *this_3(D) ={v} {CLOBBER}; > > this_3(D)->a.a = 1; > > _1 = this_3(D)->y; > > this_3(D)->a.b = _1; > > and we could figure out that this is in a METHOD_TYPE fndecl, the MEM_REF > > has as address the default def of this SSA_NAME where this is the first > > argument of the method and the PARM_DECL has this name and is > > DECL_ARTIFICIAL to print it as this->S::y instead of *<unknown>.S::y. > > I bet that code is in error.c ... > > > > If the costs of gimplifying, creating cfg and SSA form for all functions > > would be too high (I think it would be, but haven't measured it), then > > perphaps it might be useful for Marek's FE code to handle the easiest cases > > and punt when it gets more complicated? > > I mean e.g. the a(b=1) cases, or can't e.g. some member be initialized only > > in some other function - a (foo (&b)) where foo would store to what the > > pointer points to (or reference refers to)? > > > > Jakub > > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imend