This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH 0/2] Proof-of-concept towards removal of the "cfun" global
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: David Malcolm <dmalcolm at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Mon, 27 May 2013 15:29:21 +0200
- Subject: Re: [PATCH 0/2] Proof-of-concept towards removal of the "cfun" global
- References: <1369486941-21480-1-git-send-email-dmalcolm at redhat dot com> <20130525193319 dot GF1512 at atrey dot karlin dot mff dot cuni dot cz>
On Sat, May 25, 2013 at 9:33 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> Here's an idea that could make it easier to remove the "cfun" global.
>>
>> "cfun" is a major piece of global state within gcc: it's the 5th most
>> accessed variable in the build (accessed in ~4600 places within one stage
>> of a build, based on [1]). This is an obstacle to making gcc's code be
>> usable as a library.
>
> Yep, note that cfun is not the only beast of this. For 99% of backend it needs
> to be kept in sync with current_function_decl pointing to the declaration such
> that DECL_STRUCT_FUNCTION (current_function_decl) = cfun.
> There is also implicit notion of "current cgraph node" that is accessed by
> cgraph_get_node (current_function_decl) many times that can get expensive
> since it leads to hashtable lookup.
> Finally there is "crtl" that is macro hidding a global variable x_rtl
> data for RTL data of the currently compiled function.
>
> In many ways these four are all closely related and data in between them
> are not distributed in very engineered way.
Note that ideally there exists a single global variable per compilation phase.
Frontends would use current_function_decl (as struct function is not available
very early) while the middle-end and target would use cfun.
Through cfun you can reach its decl and you should ideally be able to reach
the cgraph node, too.
>> I can think of three approaches to "cfun":
>> (a) status quo: a global variable, with macros to prevent direct
>> assignment, and an API for changing cfun.
>
> We have push_cfun/pop_cfun for that. If you did not look into what they
> really do, you may be disappointed. They are huge&expensive beasts switching
> a lot of global state in compiler for optimize attribute. So it means that
> on the track removing them we will need to cleanup this area, too.
Yeah ...
>> (b) have a global "context" or "universe" object, and put cfun in
>> there (perhaps with tricks to be able to make this a singleton in a
>> non-library build, optimizing away the context lookups somehow
>> - see [2] for discussion on this)
>> (c) go through all of the places where cfun is used, and somehow ensure
>> that they're passed in the data they need. Often it's not the
>> function that's used, but its cfg.
>>
>> I think (c) is the ideal from a modularity perspective (it unlocks the
>> ability to have optimization passes be working on different functions in
>> different threads), but the most difficult.
>
> (c) is direction I was trying to push IPA code to in longer run. We need
> a single object holding "function" and that should be passed to most
> of the macros.
>
> I am not entirely happy with contents of the "struct function" at all
> (it is kind of kitchen sink for all the data we randomly need to associate
> with function), but it is closest to it. Most of IPA node considers the
> ultimate function pointer to be the cgraph node however.
>
> We do not want to melt those all thogether, since the data in there have different
> lifetime. In particular struct_function is not in memory during WPA.
I agree to all of the above.
It would be interesting to have a static analyzer compute what are the most
executed functions that ultimately end up referencing cfun ...
>>
>> One part of the puzzle is that various header files in the build define
>> macros that reference the "cfun" global, e.g.:
>>
>> #define n_basic_blocks (cfun->cfg->x_n_basic_blocks)
>>
>> This one isn't in block caps, which might mislead a new contributor into
>> thinking it's a variable, rather than a macro, so there may be virtue in
>
> Yep yo umany notice there are already _FN variants for that. The macors
> are lower case since historically they were variables. I agree they should
> be replaced.
Yes, explicit "cfun" usage is way better than implicit one - especially because
we still have implicit uses in functions that are already being passed the
function context as parameter ...
>> removing these macros for that reason alone. (I know that these confused
>> me for a while when I first started writing my plugin) [3]
>>
>> So I had a go at removing these macros, to make usage of "cfun" be
>> explicit.
>>
>> I wrote a script to do most of the gruntwork automatically: [4]
>>
>> The following patches introduce accessor methods to control_flow_graph,
>> then remove all of the macros that reference cfun from basic-block.h,
>> replacing all of the places that use them with explicit uses of
>> "cfun->cfg->get_foo ()" as appropriate. There are various other headers
>> that define macros that use cfun, but I thought I'd post this to get a
>> sense of how maintainers feel about this approach.
>>
>> I notice that we're constantly accessing:
>>
>> some loop
>> {
>> ...
>> use cfun->cfg->x_some_field;
>> ...
>> }
>>
>> Would it potentially be faster to replace some of these with:
>>
>> control_flow_graph &cfg = *cfun->cfg;
>> some loop
>> {
>> ...
>> use cfg.get_some_field () // assuming inlining of accessor
>> ...
>> }
>>
>> to avoid constantly derefing cfun->cfg?
I think that was one reason crtl was introduced ... to avoid an indirection
through cfun.
>> (That said, would
>> -fstrict-aliasing
>> be able to note that cfun->cfg doesn't change, or in a non-LTO build I'm
>> guessing it can't make that assumption if the loop calls into functions it
>> can't see inside?).
>
> I like the general direction (i.e. it is what I was hoping for to happen for
> years, but was too lazy to enforce it more curefully).
> We should have single "function" object that is passed around and it should
> have substructures or pointers to all the various stuff we hold about function
> globally (gimple body, cfg, loop tree, profile, IPA data).
>
> Just some random toughts. I epxect there will be more discussion ;)
I indeed welcome the effort to make all 'cfun' uses explicit. Even more welcome
is reducing the number of 'cfun' references ;) Like giving all gimple/rtl pass
execute () / gate () functions a struct function argument (or even
better abstract
that so we can add more context transparently later, like dump_file /
dump_flags).
Richard.
> Honza