This is an archive of the discontinued LLVM Phabricator instance.

Add the -fdestroy-globals flag
Needs ReviewPublic

Authored by itessier on Jul 12 2017, 5:07 PM.

Details

Reviewers
rsmith
Summary

The -fdestroy-globals flag can be used to disable global variable destructor
registration. It is intended to be used with embedded code that never exits.
Disabling registration allows the linker to garbage collect unused destructors
and vtables.

Diff Detail

Event Timeline

itessier created this revision.Jul 12 2017, 5:07 PM
vsk added a subscriber: vsk.Jul 13 2017, 7:19 PM

This is interesting. Do you have any results/metrics to share (e.g some any binary size reduction for projects you've looked at)?

lib/Frontend/CompilerInvocation.cpp
585

I think this will do the wrong thing when passed: -cc1 -fno-destroy-globals -fdestroy-globals. Using hasFlag here should fix the issue. I'm just noting this as a FYI, there's no need to update the diff right away, since I'd first like to find out if there are any correctness concerns / what the use cases for this functionality are.

In D35338#809146, @vsk wrote:

This is interesting. Do you have any results/metrics to share (e.g some any binary size reduction for projects you've looked at)?

I only tested this with Project Loon's avionics firmware which freed up ~1.2% of ROM space. A small amount, but for us every bit counts.

I did look at creating a templated wrapper class instead which uses placement-new to construct the wrapped type in a private char buffer. This results in the same effect as this patch (no dtor references are emitted). The only issue is the code is a big uglier to read, and we might forgot to use the wrapper (though a static checker could be added for this case). I figured it'd be best to add compiler support so other C++ based firmware projects can benefit as well.

Thanks for working on this!

One small drive-by nit for you. Same "no need to update the diff this very second" as vsk; I can't LGTM this with confidence.

(Also, in the future, please try to include context with your patch. Doing so makes reviewing it on Phab much easier. :) )

include/clang/Frontend/CodeGenOptions.def
47

Nit: Please align the /// with the above/below ones.

vsk added a subscriber: bruno.Jul 19 2017, 3:02 PM

That seems like a nice win and I like the convenience of this approach. That said I've just remembered that there's a thread on cfe-dev about this:
[RFC] Suppress C++ static destructor registration

I don't think a consensus was reached. From what I gather, some people think that the convenience of this flag makes it worth adding to clang, while others think that adding a non-standard compiler-specific flag is asking for trouble.

I suspect that we'll need more consensus to get this in tree. See Richard's comment:
"If someone's prepared to write up a paper for the C++ committee exploring what it would mean to standardize this behaviour and actually fix the problem for everyone, it would seem extremely reasonable for clang trunk to carry a flag to enable that behaviour (and it certainly doesn't have to wait for the committee to respond)."

That seems like a nice win and I like the convenience of this approach. That said I've just remembered that there's a thread on cfe-dev about this:
[RFC] Suppress C++ static destructor registration
I don't think a consensus was reached. From what I gather, some people think that the convenience of this flag makes it worth adding to clang, while others think that adding a non-standard compiler-specific flag is asking for trouble.

Given that firmware is a much different (or controlled) environment than a binary running on a full blown OS, would it be acceptable to name the flag -fbaremetal-destroy-globals, and only allow its use if the target triple's OS is set to none (e.g.: arm-none-eabi)?