Message ID | 20160914130048.GC31794@embecosm.com |
---|---|
State | New |
Headers | show |
On Wed, Sep 14, 2016 at 02:00:48PM +0100, Andrew Burgess wrote: > In an attempt to get this patch merged (as I still think that its > correct) I've investigated, and documented a little more about how I > think things currently work. I'm sure most people reading this will > already know this, but hopefully, if my understanding is wrong someone > can point it out. I wonder if user_defined_section_attribute instead shouldn't be moved into struct function and be handled as a per-function flag then. Jakub
* Jakub Jelinek <jakub@redhat.com> [2016-09-14 15:07:56 +0200]: > On Wed, Sep 14, 2016 at 02:00:48PM +0100, Andrew Burgess wrote: > > In an attempt to get this patch merged (as I still think that its > > correct) I've investigated, and documented a little more about how I > > think things currently work. I'm sure most people reading this will > > already know this, but hopefully, if my understanding is wrong someone > > can point it out. > > I wonder if user_defined_section_attribute instead shouldn't be moved > into struct function and be handled as a per-function flag then. That would certainly solve the problem I'm trying to address. But I wonder, how is that different to looking for a section attribute on the function DECL? Thanks, Andrew
On 09/15/2016 08:24 AM, Andrew Burgess wrote: > * Jakub Jelinek <jakub@redhat.com> [2016-09-14 15:07:56 +0200]: > >> On Wed, Sep 14, 2016 at 02:00:48PM +0100, Andrew Burgess wrote: >>> In an attempt to get this patch merged (as I still think that its >>> correct) I've investigated, and documented a little more about how I >>> think things currently work. I'm sure most people reading this will >>> already know this, but hopefully, if my understanding is wrong someone >>> can point it out. >> >> I wonder if user_defined_section_attribute instead shouldn't be moved >> into struct function and be handled as a per-function flag then. > > That would certainly solve the problem I'm trying to address. But I > wonder, how is that different to looking for a section attribute on > the function DECL? I'm not sure it is significantly different. It seems like it's just an implementation detail. I'd err on the side of putting this into the struct function rather than on the DECL node simply to keep the size of DECL nodes from increasing. Even if you can find suitable free flag bits, those can likely be better used for other purposes. I'm still pondering the actual patch. It's not forgotten. jeff
* Jeff Law <law@redhat.com> [2016-10-28 09:58:14 -0600]: > On 09/15/2016 08:24 AM, Andrew Burgess wrote: > > * Jakub Jelinek <jakub@redhat.com> [2016-09-14 15:07:56 +0200]: > > > > > On Wed, Sep 14, 2016 at 02:00:48PM +0100, Andrew Burgess wrote: > > > > In an attempt to get this patch merged (as I still think that its > > > > correct) I've investigated, and documented a little more about how I > > > > think things currently work. I'm sure most people reading this will > > > > already know this, but hopefully, if my understanding is wrong someone > > > > can point it out. > > > > > > I wonder if user_defined_section_attribute instead shouldn't be moved > > > into struct function and be handled as a per-function flag then. > > > > That would certainly solve the problem I'm trying to address. But I > > wonder, how is that different to looking for a section attribute on > > the function DECL? > I'm not sure it is significantly different. It seems like it's just an > implementation detail. I'd err on the side of putting this into the struct > function rather than on the DECL node simply to keep the size of DECL nodes > from increasing. Even if you can find suitable free flag bits, those can > likely be better used for other purposes. I didn't add anything to the DECL, the information we need is already there. The relevant chunk of the patch is: @@ -2890,7 +2889,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 I have not made any changes to add anything new to the DECL. I guess an argument _could_ be made that looking up an attribute is too expensive to be used in a pass::gate function (I haven't looked into how expensive it is) but I figured that initially at least it's better to reuse the data we already have around than to add a new flag that duplicates something we already have. > I'm still pondering the actual patch. It's not forgotten. Would it help clarify things if I added some printf style tracing and posted a trace? This might help highlight how USER_DEFINED_SECTION_ATTRIBUTE is set in a different phase of compilation and so can't possibly be of any use when deciding whether or not to perform the pass or not. I'm still keen to see this merged, so any extra leg work I can do to help move this forward, please let me know; I'm happy to help. Thanks, Andrew
On 09/14/2016 03:00 PM, Andrew Burgess wrote: > In an attempt to get this patch merged (as I still think that its > correct) I've investigated, and documented a little more about how I > think things currently work. I'm sure most people reading this will > already know this, but hopefully, if my understanding is wrong someone > can point it out. > 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-common.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. I think the explanation is perfectly reasonable and the patch looks good, except: > +__attribute__((noinline)) Add noclone to all of these as well. Bernd
* Bernd Schmidt <bschmidt@redhat.com> [2016-11-03 13:01:32 +0100]: > On 09/14/2016 03:00 PM, Andrew Burgess wrote: > > In an attempt to get this patch merged (as I still think that its > > correct) I've investigated, and documented a little more about how I > > think things currently work. I'm sure most people reading this will > > already know this, but hopefully, if my understanding is wrong someone > > can point it out. > > 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-common.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. > > I think the explanation is perfectly reasonable and the patch looks good, > except: > > > +__attribute__((noinline)) > > Add noclone to all of these as well. Thanks. Considering Jeff said, I'm thinking about it, and you've said yes, and given Jeff's not got back, I'm considering this patch approved (with the fix you suggest). My only remaining concern is the new tests, I've tried to restrict them to targets that I suspect they'll pass on with: /* { dg-final-use { scan-assembler "\.section\[\t \]*\.text\.unlikely\[\\n\\r\]+\[\t \]*\.size\[\t \]*foo\.cold\.0" { target *-*-linux* *-*-gnu* } } } */ but I'm still nervous that I'm going to introduce test failures. Is there any advice / guidance I should follow before I commit, or are folk pretty relaxed so long as I've made a reasonable effort? Thanks, Andrew
On Nov 16, 2016, at 12:09 PM, Andrew Burgess <andrew.burgess@embecosm.com> wrote: > My only remaining concern is the new tests, I've tried to restrict > them to targets that I suspect they'll pass on with: > > /* { dg-final-use { scan-assembler "\.section\[\t \]*\.text\.unlikely\[\\n\\r\]+\[\t \]*\.size\[\t \]*foo\.cold\.0" { target *-*-linux* *-*-gnu* } } } */ > > but I'm still nervous that I'm going to introduce test failures. Is > there any advice / guidance I should follow before I commit, or are > folk pretty relaxed so long as I've made a reasonable effort? So, if you are worried about the way the line is constructed, I usually test it by misspelling the *-*-linux* *-*-gnu* part as *-*-linNOTux* *-*-gnNOTu* and see if the test then doesn't run on your machine. If it doesn't then you can be pretty confident that only machines that match the target triplet can be impacted. I usually do this type of testing by running the test case in isolation (not the full tests suite). Anyway, do the best you can, and don't worry about t it too much, learn from the experience, even if it goes wrong in some way. If it did go wrong, just be responsive (don't check it in just before a 6 week vacation) about fixing it, if you can.
* Mike Stump <mikestump@comcast.net> [2016-11-16 12:59:53 -0800]: > On Nov 16, 2016, at 12:09 PM, Andrew Burgess <andrew.burgess@embecosm.com> wrote: > > My only remaining concern is the new tests, I've tried to restrict > > them to targets that I suspect they'll pass on with: > > > > /* { dg-final-use { scan-assembler "\.section\[\t \]*\.text\.unlikely\[\\n\\r\]+\[\t \]*\.size\[\t \]*foo\.cold\.0" { target *-*-linux* *-*-gnu* } } } */ > > > > but I'm still nervous that I'm going to introduce test failures. Is > > there any advice / guidance I should follow before I commit, or are > > folk pretty relaxed so long as I've made a reasonable effort? > > So, if you are worried about the way the line is constructed, I usually test it by misspelling the *-*-linux* *-*-gnu* part as *-*-linNOTux* *-*-gnNOTu* and see if the test then doesn't run on your machine. If it doesn't then you can be pretty confident that only machines that match the target triplet can be impacted. I usually do this type of testing by running the test case in isolation (not the full tests suite). Anyway, do the best you can, and don't worry about t it too much, learn from the experience, even if it goes wrong in some way. If it did go wrong, just be responsive (don't check it in just before a 6 week vacation) about fixing it, if you can. > Thanks for the feedback. Change committed as revision 242519. If anyone sees any issues just let me know. Thanks, Andrew
On 11/16/2016 03:12 PM, Andrew Burgess wrote: > * Mike Stump <mikestump@comcast.net> [2016-11-16 12:59:53 -0800]: > >> On Nov 16, 2016, at 12:09 PM, Andrew Burgess <andrew.burgess@embecosm.com> wrote: >>> My only remaining concern is the new tests, I've tried to restrict >>> them to targets that I suspect they'll pass on with: >>> >>> /* { dg-final-use { scan-assembler "\.section\[\t \]*\.text\.unlikely\[\\n\\r\]+\[\t \]*\.size\[\t \]*foo\.cold\.0" { target *-*-linux* *-*-gnu* } } } */ >>> >>> but I'm still nervous that I'm going to introduce test failures. Is >>> there any advice / guidance I should follow before I commit, or are >>> folk pretty relaxed so long as I've made a reasonable effort? >> >> So, if you are worried about the way the line is constructed, I usually test it by misspelling the *-*-linux* *-*-gnu* part as *-*-linNOTux* *-*-gnNOTu* and see if the test then doesn't run on your machine. If it doesn't then you can be pretty confident that only machines that match the target triplet can be impacted. I usually do this type of testing by running the test case in isolation (not the full tests suite). Anyway, do the best you can, and don't worry about t it too much, learn from the experience, even if it goes wrong in some way. If it did go wrong, just be responsive (don't check it in just before a 6 week vacation) about fixing it, if you can. >> > > Thanks for the feedback. > > Change committed as revision 242519. If anyone sees any issues just > let me know. Thanks. And thanks for seeing this through... I know it's a pain sometimes. jeff
On 16 November 2016 at 23:12, Andrew Burgess <andrew.burgess@embecosm.com> wrote: > * Mike Stump <mikestump@comcast.net> [2016-11-16 12:59:53 -0800]: > >> On Nov 16, 2016, at 12:09 PM, Andrew Burgess <andrew.burgess@embecosm.com> wrote: >> > My only remaining concern is the new tests, I've tried to restrict >> > them to targets that I suspect they'll pass on with: >> > >> > /* { dg-final-use { scan-assembler "\.section\[\t \]*\.text\.unlikely\[\\n\\r\]+\[\t \]*\.size\[\t \]*foo\.cold\.0" { target *-*-linux* *-*-gnu* } } } */ >> > >> > but I'm still nervous that I'm going to introduce test failures. Is >> > there any advice / guidance I should follow before I commit, or are >> > folk pretty relaxed so long as I've made a reasonable effort? >> >> So, if you are worried about the way the line is constructed, I usually test it by misspelling the *-*-linux* *-*-gnu* part as *-*-linNOTux* *-*-gnNOTu* and see if the test then doesn't run on your machine. If it doesn't then you can be pretty confident that only machines that match the target triplet can be impacted. I usually do this type of testing by running the test case in isolation (not the full tests suite). Anyway, do the best you can, and don't worry about t it too much, learn from the experience, even if it goes wrong in some way. If it did go wrong, just be responsive (don't check it in just before a 6 week vacation) about fixing it, if you can. >> > > Thanks for the feedback. > > Change committed as revision 242519. If anyone sees any issues just > let me know. > Hi Andrew, Sorry for the delay, there are so many commits these days, with so many regression reports to check manually before reporting here.... So, your new test fails on arm* targets: gcc.dg/tree-prof/section-attr-1.c scan-assembler .section[\t ]*.text.unlikely[\\n\\r]+[\t ]*.size[\t ]*foo.cold.0 gcc.dg/tree-prof/section-attr-2.c scan-assembler .section[\t ]*.text.unlikely[\\n\\r]+[\t ]*.size[\t ]*foo.cold.0 gcc.dg/tree-prof/section-attr-3.c scan-assembler .section[\t ]*.text.unlikely[\\n\\r]+[\t ]*.size[\t ]*foo.cold.0 Christophe > Thanks, > Andrew
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index bb8435f..0a482e6 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -106,7 +106,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" @@ -2890,7 +2889,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-common.c b/gcc/c-family/c-common.c index 1132a03..2d7107d 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -7751,8 +7751,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 eccc3d8..b407b85 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -4478,8 +4478,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/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..51e38cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c @@ -0,0 +1,43 @@ +/* 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 + +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; +} + +__attribute__((noinline)) +void +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..cbfa5fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c @@ -0,0 +1,43 @@ +/* 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 + +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; +} + +__attribute__((noinline)) +void +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..593a94a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c @@ -0,0 +1,43 @@ +/* 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 + +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; +} + +__attribute__((noinline)) +void +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 66099ec..113fc7f 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -149,11 +149,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;