Nathan, I just noticed this path. This is a good improvement over the
existing scheme.

I see one potential problem with the patch -- different instances of
the same comdat function can potentially have different control flows
(due to differences in early inline, early optimizations in different
module contexts)  before profile counter allocation -- which means
making the profile counters 'comdat' can later cause coverage mismatch
problems during profile-use phase.

In this patch, fn data buffer is introduced. What is that for and how
does it work?

thanks,

David

On Wed, Nov 2, 2011 at 1:18 PM, Nathan Sidwell <nat...@acm.org> wrote:
> This patch modifies the coverage scheme so that it works better with comdat
> sections.  The existing scheme uses a single file-scope array for counters,
> with each function using a chunk of that array.  If the function is comdat,
> it's possible that that instance will be omitted from the link, in
> preference to one from another object file.  The chunk of the counter array
> will remain and remain as zero counts.  When processed by gcov, that
> instance of the function will appear unexecuted, which is misleading,
> because it's not present at all in the final executable.  For C, this
> affects unlined inline functions, for C++ it also affects template
> instantiations.
>
> This patch changes things so that counters are allocated as per-function
> arrays with the same comdatedness as the function being instrumented.  Thus
> the array will be discarded, if the function itself is.  Each function's
> function-descriptor now also points to the counter array, in addition to
> specifying the number of counters instrumented (plus the existing
> checksums). This object too has the same comdatedness (& visibility) as the
> function.  The name of this object is derived from the name of the function,
> via a mangling scheme.
>
> In the existing scheme, there's a global file-scope object-descriptor that
> (a) points to the global counter array, and (b) has a trailing array of
> function-descriptors.  The patch changes things so that there's no pointer
> to the now-deleted global counter array, and the trailing array is now an
> array of pointers to function-descriptors.  In the absence of comdat, we can
> now generate the same gcov data file as before, but with an additional layer
> of indirection.
>
> However, with comdat functions the function-descriptor selected for a
> particular function may come from a different object file.  It'll be pointed
> to by the object-descriptor's trailing array.  When iterating over this
> array we do not want to emit data for the instance of the function being
> pointed to, and so need some way of detecting a foreign function descriptor.
>  We do this by adding a key field to the function descriptor.  It is
> initialized to point to the (static) object-descriptor.  Thus foreign
> function-descriptors will have a key that does not point to the
> object-descriptor being iterated over.
>
> The above description only discusses the block counters.  The coverage
> system instruments more than that, and each distinct counter type is
> modified in the same way.  One significant change is that the merge function
> pointers are no longer per-function-descriptor, but are in the
> object-descriptor and a NULL value there indicates a skipped counter.
>
> For the data-file itself, the per-object summary data is deleted, as it no
> longer makes much sense.  The number of instrumented functions from an
> object file can vary, depending on which comdat functions are selected from
> it in the final links it participates in.  For convenience the program
> summaries are now placed before the per-function data.  Also, because an
> object can be in multiple executables (or shared objects), we need to keep
> track of functions that were emitted in the object file but not in the final
> link.  Thus we now have place-holder function data slots, and have the
> ability to buffer file data for a function that was instrumented in some
> other executable but not in the current one -- I couldn't figure out a sane
> way to deal this other than using malloc.  I have not removed gcov-dump
> support for the per-object summary, to allow use with older data files.  But
> remember the gcov file format is explicitly tied to the version of the
> compiler used to generate it -- it is not supposed to be version neutral.
>
> As mentioned above, there is an ABI impact, because the function-descriptors
> of externally visible functions must also be externally visible.  These are
> named '__gcov__FUNCTION', where 'FUNCTION' is the (possibly mangled) name of
> the function being described.  The per-function counter arrays are not
> externally visible, so their mangling only needs to guarantee uniqueness in
> the object file.  These are mangled as '__gcovN_FUNCTION', where 'N' is the
> counter number.
>
> There are a couple of other changes, due to existing shortfalls exposed by
> this work.  Firstly, for an inline function that is inlined everywhere, we
> (currently) generate a block of counters in the global array.  We never emit
> the non-inlined body of function, so these ended up as unused parts of the
> global array.  When emitting the object-descriptor, we elide functions whose
> DECL_STRUCT_FUNCTION has been cleared.  The impact of this in reading the
> count data file is that we no longer emit a diagnostic for functions that
> are not described in the data file -- we don't know at this point whether
> the function being optimized will actually be emitted.
>
> Tested by normal and profiled bootstrap on i686-pc-linux-gnu for all
> languages.
>
> I'll apply this patch shortly, unless there are questions or comments.
>
> nathan

Reply via email to