https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104550
--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> --- On Wed, 16 Feb 2022, jakub at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104550 > > Jakub Jelinek <jakub at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > CC| |jakub at gcc dot gnu.org > > --- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- > Well, for the .DEFERRED_INIT case if the var ends up in memory, I really don't > see the point in any clear_padding, .DEFERRED_INIT expansion should just > initialize the whole DECL_RTL MEM_P slot with the pattern it wants, trying to > initialize only the non-padding bits and then only the padding bits next to > each other is a waste of CPU cycles. > Another case are C++ vars with non-trivial ctors, if we for -flifetime-dse=2 > emit CLOBBERs at the start of such ctors, then IMNSHO the right thing is to > emit the zero or pattern initialization in those constructors, perhaps through > .DEFERRED_INIT. > This is the start_preparsed_function > if (!processing_template_decl > && (flag_lifetime_dse > 1) > && DECL_CONSTRUCTOR_P (decl1) > && !DECL_CLONED_FUNCTION_P (decl1) > /* Clobbering an empty base is harmful if it overlays real data. */ > && !is_empty_class (current_class_type) > /* We can't clobber safely for an implicitly-defined default constructor > because part of the initialization might happen before we enter the > constructor, via AGGR_INIT_ZERO_FIRST (c++/68006). */ > && !implicit_default_ctor_p (decl1)) > finish_expr_stmt (build_clobber_this ()); > case. Advantage of doing it in the ctor is that if it isn't inlined, it is > done just once per type, doesn't need to be duplicated in all the spots that > use it. > Of course, if the above conditions aren't met, then it still needs to be > initialized somewhere else like where it is done currently, or for the case of > vars with constructors for which we don't emit it perhaps do > __builtin_clear_padding after the constructor (but can we be sure that the > ctor > hasn't e.g. performed placement new and built in itself some other class?). > > Anyway, doing __builtin_clear_padding at RTL expansion time might be > non-trivial. One thing we still haven't decided on what to do with the > virtual > inheritance, whether we need a langhook which won't be there at expansion > time, > or if we can just use binfo (but doesn't free_lang_data mess up with binfo > too)? > And right now the code has two main possibilities, either emit gimple code to > do the clearing, or set a padding bitmask in memory. For RTL, either one > could > use the latter and turn that into RTL code clearing, or we would need a third > mode in which it would be emitting RTL directly. Emitting such code early has > the advantage of store-merging and all kinds of other optimizations though... There's also the option to do .DEFERRED_INIT expansion on GIMPLE somewhere, maybe in ISEL. But sure, if padding clearing needs a langhook that's a no-go. BINFOs are preserved to the extent needed for devirtualization. I suppose the mask could also be precomputed and stuck into the .DEFERRED_INIT call itself somehow ... (encoded into some sequence of variable number of args? <offset>, <mask>, <offset>, <mask>, 0)