gcc: remove unneeded global related to hot/cold partitioning
authorAndrew Burgess <andrew.burgess@embecosm.com>
Wed, 16 Nov 2016 22:10:52 +0000 (22:10 +0000)
committerAndrew Burgess <aburgess@gcc.gnu.org>
Wed, 16 Nov 2016 22:10:52 +0000 (22:10 +0000)
commita2ea37fb4c8084421784c80bfd1a4e065980314c
tree65afad1bdb61bac43a43cff8caf2ad6b9ce66633
parentd174eb6541dc457ada0297dfbbb904cc563b5437
gcc: remove unneeded global related to hot/cold partitioning

The `user_defined_section_attribute' is used as part of the condition to
determine if GCC should partition blocks within a function into hot and
cold blocks.  This global is initially false, and is set to true from
within the file parse phase of GCC, as part of the attribute handling
hook.

The `user_defined_section_attribute' is reset to false as part of the
final pass of GCC.  However, the final pass is part of the optimisation
phase of the compiler, and so if at any point during the file parse
phase any function, or data, has a section attribute the global
`user_defined_section_attribute' will be set to true.

When GCC performs the block partitioning pass on the first function, if
`user_defined_section_attribute' is true then the function will not be
partitioned.  Notice though, that due to the above, whether we partition
this first function or not has nothing to do with whether the function
has a section attribute, instead, if any function or data in the parsed
file has a section attribute then we don't partition the first
function.

After performing (or not) the block partitioning pass on the first
function we perform the final pass on the first function, at which point
we reset `user_defined_section_attribute' to false.  As parsing is
complete by this point, we will never set
`user_defined_section_attribute' to true after that, and so all of the
following functions will have the partition blocks pass performed on
them, even if the function has a section attribute, and will not be
partitioned.

Luckily we don't end up partitioning functions that should not be
partitioned though.  Due to the way that functions are selected during
the assembler writing phase, if a function has a section attribute this
takes priority over any hot/cold block partitioning that has been done.

What we see from the above then is that the
`user_defined_section_attribute' mechanism is broken.  It was originally
created when GCC parsed, optimised, and generated assembler function at
a time.  Now that we deal with the whole file in one go, we need to
update the mechanism used to gate the block partitioning pass.

This patch does this by looking specifically for a section attribute on
the function DECL, which removes the need for a global variable, and
will work whether we parse the whole file in one go, or one function at
a time.

A few new tests have been added.  These check for the case where a
function is not partitioned when it could be.

gcc/ChangeLog:

* gcc/bb-reorder.c: Remove 'toplev.h' include.
(pass_partition_blocks::gate): No longer check
user_defined_section_attribute, instead check the function decl
for a section attribute.
* gcc/c-family/c-attribs.c (handle_section_attribute): No longer
set user_defined_section_attribute.
* gcc/final.c (rest_of_handle_final): Likewise.
* gcc/toplev.c: Remove definition of user_defined_section_attribute.
* gcc/toplev.h: Remove declaration of
user_defined_section_attribute.

gcc/testsuiteChangeLog:

* gcc.dg/tree-prof/section-attr-1.c: New file.
* gcc.dg/tree-prof/section-attr-2.c: New file.
* gcc.dg/tree-prof/section-attr-3.c: New file.

From-SVN: r242519
gcc/ChangeLog
gcc/bb-reorder.c
gcc/c-family/c-attribs.c
gcc/final.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c [new file with mode: 0644]
gcc/toplev.c
gcc/toplev.h