aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2016-11-16 22:10:52 +0000
committerAndrew Burgess <aburgess@gcc.gnu.org>2016-11-16 22:10:52 +0000
commita2ea37fb4c8084421784c80bfd1a4e065980314c (patch)
tree65afad1bdb61bac43a43cff8caf2ad6b9ce66633
parentd174eb6541dc457ada0297dfbbb904cc563b5437 (diff)
downloadgcc-a2ea37fb4c8084421784c80bfd1a4e065980314c.zip
gcc-a2ea37fb4c8084421784c80bfd1a4e065980314c.tar.gz
gcc-a2ea37fb4c8084421784c80bfd1a4e065980314c.tar.bz2
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
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/bb-reorder.c3
-rw-r--r--gcc/c-family/c-attribs.c2
-rw-r--r--gcc/final.c2
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c45
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c44
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c45
-rw-r--r--gcc/toplev.c5
-rw-r--r--gcc/toplev.h5
10 files changed, 154 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9b04621..bd70d4e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2016-11-16 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * 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.
+
2016-11-16 Maciej W. Rozycki <macro@imgtec.com>
* config/mips/mips.md (casesi_internal_mips16_<mode>):
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 85bc569..e51ec08 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -107,7 +107,6 @@
#include "output.h"
#include "expr.h"
#include "params.h"
-#include "toplev.h" /* user_defined_section_attribute */
#include "tree-pass.h"
#include "cfgrtl.h"
#include "cfganal.h"
@@ -2894,7 +2893,7 @@ pass_partition_blocks::gate (function *fun)
we are going to omit the reordering. */
&& optimize_function_for_speed_p (fun)
&& !DECL_COMDAT_GROUP (current_function_decl)
- && !user_defined_section_attribute);
+ && !lookup_attribute ("section", DECL_ATTRIBUTES (fun->decl)));
}
unsigned
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 925f1b2..964efe9 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -1438,8 +1438,6 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,
goto fail;
}
- user_defined_section_attribute = true;
-
if (!VAR_OR_FUNCTION_DECL_P (decl))
{
error ("section attribute not allowed for %q+D", *node);
diff --git a/gcc/final.c b/gcc/final.c
index 5709d0e..d3a53c3 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4484,8 +4484,6 @@ rest_of_handle_final (void)
assemble_end_function (current_function_decl, fnname);
- user_defined_section_attribute = false;
-
/* Free up reg info memory. */
free_reg_info ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3707e7c..8958f86 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-11-16 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * 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.
+
2016-11-16 Maciej W. Rozycki <macro@imgtec.com>
* gcc.target/mips/code-readable-4.c (dg-final): Expect `dla'
diff --git a/gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c b/gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c
new file mode 100644
index 0000000..ee6662e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c
@@ -0,0 +1,45 @@
+/* Checks for a bug where a function with a section attribute would prevent
+ all later functions from being partitioned into hot and cold blocks. */
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -fno-profile-reorder-functions -freorder-blocks-and-partition -save-temps" } */
+
+#define SIZE 10000
+
+#define NOINLINE __attribute__((noinline)) __attribute__ ((noclone))
+
+const char *sarr[SIZE];
+const char *buf_hot;
+const char *buf_cold;
+
+void foo (int path);
+
+__attribute__((section(".text")))
+int
+main (int argc, char *argv[])
+{
+ int i;
+ buf_hot = "hello";
+ buf_cold = "world";
+ for (i = 0; i < 1000000; i++)
+ foo (argc);
+ return 0;
+}
+
+
+void NOINLINE
+foo (int path)
+{
+ int i;
+ if (path)
+ {
+ for (i = 0; i < SIZE; i++)
+ sarr[i] = buf_hot;
+ }
+ else
+ {
+ for (i = 0; i < SIZE; i++)
+ sarr[i] = buf_cold;
+ }
+}
+
+/* { dg-final-use { scan-assembler "\.section\[\t \]*\.text\.unlikely\[\\n\\r\]+\[\t \]*\.size\[\t \]*foo\.cold\.0" { target *-*-linux* *-*-gnu* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c b/gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c
new file mode 100644
index 0000000..898a395
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c
@@ -0,0 +1,44 @@
+/* Checks for a bug where static data with a section attribute within a
+ function would stop the function being partitioned into hot and cold
+ blocks. */
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -fno-profile-reorder-functions -freorder-blocks-and-partition -save-temps" } */
+
+#define SIZE 10000
+
+#define NOINLINE __attribute__((noinline)) __attribute__ ((noclone))
+
+const char *sarr[SIZE];
+const char *buf_hot;
+const char *buf_cold;
+
+void foo (int path);
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ buf_hot = "hello";
+ buf_cold = "world";
+ for (i = 0; i < 1000000; i++)
+ foo (argc);
+ return 0;
+}
+
+void NOINLINE
+foo (int path)
+{
+ static int i __attribute__((section(".data")));
+ if (path)
+ {
+ for (i = 0; i < SIZE; i++)
+ sarr[i] = buf_hot;
+ }
+ else
+ {
+ for (i = 0; i < SIZE; i++)
+ sarr[i] = buf_cold;
+ }
+}
+
+/* { dg-final-use { scan-assembler "\.section\[\t \]*\.text\.unlikely\[\\n\\r\]+\[\t \]*\.size\[\t \]*foo\.cold\.0" { target *-*-linux* *-*-gnu* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c b/gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c
new file mode 100644
index 0000000..36829dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c
@@ -0,0 +1,45 @@
+/* Checks for a bug where static data with a section attribute within a
+ function would stop the function being partitioned into hot and cold
+ blocks. */
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -fno-profile-reorder-functions -freorder-blocks-and-partition -save-temps" } */
+
+#define SIZE 10000
+
+#define NOINLINE __attribute__((noinline)) __attribute__ ((noclone))
+
+const char *sarr[SIZE];
+const char *buf_hot __attribute__ ((section (".data")));
+const char *buf_cold;
+
+void foo (int path);
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ buf_hot = "hello";
+ buf_cold = "world";
+ for (i = 0; i < 1000000; i++)
+ foo (argc);
+ return 0;
+}
+
+
+void NOINLINE
+foo (int path)
+{
+ int i;
+ if (path)
+ {
+ for (i = 0; i < SIZE; i++)
+ sarr[i] = buf_hot;
+ }
+ else
+ {
+ for (i = 0; i < SIZE; i++)
+ sarr[i] = buf_cold;
+ }
+}
+
+/* { dg-final-use { scan-assembler "\.section\[\t \]*\.text\.unlikely\[\\n\\r\]+\[\t \]*\.size\[\t \]*foo\.cold\.0" { target *-*-linux* *-*-gnu* } } } */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 59b84eb..d43234a 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -151,11 +151,6 @@ HOST_WIDE_INT random_seed;
the support provided depends on the backend. */
rtx stack_limit_rtx;
-/* True if the user has tagged the function with the 'section'
- attribute. */
-
-bool user_defined_section_attribute = false;
-
struct target_flag_state default_target_flag_state;
#if SWITCHABLE_TARGET
struct target_flag_state *this_target_flag_state = &default_target_flag_state;
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 06923cf..f62a172 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -74,11 +74,6 @@ extern void target_reinit (void);
/* A unique local time stamp, might be zero if none is available. */
extern unsigned local_tick;
-/* True if the user has tagged the function with the 'section'
- attribute. */
-
-extern bool user_defined_section_attribute;
-
/* See toplev.c. */
extern int flag_rerun_cse_after_global_opts;