Fix removal of ctors/dtors

H.J. Lu hjl.tools@gmail.com
Fri Dec 31 17:06:00 GMT 2010


On Sat, Nov 13, 2010 at 3:31 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Nov 8, 2010 at 11:03 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Tue, Oct 26, 2010 at 7:16 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>>> Hi,
>>> while implementing code removing pure & const constructors I considered correct option of
>>> dropping CONSTRUCTOR/DESTRUCTOR flag for functions found to be const or pure or slightly hacky
>>> of simply teaching dead function removal to consider them dead.  The second is suboptimal
>>> for static constructors & destructors that are also called dirrectly.  I concluded that no one
>>> does that, but Zdenek did and it triggers one overparanoid sanity check.
>>>
>>> So this patch takes the cleaner route of just dropping the flags and letting
>>> unreachable code removal to remove the functions later.  This happens in
>>> visibility pass where we sanitize flags for pure/const constructors comming
>>> from forntends or via cgraph_set_pure_flag/cgraph_set_const_flags when they are
>>> discovered pure/const later.
>>>
>>> While working on it I also noticed that we don't handle correctly extern
>>> declarations (we consider them extern inlines and keep them in the cgraph.
>>> This is wasteful especially for LTO) and extern inlines (we keep them in the
>>> program even if they are obviously dead - they are never called nor have address
>>> taken up to the IPA inliner). Cleaning this issue shown that both inliner and
>>> ipa-cp compute code size costs incorrectly by assuming that optimizing out
>>> external copy of extern function it will save code size.
>>>
>>> Finally both inliner and ipa-cp confuse handling of functions with address
>>> taken.  ipa-cp is considering functions with address taken to be cloning candidates.
>>> This is wrong.  We should clone only when we think original function is not called at all
>>> but we can't say for sure since it is externally visible.  Clonning is of course possible,
>>> but current impementation leads to wrong code when updating call sites of calls promoted to
>>> be direct.
>>>
>>> Inliner on the other hand produce invalid callgraph with inline clones having
>>> address taken.
>>>
>>> Bootstrapped/regtested x86_64-linux, lto-bootstrapped x86_64-linux and tested
>>> with Firefox builds.   I also tested that tramp3d does not care about the
>>> inliner mertric fixes.
>>>
>>> Honza
>>>
>>>        * cgraph.c (cgraph_set_readonly_flag): Rename to...
>>>        (cgraph_set_const_flags) ... this one; get also looping argument;
>>>        clear constructor/destructor flags.
>>>        (cgraph_set_pure_flag): Likewise.
>>>        (cgraph_set_looping_const_or_pure_flag): Remove.
>>>        (cgraph_can_remove_if_no_direct_calls_and_refs): Do not try
>>>        to optimize away static ctors/dtors; it does not work on inline clones;
>>>        external functions can always be rmeoved.
>>>        (cgraph_will_be_removed_from_program_if_no_direct_calls): Assert on inline
>>>        clones; in LTO external functions always can go.
>>>        (cgraph_used_from_object_file_p): Handle EXTERNAL functions correctly.
>>>        (cgraph_mark_address_taken_node): Assert that we are not taking address of
>>>        inline clone.
>>>        (cgraph_can_remove_if_no_direct_calls_p): We always eventually remove
>>>        external functions.
>>>        * ipa-cp.c (ipcp_cloning_candidate_p): Do not clone functions with address taken.
>>>        (ipcp_initialize_node_lattices): Only local functions can be handled without cloning.
>>>        * cgraph.h (cgraph_set_readonly_flag,
>>>        cgraph_set_looping_const_or_pure_flag): Remove.
>>>        (cgraph_set_const_flag): Declare.
>>>        (cgraph_set_pure_flag): Update.
>>>        * ipa-pure-const (propagate_pure_const, local_pure_const): Update
>>>        flags setting code.
>>>        * ipa.c (cgraph_remove_unreachable_nodes): Fix formating; do not look at inline
>>>        clones; fix handling of external definitions.
>>>        (cgraph_postorder): Do not look at inline clones in the first pass.
>>>        (function_and_variable_visibility): Drop constructors/destructor
>>>        flags at pure and const functions.
>>>        * tree-profile.c (tree_profiling): Update.
>>>        * ipa-inline.c (cgraph_clone_inlined_nodes): Always clone functions with
>>>        address taken; external functions do not account to whole program size.
>>>        (cgraph_decide_inlining): Likewise; do not try to inline functions already
>>>        inlined.
>>>
>>>        * testsuite/gcc.dg/lto/pr45736_0.c: New function.
>>
>> This patch caused:
>>
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46367
>>
>
> This also caused:
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46469
>

This also caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47009

-- 
H.J.



More information about the Gcc-patches mailing list