Hi, Honza & Martin, Would you please take some time to review proposal and patches of whole program devirtualization? We have to say, this feature is not 100% safe, but provides us a way to deploy correct WPD on C++ program if we elaborately prepare linked libraries to ensure rtti symbols are contained, which is always the case for libstdc++ and well-composed third-part c++libraries with default gcc options. If not, we could get an expected rebuild with desirable options, and this does not require invasive modification on source codes, which is an advantage over LLVM visibility-based scheme. Now gcc-12 dev branch is at late stage since time will step into Nov. Anyway, we are not sure it is acceptable or not. But if yes, getting it in before code freeze would be a good time point. And made some minor changes on patches, also posted RFC link here for your convenience. (https://gcc.gnu.org/pipermail/gcc/2021-August/237132.html) Thanks, Feng ________________________________________ From: Feng Xue OS Sent: Saturday, September 18, 2021 5:38 PM To: Jason Merrill; Jan Hubicka; mjambor@suse.cz; Richard Biener; gcc-patches@gcc.gnu.org Subject: Re: [PATCH/RFC 1/2] WPD: Enable whole program devirtualization >On 9/16/21 22:29, Feng Xue OS wrote: >>> On 9/16/21 05:25, Feng Xue OS via Gcc-patches wrote: >>>> This and following patches are composed to enable full devirtualization >>>> under whole program assumption (so also called whole-program >>>> devirtualization, WPD for short), which is an enhancement to current >>>> speculative devirtualization. The base of the optimization is how to >>>> identify class type that is local in terms of whole-program scope, at >>>> least those class types in libstdc++ must be excluded in some way. >>>> Our means is to use typeinfo symbol as identity marker of a class since >>>> it is unique and always generated once the class or its derived type >>>> is instantiated somewhere, and rely on symbol resolution by >>>> lto-linker-plugin to detect whether a typeinfo is referenced by regular >>>> object/library, which indirectly tells class types are escaped or not. >>>> The RFC at https://gcc.gnu.org/pipermail/gcc/2021-August/237132.html >>>> gives more details on that. >>>> >>>> Bootstrapped/regtested on x86_64-linux and aarch64-linux. >>>> >>>> Thanks, >>>> Feng >>>> >>>> ---- >>>> 2021-09-07 Feng Xue >>>> >>>> gcc/ >>>> * common.opt (-fdevirtualize-fully): New option. >>>> * class.c (build_rtti_vtbl_entries): Force generation of typeinfo >>>> even -fno-rtti is specificied under full devirtualization. >>> >>> This makes -fno-rtti useless; rather than this, you should warn about >>> the combination of flags and force flag_rtti on. It also sounds like >>> you depend on the library not being built with -fno-rtti. >> >> Although rtti is generated by front-end, we will remove it after lto symtab >> merge, which is meant to keep same behavior as -fno-rtti. > > Ah, the cp/ change is OK, then, with a comment about that. > >> Yes, regular library to be linked with should contain rtti data, otherwise >> WPD could not deduce class type usage safely. By default, we can think >> that it should work for libstdc++, but it probably becomes a problem for >> user library, which might be avoided if we properly document this >> requirement and suggest user doing that when using WPD. > > Yes, I would expect that external libraries would be built with RTTI on > to allow users to use RTTI features even if they aren't used within the > library. But it's good to document it as a requirement. > >> + /* If a class with virtual base is only instantiated as >> + subobjects of derived classes, and has no complete object in >> + compilation unit, merely construction vtables will be involved, >> + its primary vtable is really not needed, and subject to being >> + removed. So once a vtable node is encountered, for all >> + polymorphic base classes of the vtable's context class, always >> + force generation of primary vtable nodes when full >> + devirtualization is enabled. */ > > Why do you need the primary vtable if you're relying on RTTI info? > Construction vtables will point to the same RTTI node. At middle end, the easiest way to get vtable of type is via TYPE_BINFO(type), it is the primary one. And WPD relies on existence of varpool_node of the vtable decl to determine if the type has been removed (when it is never instantiated), so we will force generation of vtable node at very early stage. Additionally, construction vtable (C-in-D) belongs to the class (D) of complete object, not the class (C) of subobject actually being constructed for, it is not easy to correlate construction vtable with the subobject class (C) after front end. > >> + /* Public class w/o key member function (or local class in a public >> + inline function) requires COMDAT-like vtable so as to be shared >> + among units. But C++ privatizing via -fno-weak would introduce >> + multiple static vtable copies for one class in merged lto symbol >> + table. This breaks one-to-one correspondence between class and >> + vtable, and makes class liveness check become not that easy. To >> + be simple, we exclude such kind of class from our choice list. > > Same question. Also, why would you use -fno-weak? Forcing multiple > copies of things we're perfectly capable of combining seems like a > strange choice. You can privatize things with the symbol visibility > controls or RTLD_LOCAL. We expect that user does not specify -fno-weak for WPD. But if specified, we should correctly handle that and bypass the type. And indeed there is no need to force generation of vtable under this situation. But if vtable is not keyed to any compilation unit, we might never have any copy of it in ordinary build, while its class type is meaningful to whole-program analysis, such as an abstract root class. Thanks, Feng