Inlined code

Chris Johns chrisj at rtems.org
Mon Aug 6 00:51:21 UTC 2018


On 05/08/2018 19:39, Christian Mauderer wrote:
> Am 05.08.2018 um 04:00 schrieb Chris Johns:
>> Hi,
>>
>> I have been working on migrating covoar in the rtems-tools repo to DWARF. The
>> goal is remove objdump parsing and to get accurate details about the functions
>> being covered. This is an unfunded task.
>>
>> The work has resulted in a close examination of inlined code in RTEMS and what I
>> saw alarmed me so I have added a report to the rtems-exeinfo tool in rtems-tools
>> (the change is to be posted for review once I get the coverage tests running).
>>
>> A summary report for hello.exe on RTEMS 5 for SPARC is:
>>
>> inlined funcs   : 1412
>>     total funcs : 1956
>>  % inline funcs : 72%
>>      total size : 174616
>>     inline size : 81668
>>   % inline size : 46%
>>
>> This is a small application so it could be argued that skews the figures. A
>> large C/C++ application built with -O2 running on RTEMS 4.11 ARM reports the
>> inline usage as:
>>
>> inlined funcs   : 10370
>>     total funcs : 17700
>>  % inline funcs : 58%
>>      total size : 3066240
>>     inline size : 1249514
>>   % inline size : 40%
>>
>> This does not seem right to me.
>>
>> The report is new and there could be issues in the DWARF handling that feeds
>> this report however I am posting this to start a discussion on the topic of
>> inlining.
>>
>> I attach the report for hello.exe. The `-i` option generates the inline report.
>>
>> The first section is a summary showing the total number of functions in the
>> executable that have machine code and are flagged as inline. The report lists
>> the percentage of functions that are inlined and the percentage of machine code
>> that is inlined. The values seem high to me.
>>
>> The second table lists inline functions that are repeated sorted from the
>> largest foot print to the smallest. The first column the total size of machine
>> code in the executable and the second column the number of instances.
>>
>> The third table is the list of inline functions sorted from largest machine code
>> footprint to smallest. The second column are flags of which there is one. A `E`
>> indicates the inline function is also external which means the compiler has
>> created an external reference to this function, ie an address-of is being taken.
>> The third column is the address in the executable so you can take a look with
>> objdump at the machine code.
>>
>> We need to ask some important question in relation to inlining. It is cheap to
>> add and we all feel the code we add needs to be fast and needs to be inlined but
>> does it really need to be inlined?
>>
>> Some pieces of code do need to be inlined and the overhead is just that an
>> overhead, for example in the large C/C++ application there is a low level
>> volatile hardware write routing with close to 300 instances and a code size of
>> 10K. This code needs to be inlined for performance reasons but should the size
>> on average be 40 bytes, I doubt it.
>>
>> Can we be more judicious with our use of the inline keyword?
>>
>> Is the performance gain we really expect or is the actual overhead of a call
>> frame not worth saving?
>>
>> What are the real costs of inlining a piece of code? It adds size to the
>> executable and depending on the code being inlined it complicates coverage
>> analysis be adding extra branch points.
>>
>> The metrics to determine what should be inlined is complicated and I do not
>> think we have a suitable policy in place. I believe it is time we to create one.
>>
>> The issue is not limited to our code, gcc, newlib and libstdc++ seem to have
>> some code that should be looked at more closely. For example __udivmoddi4, and
>> __sprint_r.
>>
>> Chris
>>
>>
> 
> Hello Chris,
> 
> I just took a look at one of the first function in your list: __sprint_r
> 
> https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/stdio/vfprintf.c;h=c4bf2dbe31da64462ecccec97c8e901e4ffadd44;hb=HEAD#l403
> 
> As far as I can see, there is no explicit inline key word for that
> function. So in that case, the compiler decided that it would be a good
> idea to inline that function.

Thanks and yes. At this point in time I cannot tell what is happening and I am
not sure the tool is reporting accurate data, I need to investigate.

> I'm not sure whether I might just haven't seen it but is there a
> possibility to distinguish between functions that have been inlined by
> the compiler and ones that have been inlined due to the "inline" keyword
> without looking at every definition?

I am not sure. The DWARF data is complex and detailed and I view this initial
step into the area of using DWARF to perform static analysis of RTEMS
executables as green.

DWARF does provide declaration attributes. I need to review the DWARF data and
standard to determine if we can tell what is declared inline and what has been
inlined. I think it would be good to know.

> Did you try compiling with size optimization? I would expect that the
> compiler would inline far less functions and maybe even ignore some
> "inline" keywords. As far as I know it's more of a hint to the compiler.

Not yet. A complete tool build with those options is a lot of effort and I am
still not comfortable the report is accurate. I think this is something that
should be done at some point. I think it would create an interesting data point.

> I would only worry about functions that are still inlined if size
> optimization is selected. 

I think we need to review the functions we currently have tagged as inline. I
think the only way we can do this is with real data.

> That's the case when I tell the compiler to
> make the program as small as possible. In all other cases I want some
> well balanced optimum between speed and size. Inlining small functions
> is OK in that case if you ask me.

How do you define this, ie what is the inline policy we use?
How do you audit this?

Chris


More information about the devel mailing list