Message ID | 1296255975.2625.41.camel@otta |
---|---|
State | New |
Headers | show |
the patch is ok for inclusion in some version. a release manager must approve it for 4.6. Kenny On 01/28/2011 06:06 PM, Peter Bergner wrote: > Tracking down some test suite failures while doing a --with-cpu=power7 build, > I noticed that DCE is no longer eliminating dead calls to const or pure > function calls. This is due to all global registers being added to every > call's use and def chains, even though const functions won't reference them > at all and pure functions won't set them. > > The following patch fixes that and has bootstrapped and regtested with > no regressions. This is a regression since it works in gcc 4.3, but > fails in gcc 4.4, 4.5 and trunk, but I understand it only a performance > issue and not a correctness issue. > > Is that patch OK? If so, do we want this in mainline now or after 4.6 > has branched? > > Peter > > > PR rtl-optimization/47525 > * df-scan.c: Update copyright years. > (df_get_call_refs): Do not mark global registers as DF_REF_REG_USE > and non-clobber DF_REF_REG_DEF for calls to const and pure functions. > > Index: df-scan.c > =================================================================== > --- df-scan.c (revision 169365) > +++ df-scan.c (working copy) > @@ -1,6 +1,6 @@ > /* Scanning of rtl for dataflow analysis. > Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, > - 2008, 2009, 2010 Free Software Foundation, Inc. > + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. > Originally contributed by Michael P. Hayes > (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com) > Major rewrite contributed by Danny Berlin (dberlin@dberlin.org) > @@ -3360,16 +3360,19 @@ df_get_call_refs (struct df_collection_r > NULL, bb, insn_info, DF_REF_REG_USE, > DF_REF_CALL_STACK_USAGE | flags); > > - /* Calls may also reference any of the global registers, > - so they are recorded as used. */ > - for (i = 0; i< FIRST_PSEUDO_REGISTER; i++) > - if (global_regs[i]) > - { > - df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], > - NULL, bb, insn_info, DF_REF_REG_USE, flags); > - df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], > - NULL, bb, insn_info, DF_REF_REG_DEF, flags); > - } > + /* Calls to const functions cannot access any global registers and calls to > + pure functions cannot set them. All other calls may reference any of the > + global registers, so they are recorded as used. */ > + if (!RTL_CONST_CALL_P (insn_info->insn)) > + for (i = 0; i< FIRST_PSEUDO_REGISTER; i++) > + if (global_regs[i]) > + { > + df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], > + NULL, bb, insn_info, DF_REF_REG_USE, flags); > + if (!RTL_PURE_CALL_P (insn_info->insn)) > + df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], > + NULL, bb, insn_info, DF_REF_REG_DEF, flags); > + } > > is_sibling_call = SIBLING_CALL_P (insn_info->insn); > EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, ui, bi) > >
On Sat, Jan 29, 2011 at 00:06, Peter Bergner <bergner@vnet.ibm.com> wrote: > Tracking down some test suite failures while doing a --with-cpu=power7 build, > I noticed that DCE is no longer eliminating dead calls to const or pure > function calls. This is due to all global registers being added to every > call's use and def chains, even though const functions won't reference them > at all and pure functions won't set them. > > The following patch fixes that and has bootstrapped and regtested with > no regressions. This is a regression since it works in gcc 4.3, but > fails in gcc 4.4, 4.5 and trunk, but I understand it only a performance > issue and not a correctness issue. > > Is that patch OK? If so, do we want this in mainline now or after 4.6 > has branched? Since this is a regression, ok for 4.6 but please bootstrap it on an x86 machine too just for the sake of coverage. Paolo
On Sat, Jan 29, 2011 at 11:54 AM, Paolo Bonzini <bonzini@gnu.org> wrote: > On Sat, Jan 29, 2011 at 00:06, Peter Bergner <bergner@vnet.ibm.com> wrote: >> Tracking down some test suite failures while doing a --with-cpu=power7 build, >> I noticed that DCE is no longer eliminating dead calls to const or pure >> function calls. This is due to all global registers being added to every >> call's use and def chains, even though const functions won't reference them >> at all and pure functions won't set them. >> >> The following patch fixes that and has bootstrapped and regtested with >> no regressions. This is a regression since it works in gcc 4.3, but >> fails in gcc 4.4, 4.5 and trunk, but I understand it only a performance >> issue and not a correctness issue. >> >> Is that patch OK? If so, do we want this in mainline now or after 4.6 >> has branched? > > Since this is a regression, ok for 4.6 but please bootstrap it on an > x86 machine too just for the sake of coverage. I don't think the testcase is valid. extern int link_failure (int) __attribute__ ((pure)); extern void no_return (void) __attribute__ ((noreturn,pure)); int main (void) { if (link_failure (0) < 1) no_return (); return 0; } no_return might be implemented as no_return() { while (1);} which means we can't DCE either call. Richard. > Paolo >
On Mon, Jan 31, 2011 at 1:21 PM, Richard Guenther <richard.guenther@gmail.com> wrote: > On Sat, Jan 29, 2011 at 11:54 AM, Paolo Bonzini <bonzini@gnu.org> wrote: >> On Sat, Jan 29, 2011 at 00:06, Peter Bergner <bergner@vnet.ibm.com> wrote: >>> Tracking down some test suite failures while doing a --with-cpu=power7 build, >>> I noticed that DCE is no longer eliminating dead calls to const or pure >>> function calls. This is due to all global registers being added to every >>> call's use and def chains, even though const functions won't reference them >>> at all and pure functions won't set them. >>> >>> The following patch fixes that and has bootstrapped and regtested with >>> no regressions. This is a regression since it works in gcc 4.3, but >>> fails in gcc 4.4, 4.5 and trunk, but I understand it only a performance >>> issue and not a correctness issue. >>> >>> Is that patch OK? If so, do we want this in mainline now or after 4.6 >>> has branched? >> >> Since this is a regression, ok for 4.6 but please bootstrap it on an >> x86 machine too just for the sake of coverage. > > I don't think the testcase is valid. > > extern int link_failure (int) __attribute__ ((pure)); > extern void no_return (void) __attribute__ ((noreturn,pure)); > int > main (void) > { > if (link_failure (0) < 1) > no_return (); > return 0; > } > > no_return might be implemented as > > no_return() { while (1);} > > which means we can't DCE either call. Honza - you added that looping-const-or-pure stuff(?), I think we need to treat pure and const annotated fns as looping (at least for functions also marked noreturn). OTOH, noreturn, pure does not make much sense (it would just mean there's no side-effect apart from not returning). Richard. > Richard. > >> Paolo >> >
On 01/31/2011 07:21 AM, Richard Guenther wrote: > On Sat, Jan 29, 2011 at 11:54 AM, Paolo Bonzini<bonzini@gnu.org> wrote: >> On Sat, Jan 29, 2011 at 00:06, Peter Bergner<bergner@vnet.ibm.com> wrote: >>> Tracking down some test suite failures while doing a --with-cpu=power7 build, >>> I noticed that DCE is no longer eliminating dead calls to const or pure >>> function calls. This is due to all global registers being added to every >>> call's use and def chains, even though const functions won't reference them >>> at all and pure functions won't set them. >>> >>> The following patch fixes that and has bootstrapped and regtested with >>> no regressions. This is a regression since it works in gcc 4.3, but >>> fails in gcc 4.4, 4.5 and trunk, but I understand it only a performance >>> issue and not a correctness issue. >>> >>> Is that patch OK? If so, do we want this in mainline now or after 4.6 >>> has branched? >> Since this is a regression, ok for 4.6 but please bootstrap it on an >> x86 machine too just for the sake of coverage. > I don't think the testcase is valid. > > extern int link_failure (int) __attribute__ ((pure)); > extern void no_return (void) __attribute__ ((noreturn,pure)); > int > main (void) > { > if (link_failure (0)< 1) > no_return (); > return 0; > } > > no_return might be implemented as > > no_return() { while (1);} > > which means we can't DCE either call. > > Richard. > i think that i would argue that such an implementation of no_return should not have been marked as pure. the point of pure is that you can remove them >> Paolo >>
> Honza - you added that looping-const-or-pure stuff(?), I think we need Kenny added them. > to treat pure and const annotated fns as looping (at least for functions > also marked noreturn). OTOH, noreturn, pure does not make much > sense (it would just mean there's no side-effect apart from not returning). Well, "pure" function marked with the attribute is intedned to be removable. looping-const-or-pure is for functions detected internally to have no memory stores but to not be removable because they may not return. We have no "looping-pure" function attribute. @item pure @cindex @code{pure} function attribute Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Never returninging is an sice effect and the the testcase is invalid. Honza > > Richard. > > > Richard. > > > >> Paolo > >> > >
The truth is that this is a language lawyer question and not a question for the optimization people. Because it is the job of optimization people to push the definitions as hard as possible. From my point of view, when someone says pure, they are asking for the function to be removed under the proper conditions. Kenny On 01/31/2011 07:30 AM, Jan Hubicka wrote: >> Honza - you added that looping-const-or-pure stuff(?), I think we need > Kenny added them. > >> to treat pure and const annotated fns as looping (at least for functions >> also marked noreturn). OTOH, noreturn, pure does not make much >> sense (it would just mean there's no side-effect apart from not returning). > Well, "pure" function marked with the attribute is intedned to be removable. > looping-const-or-pure is for functions detected internally to have no memory > stores but to not be removable because they may not return. > We have no "looping-pure" function attribute. > > @item pure > @cindex @code{pure} function attribute > Many functions have no effects except the return value and their > return value depends only on the parameters and/or global variables. > > Never returninging is an sice effect and the the testcase is invalid. > > Honza >> Richard. >> >>> Richard. >>> >>>> Paolo >>>>
> The truth is that this is a language lawyer question and not a question > for the optimization people. Because it is the job of optimization > people to push the definitions as hard as possible. From my point of > view, when someone says pure, they are asking for the function to be > removed under the proper conditions. We seem to be arguing same way here. "pure" function attribute means that function is removable. Internally detected pure flag in adition with looping-const-or-pure flag means function is not removable. What probably went wrong is that originally "pure" functions was implemented by adding memory use and const flag on the call statement (to make RTL memory analysis discover there are no side effects, but the statement reads all memory) and by wrapping call within libcall notes (to make DCE discover that it can remove it). Internally detected pure&looping functions was implemented by only annotating the call statement, but not building the libcall. At that point RTL land never removed non-libcall call. Now when libcalls are gone and if DF based DCE was updated to remove call statements by itself, we need to annotate those statements if they are looping or not. Alternatively, for 4.6, we can also just drop the annotations on looping pure/consts and rely on GIMPLE land to do enough optimization here. (this is probably something we would want to revisit later, since pure flag is useful for scheduling) Honza
> > The truth is that this is a language lawyer question and not a question > > for the optimization people. Because it is the job of optimization > > people to push the definitions as hard as possible. From my point of > > view, when someone says pure, they are asking for the function to be > > removed under the proper conditions. > > We seem to be arguing same way here. "pure" function attribute means that > function is removable. > Internally detected pure flag in adition with looping-const-or-pure flag > means function is not removable. > > What probably went wrong is that originally "pure" functions was implemented by > adding memory use and const flag on the call statement (to make RTL memory > analysis discover there are no side effects, but the statement reads all > memory) and by wrapping call within libcall notes (to make DCE discover that it > can remove it). > > Internally detected pure&looping functions was implemented by only annotating the > call statement, but not building the libcall. At that point RTL land never removed > non-libcall call. > > Now when libcalls are gone and if DF based DCE was updated to remove call > statements by itself, we need to annotate those statements if they are looping > or not. Alternatively, for 4.6, we can also just drop the annotations on Hmm, actually we have RTL_LOOPING_CONST_OR_PURE_CALL_P, so I see no problem. I will try to look into the thread more to figure out what it is all about Honza > looping pure/consts and rely on GIMPLE land to do enough optimization here. > (this is probably something we would want to revisit later, since pure flag > is useful for scheduling) > > Honza
> Hmm, actually we have RTL_LOOPING_CONST_OR_PURE_CALL_P, so I see no problem. > I will try to look into the thread more to figure out what it is all about OK, so I think that Peter's patch is fine. The testcase attached to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47525 is indeed nonsential. I think noreturn flag there is needed only to avoid GIMPLE optimizers to optimize the function away earlier. With lack of unit testing, we might try to come with testcase where GIMPLE optimizers miss the transofrmation for other reason. We might also add sanity checks into c-common.c to warn on such conflicting combinations of attributes, like pure/const & noreturn. Honza > > Honza > > > looping pure/consts and rely on GIMPLE land to do enough optimization here. > > (this is probably something we would want to revisit later, since pure flag > > is useful for scheduling) > > > > Honza
On Mon, Jan 31, 2011 at 1:50 PM, Jan Hubicka <hubicka@ucw.cz> wrote: >> Hmm, actually we have RTL_LOOPING_CONST_OR_PURE_CALL_P, so I see no problem. >> I will try to look into the thread more to figure out what it is all about > > OK, so I think that Peter's patch is fine. The testcase attached to > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47525 > is indeed nonsential. I think noreturn flag there is needed only to avoid > GIMPLE optimizers to optimize the function away earlier. With lack of unit > testing, we might try to come with testcase where GIMPLE optimizers miss the > transofrmation for other reason. > > We might also add sanity checks into c-common.c to warn on such conflicting > combinations of attributes, like pure/const & noreturn. Well, 1) an endless loop isn't a side-effect, 2) nor is not returning, 3) if they were, pure + noreturn would be non-sensical - in which case we can parse it as looping-const-or-pure (please). From just looking at the testcase (w/o bodies for the fns) it looks bogus to DCE the noreturn call. Richard. > Honza >> >> Honza >> >> > looping pure/consts and rely on GIMPLE land to do enough optimization here. >> > (this is probably something we would want to revisit later, since pure flag >> > is useful for scheduling) >> > >> > Honza >
> On Mon, Jan 31, 2011 at 1:50 PM, Jan Hubicka <hubicka@ucw.cz> wrote: > >> Hmm, actually we have RTL_LOOPING_CONST_OR_PURE_CALL_P, so I see no problem. > >> I will try to look into the thread more to figure out what it is all about > > > > OK, so I think that Peter's patch is fine. The testcase attached to > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47525 > > is indeed nonsential. I think noreturn flag there is needed only to avoid > > GIMPLE optimizers to optimize the function away earlier. With lack of unit > > testing, we might try to come with testcase where GIMPLE optimizers miss the > > transofrmation for other reason. > > > > We might also add sanity checks into c-common.c to warn on such conflicting > > combinations of attributes, like pure/const & noreturn. > > Well, 1) an endless loop isn't a side-effect, 2) nor is not returning, 3) if Well, if you define not returning as side effect than docs become less clear (Looping pure function can also i.e. terminate the program and do other things. Only what we ensure is that after returning, the memory is not modified) Docs says: Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute @code{pure}. It does not explicitely mention DCE, tought it is implicit in CSE to be useful. Nothing of that makes sense on noreturn functions. > they were, pure + noreturn would be non-sensical - in which case we > can parse it as looping-const-or-pure (please). From just looking at I don't think silently adding looping flag in some cases (such as combination with noreturn) is sound design and would just confuse users. Nor we want to flip the default and declare all pure/const functions to be looping since that would defeat purpose of the flag. We can warn + drop the flag for sure, but I would not accept noreturn pures as valid and try to behave sanely here. Honza > the testcase (w/o bodies for the fns) it looks bogus to DCE the noreturn > call. > > Richard. > > > Honza > >> > >> Honza > >> > >> > looping pure/consts and rely on GIMPLE land to do enough optimization here. > >> > (this is probably something we would want to revisit later, since pure flag > >> > is useful for scheduling) > >> > > >> > Honza > >
> > On Mon, Jan 31, 2011 at 1:50 PM, Jan Hubicka <hubicka@ucw.cz> wrote: > > >> Hmm, actually we have RTL_LOOPING_CONST_OR_PURE_CALL_P, so I see no problem. > > >> I will try to look into the thread more to figure out what it is all about > > > > > > OK, so I think that Peter's patch is fine. The testcase attached to > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47525 > > > is indeed nonsential. I think noreturn flag there is needed only to avoid > > > GIMPLE optimizers to optimize the function away earlier. With lack of unit > > > testing, we might try to come with testcase where GIMPLE optimizers miss the > > > transofrmation for other reason. > > > > > > We might also add sanity checks into c-common.c to warn on such conflicting > > > combinations of attributes, like pure/const & noreturn. > > > > Well, 1) an endless loop isn't a side-effect, 2) nor is not returning, 3) if > > Well, if you define not returning as side effect than docs become less clear > (Looping pure function can also i.e. terminate the program and do other things. > Only what we ensure is that after returning, the memory is not modified) I think when the possibility of infinite loops was discussed first time, they was declared to be "runtime side effect" Honza
2011/1/31 Jan Hubicka <hubicka@ucw.cz>: >> > On Mon, Jan 31, 2011 at 1:50 PM, Jan Hubicka <hubicka@ucw.cz> wrote: >> > >> Hmm, actually we have RTL_LOOPING_CONST_OR_PURE_CALL_P, so I see no problem. >> > >> I will try to look into the thread more to figure out what it is all about >> > > >> > > OK, so I think that Peter's patch is fine. The testcase attached to >> > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47525 >> > > is indeed nonsential. I think noreturn flag there is needed only to avoid >> > > GIMPLE optimizers to optimize the function away earlier. With lack of unit >> > > testing, we might try to come with testcase where GIMPLE optimizers miss the >> > > transofrmation for other reason. >> > > >> > > We might also add sanity checks into c-common.c to warn on such conflicting >> > > combinations of attributes, like pure/const & noreturn. >> > >> > Well, 1) an endless loop isn't a side-effect, 2) nor is not returning, 3) if >> >> Well, if you define not returning as side effect than docs become less clear >> (Looping pure function can also i.e. terminate the program and do other things. >> Only what we ensure is that after returning, the memory is not modified) > > I think when the possibility of infinite loops was discussed first time, they was > declared to be "runtime side effect" Well, I think at least the docs for pure/const should be amended to mention dead-code elimination (in case the return value is not used, in which case a void function as in the testcase doesn't make much sense). The docs should also mention that the compiler assumes a pure / const function always returns normally even when noreturn or throw is specified (which both is weird). Richard. > Honza >
On Mon, 2011-01-31 at 13:21 +0100, Richard Guenther wrote: > I don't think the testcase is valid. > > extern int link_failure (int) __attribute__ ((pure)); > extern void no_return (void) __attribute__ ((noreturn,pure)); > int > main (void) > { > if (link_failure (0) < 1) > no_return (); > return 0; > } I originally hit this bug on testsuite/gcc.dg/pr42461.c which looks like: extern int link_failure (int) __attribute__ ((pure)); int main (void) { if (link_failure (0) < 1) __builtin_unreachable (); return 0; } I tried rewriting it without the __builtin_unreachable() call so that I could compile it on older gcc's (4.3 and 4.4) where the unreachable builtin isn't defined. So the no_return() was just my poor man's __builtin_unreachable() substitute. Peter
On Mon, 2011-01-31 at 13:21 +0100, Richard Guenther wrote: > no_return might be implemented as > > no_return() { while (1);} > > which means we can't DCE either call. I'll also note that my patch doesn't modify DCE at all, so current and older GCCs will happily DCE both calls today. My problem is that when I add the -maltivec option, we add a register to global_regs[], so that the function calls we can DCE without -maltivec, we can no longer DCE. My point is that const and pure functions shouldn't be messing with global registers and that is all my patch deals with. Whether we should even be DCE'ing const or pure functions is a question for the DCE pass and not related to this patch.... although I agree with Kenny and one of your later posts that we should allow DCE of these types of functions and the documentation should be updated to explicitly mention DCE is allowed. Peter
> > I think when the possibility of infinite loops was discussed first time, they was > > declared to be "runtime side effect" > > Well, I think at least the docs for pure/const should be amended to > mention dead-code elimination (in case the return value is not used, Yes. We should probably replace "loop optimization" by "code motion" since pure/consts can be subject of PRE. I don't like much defining the meaning of pureness of function by listing what optimizations are performed. On the other hand it is probably more practical approach than "proper" definition. I can't think of any other optimization we do or want to do that can not be seen as consequence of CSE/DCE/code motion. > in which case a void function as in the testcase doesn't make much > sense). The docs should also mention that the compiler assumes > a pure / const function always returns normally even when > noreturn or throw is specified (which both is weird). DCE on noreturn functions is very undefined thing. We have no idea where to place the new fallthrough edge. I would expect normal DCE to not remove such statement since it is a control flow and control flow statements are not removed even when they have no side effects. I am very surprised RTL DCE manages to take that statement away without ICEing. Also note that const&pure functions can throw (same way as normal operations can). I am not sure if "return normally" is well defined and understandable by user, but I guess we could write that function must always either "return normally or by exception handling". It would be similar to what we already have in leaf attribute definition: Calls to external functions with this attribute must return to the current compilation unit only by return or by exception handling. I can think of function whose body is infinite loop without side effects except for throwing exception after finitely many iterations. Such function is technically noreturn & pure. Still I would preffer to just warn as such flag combination makes no sense in sane code. I would also mention in docs that const/pure functions should not be noreturn or returns_twice since those flags imply side effects not allowed by definition of const&pure functions. Honza > > Richard. > > > Honza > >
On Sat, 2011-01-29 at 11:54 +0100, Paolo Bonzini wrote: > On Sat, Jan 29, 2011 at 00:06, Peter Bergner <bergner@vnet.ibm.com> wrote: > > Is that patch OK? If so, do we want this in mainline now or after 4.6 > > has branched? > > Since this is a regression, ok for 4.6 but please bootstrap it on an > x86 machine too just for the sake of coverage. Ok, this passed bootstrap and reg testing on x86_64-linux too with no regressions. I'll commit this tomorrow unless one of the RMs objects and wants this to wait for 4.7. Peter
On Tue, 2011-02-01 at 14:18 -0600, Peter Bergner wrote: > On Sat, 2011-01-29 at 11:54 +0100, Paolo Bonzini wrote: > > On Sat, Jan 29, 2011 at 00:06, Peter Bergner <bergner@vnet.ibm.com> wrote: > > > Is that patch OK? If so, do we want this in mainline now or after 4.6 > > > has branched? > > > > Since this is a regression, ok for 4.6 but please bootstrap it on an > > x86 machine too just for the sake of coverage. > > Ok, this passed bootstrap and reg testing on x86_64-linux too with no > regressions. I'll commit this tomorrow unless one of the RMs objects > and wants this to wait for 4.7. Committed as revision 169768. Thanks everyone. Peter
Index: df-scan.c =================================================================== --- df-scan.c (revision 169365) +++ df-scan.c (working copy) @@ -1,6 +1,6 @@ /* Scanning of rtl for dataflow analysis. Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010 Free Software Foundation, Inc. + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Originally contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com) Major rewrite contributed by Danny Berlin (dberlin@dberlin.org) @@ -3360,16 +3360,19 @@ df_get_call_refs (struct df_collection_r NULL, bb, insn_info, DF_REF_REG_USE, DF_REF_CALL_STACK_USAGE | flags); - /* Calls may also reference any of the global registers, - so they are recorded as used. */ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (global_regs[i]) - { - df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], - NULL, bb, insn_info, DF_REF_REG_USE, flags); - df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], - NULL, bb, insn_info, DF_REF_REG_DEF, flags); - } + /* Calls to const functions cannot access any global registers and calls to + pure functions cannot set them. All other calls may reference any of the + global registers, so they are recorded as used. */ + if (!RTL_CONST_CALL_P (insn_info->insn)) + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (global_regs[i]) + { + df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], + NULL, bb, insn_info, DF_REF_REG_USE, flags); + if (!RTL_PURE_CALL_P (insn_info->insn)) + df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], + NULL, bb, insn_info, DF_REF_REG_DEF, flags); + } is_sibling_call = SIBLING_CALL_P (insn_info->insn); EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, ui, bi)