* [PATCH] Mark explicit decls as implicit when we've seen a prototype
@ 2014-12-04 11:01 Richard Biener
2014-12-04 11:14 ` Alexander Monakov
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Richard Biener @ 2014-12-04 11:01 UTC (permalink / raw)
To: gcc-patches; +Cc: Joseph S. Myers, jason
Currently even when I prototype
double exp10 (double);
this function is not available to optimizers for code generation if
they just check for builtin_decl_implicit (BUILT_IN_EXP10).
Curiously though the function is identified as BUILT_IN_EXP10 when
used though, thus the middle-end assumes it has expected exp10
semantics. I see we already cheat with stpcpy and make it available
to optimizers by marking it implicit when we've seen a prototype.
The following patch proposed to do that for all builtins.
At least I can't see how interpreting exp10 as exp10 but then
not being allowed to use it as exp10 is sensible.
Now one could argue that declaring exp10 doesn't mean there is
an implementation available at link time (after all declaring
exp10 doesn't mean I use exp10 anywhere). But that's true
for implicit decls as well - I might declare 'pow', not use
it and not link against libm. So if the compiler now emits
a call to pow my link will break:
extern double pow (double, double);
double x;
int main ()
{
return x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x;
}
links fine with -O0 but fails to link with -Os -ffast-math where
I have to supply -lm.
So the following patch extends the stpcpy assumption to all builtins.
Ok after bootstrap / regtest?
Thanks,
Richard.
2014-12-04 Richard Biener <rguenther@suse.de>
c/
* c-decl.c (merge_decls): For explicit builtin functions mark
them as implicit when we have seen a compatible prototype.
cp/
* decl.c (duplicate_decls): For explicit builtin functions mark
them as implicit when we have seen a compatible prototype.
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c (revision 218343)
+++ gcc/c/c-decl.c (working copy)
@@ -2563,18 +2563,11 @@ merge_decls (tree newdecl, tree olddecl,
if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
{
enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
- switch (fncode)
- {
- /* If a compatible prototype of these builtin functions
- is seen, assume the runtime implements it with the
- expected semantics. */
- case BUILT_IN_STPCPY:
- if (builtin_decl_explicit_p (fncode))
- set_builtin_decl_implicit_p (fncode, true);
- break;
- default:
- break;
- }
+ /* If a compatible prototype of a builtin function
+ is seen, assume the runtime implements it with the
+ expected semantics. */
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_implicit_p (fncode, true);
}
}
else
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c (revision 218343)
+++ gcc/cp/decl.c (working copy)
@@ -2288,18 +2288,11 @@ duplicate_decls (tree newdecl, tree oldd
if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
{
enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
- switch (fncode)
- {
- /* If a compatible prototype of these builtin functions
- is seen, assume the runtime implements it with the
- expected semantics. */
- case BUILT_IN_STPCPY:
- if (builtin_decl_explicit_p (fncode))
- set_builtin_decl_implicit_p (fncode, true);
- break;
- default:
- break;
- }
+ /* If a compatible prototype of a builtin function
+ is seen, assume the runtime implements it with the
+ expected semantics. */
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_implicit_p (fncode, true);
}
}
if (new_defines_function)
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-04 11:01 [PATCH] Mark explicit decls as implicit when we've seen a prototype Richard Biener
@ 2014-12-04 11:14 ` Alexander Monakov
2014-12-04 14:06 ` Jason Merrill
2014-12-04 15:05 ` Joseph Myers
2 siblings, 0 replies; 15+ messages in thread
From: Alexander Monakov @ 2014-12-04 11:14 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches, Joseph S. Myers, jason
On Thu, 4 Dec 2014, Richard Biener wrote:
>
> Currently even when I prototype
>
> double exp10 (double);
>
> this function is not available to optimizers for code generation if
> they just check for builtin_decl_implicit (BUILT_IN_EXP10).
> Curiously though the function is identified as BUILT_IN_EXP10 when
> used though, thus the middle-end assumes it has expected exp10
> semantics. I see we already cheat with stpcpy and make it available
> to optimizers by marking it implicit when we've seen a prototype.
>
> The following patch proposed to do that for all builtins.
>
> At least I can't see how interpreting exp10 as exp10 but then
> not being allowed to use it as exp10 is sensible.
>
> Now one could argue that declaring exp10 doesn't mean there is
> an implementation available at link time (after all declaring
> exp10 doesn't mean I use exp10 anywhere). But that's true
> for implicit decls as well - I might declare 'pow', not use
> it and not link against libm. So if the compiler now emits
> a call to pow my link will break:
>
> extern double pow (double, double);
> double x;
> int main ()
> {
> return x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x;
> }
>
> links fine with -O0 but fails to link with -Os -ffast-math where
> I have to supply -lm.
>
> So the following patch extends the stpcpy assumption to all builtins.
I think it would be nice if -ffreestanding could be used to disable this kind
of transformations. Compare with folding a loop to memset in a libc function
implementing memset itself.
Thanks.
Alexander
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-04 11:01 [PATCH] Mark explicit decls as implicit when we've seen a prototype Richard Biener
2014-12-04 11:14 ` Alexander Monakov
@ 2014-12-04 14:06 ` Jason Merrill
2014-12-04 15:05 ` Joseph Myers
2 siblings, 0 replies; 15+ messages in thread
From: Jason Merrill @ 2014-12-04 14:06 UTC (permalink / raw)
To: Richard Biener, gcc-patches; +Cc: Joseph S. Myers
OK.
Jason
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-04 11:01 [PATCH] Mark explicit decls as implicit when we've seen a prototype Richard Biener
2014-12-04 11:14 ` Alexander Monakov
2014-12-04 14:06 ` Jason Merrill
@ 2014-12-04 15:05 ` Joseph Myers
2014-12-04 15:17 ` Richard Biener
2 siblings, 1 reply; 15+ messages in thread
From: Joseph Myers @ 2014-12-04 15:05 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches, jason
On Thu, 4 Dec 2014, Richard Biener wrote:
> Currently even when I prototype
>
> double exp10 (double);
>
> this function is not available to optimizers for code generation if
> they just check for builtin_decl_implicit (BUILT_IN_EXP10).
> Curiously though the function is identified as BUILT_IN_EXP10 when
> used though, thus the middle-end assumes it has expected exp10
> semantics. I see we already cheat with stpcpy and make it available
> to optimizers by marking it implicit when we've seen a prototype.
>
> The following patch proposed to do that for all builtins.
>
> At least I can't see how interpreting exp10 as exp10 but then
> not being allowed to use it as exp10 is sensible.
>
> Now one could argue that declaring exp10 doesn't mean there is
> an implementation available at link time (after all declaring
> exp10 doesn't mean I use exp10 anywhere). But that's true
> for implicit decls as well - I might declare 'pow', not use
> it and not link against libm. So if the compiler now emits
> a call to pow my link will break:
Logically I think the following should apply (no doubt there are various
existing bugs in this area; at least, PR 46926 for sincos calls being
generated in circumstances when that name is not reserved):
* If a function is assumed to have particular semantics, it can also be
assumed to be available for code generation, *except* that implicitly
introducing references to functions that may not be in libc is unsafe
unless the user's program explicitly used a function from the containing
library. (Libraries for things that may not be in libc are as listed at
<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html>; only
libm for <math.h>, <complex.h> and <fenv.h> functions is likely to be
relevant to GCC. "explicitly used" is as in C11 6.9#5: "used in an
expression (other than as part of the operand of a sizeof or _Alignof
operator whose result is an integer constant)" (appropriately extended to
cover GNU C extensions, such as typeof with non-variably-modified
arguments).)
I don't think there's any existing infrastructure to avoid introducing
e.g. calls to pow (in the absence of explicit calls to some libm function)
in cases such as you suggest (and of course pow is an ISO C90 function so
its semantics can always be assumed - the question is just whether libm
will be used).
* If __builtin_foo (a built-in function where there is a corresponding
function foo, standard or otherwise) is explicitly used, except maybe for
calls with constant arguments expected to be optimized, the function foo
may be assumed to be available and to have the expected semantics. This
applies regardless of what library foo is expected to be in, and
regardless of whether foo is defined by any standard selected with -std,
and regardless of any target-specific configuration information about what
functions the target libraries provide (e.g. __builtin_sincos calls can be
expanded to sincos whether or not the target has such a function).
Furthermore, an explicit use of __builtin_foo for a libm function can be
taken as meaning that libm will be linked in, except maybe for calls with
constant arguments expected to be optimized.
(The point of the constant arguments exception is that calls to
__builtin_nan (""), for example, are OK in static initializers, and maybe
shouldn't be taken as meaning the nan library function is available or
libm will be linked in. The built-in functions for generating NaNs may be
the only case for which this needs to apply.)
* As documented for -nostdlib, memcmp, memset, memcpy and memmove may
always be assumed to be available, even with -ffreestanding, regardless of
what explicit calls are or are not present.
* Built-in functions enabled by the selected -std (which in the default
mode should mean all of them, but in modes such as -std=c11 is a smaller
set) may always be assumed to be available in libraries linked in and to
have the expected semantics, subject to (a) any target-specific
configuration (targetm.libc_has_function) and (b) whether there are any
explicit calls to functions in the relevant library (not generating calls
to pow in the absence of any explicit libm function calls).
* Built-in functions reserved but not enabled by the selected -std (e.g.
float and long double functions for -std=c90) may be treated the same as
those enabled by the selected -std: it's never valid for the user to use
them with any other semantics, and targetm.libc_has_function determines
whether the function is available to generate calls to it (together with
the presence of any explicit calls to libm functions).
* Built-in functions not reserved or enabled by the selected -std may be
assumed to be available and to have the expected semantics (subject to
some functions from the relevant library being explicitly called, in the
case of libm functions) if declared *in a system header*. So if you use
-std=c11 -D_GNU_SOURCE and then include a header declaring exp10 or
stpcpy, that implies you are using the _GNU_SOURCE library interface and
so will not use those names for some other purpose. Indeed, if you use
_GNU_SOURCE before including any system header anywhere in your program
you're arguably using the _GNU_SOURCE library interface and so reserving
those names. But if you only ever use system headers with feature test
macros that don't reserve a given name, then you can use that name for
some other incompatible purpose (so e.g. a strict ISO C program can use
the exp10 or stpcpy names for its own purposes).
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-04 15:05 ` Joseph Myers
@ 2014-12-04 15:17 ` Richard Biener
2014-12-04 15:24 ` Joseph Myers
0 siblings, 1 reply; 15+ messages in thread
From: Richard Biener @ 2014-12-04 15:17 UTC (permalink / raw)
To: Joseph Myers; +Cc: gcc-patches, jason
On Thu, 4 Dec 2014, Joseph Myers wrote:
> On Thu, 4 Dec 2014, Richard Biener wrote:
>
> > Currently even when I prototype
> >
> > double exp10 (double);
> >
> > this function is not available to optimizers for code generation if
> > they just check for builtin_decl_implicit (BUILT_IN_EXP10).
> > Curiously though the function is identified as BUILT_IN_EXP10 when
> > used though, thus the middle-end assumes it has expected exp10
> > semantics. I see we already cheat with stpcpy and make it available
> > to optimizers by marking it implicit when we've seen a prototype.
> >
> > The following patch proposed to do that for all builtins.
> >
> > At least I can't see how interpreting exp10 as exp10 but then
> > not being allowed to use it as exp10 is sensible.
> >
> > Now one could argue that declaring exp10 doesn't mean there is
> > an implementation available at link time (after all declaring
> > exp10 doesn't mean I use exp10 anywhere). But that's true
> > for implicit decls as well - I might declare 'pow', not use
> > it and not link against libm. So if the compiler now emits
> > a call to pow my link will break:
>
> Logically I think the following should apply (no doubt there are various
> existing bugs in this area; at least, PR 46926 for sincos calls being
> generated in circumstances when that name is not reserved):
>
> * If a function is assumed to have particular semantics, it can also be
> assumed to be available for code generation, *except* that implicitly
> introducing references to functions that may not be in libc is unsafe
> unless the user's program explicitly used a function from the containing
> library. (Libraries for things that may not be in libc are as listed at
> <http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html>; only
> libm for <math.h>, <complex.h> and <fenv.h> functions is likely to be
> relevant to GCC. "explicitly used" is as in C11 6.9#5: "used in an
> expression (other than as part of the operand of a sizeof or _Alignof
> operator whose result is an integer constant)" (appropriately extended to
> cover GNU C extensions, such as typeof with non-variably-modified
> arguments).)
>
> I don't think there's any existing infrastructure to avoid introducing
> e.g. calls to pow (in the absence of explicit calls to some libm function)
> in cases such as you suggest (and of course pow is an ISO C90 function so
> its semantics can always be assumed - the question is just whether libm
> will be used).
>
> * If __builtin_foo (a built-in function where there is a corresponding
> function foo, standard or otherwise) is explicitly used, except maybe for
> calls with constant arguments expected to be optimized, the function foo
> may be assumed to be available and to have the expected semantics. This
> applies regardless of what library foo is expected to be in, and
> regardless of whether foo is defined by any standard selected with -std,
> and regardless of any target-specific configuration information about what
> functions the target libraries provide (e.g. __builtin_sincos calls can be
> expanded to sincos whether or not the target has such a function).
> Furthermore, an explicit use of __builtin_foo for a libm function can be
> taken as meaning that libm will be linked in, except maybe for calls with
> constant arguments expected to be optimized.
>
> (The point of the constant arguments exception is that calls to
> __builtin_nan (""), for example, are OK in static initializers, and maybe
> shouldn't be taken as meaning the nan library function is available or
> libm will be linked in. The built-in functions for generating NaNs may be
> the only case for which this needs to apply.)
>
> * As documented for -nostdlib, memcmp, memset, memcpy and memmove may
> always be assumed to be available, even with -ffreestanding, regardless of
> what explicit calls are or are not present.
>
> * Built-in functions enabled by the selected -std (which in the default
> mode should mean all of them, but in modes such as -std=c11 is a smaller
> set) may always be assumed to be available in libraries linked in and to
> have the expected semantics, subject to (a) any target-specific
> configuration (targetm.libc_has_function) and (b) whether there are any
> explicit calls to functions in the relevant library (not generating calls
> to pow in the absence of any explicit libm function calls).
>
> * Built-in functions reserved but not enabled by the selected -std (e.g.
> float and long double functions for -std=c90) may be treated the same as
> those enabled by the selected -std: it's never valid for the user to use
> them with any other semantics, and targetm.libc_has_function determines
> whether the function is available to generate calls to it (together with
> the presence of any explicit calls to libm functions).
>
> * Built-in functions not reserved or enabled by the selected -std may be
> assumed to be available and to have the expected semantics (subject to
> some functions from the relevant library being explicitly called, in the
> case of libm functions) if declared *in a system header*. So if you use
> -std=c11 -D_GNU_SOURCE and then include a header declaring exp10 or
> stpcpy, that implies you are using the _GNU_SOURCE library interface and
> so will not use those names for some other purpose. Indeed, if you use
> _GNU_SOURCE before including any system header anywhere in your program
> you're arguably using the _GNU_SOURCE library interface and so reserving
> those names. But if you only ever use system headers with feature test
> macros that don't reserve a given name, then you can use that name for
> some other incompatible purpose (so e.g. a strict ISO C program can use
> the exp10 or stpcpy names for its own purposes).
So what does this all mean in practice for optimization passes?
There are only two things they can easily check right now - look
at builtin_decl_implicit () and builtin_decl_explicit (). It seems
that builtin_decl_explicit () is useless because a) the declaration
may not come from a system header, b) the function may not be
referenced and thus the relevant library may not be linked in.
Strictly speaking builtin_decl_implicit () is also not too useful
as b) applies there as well.
When b) does not apply then the given stpcpy special-casing shows
that even then this is not enough. So should that special-casing
and any extension of it add
&& in_system_header_at (DECL_SOURCE_LOCATION (newdecl))
?
As a check whether a function is used would need to be delayed
until after the cgraph is built (when we know all references via
calls and address-takens), the whole machinery would need to
move there. But then we couldn't simply rely on builtin_decl_implicit
but would have to wrap middle-end uses for code generation in
some better abstraction.
Richard.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-04 15:17 ` Richard Biener
@ 2014-12-04 15:24 ` Joseph Myers
2014-12-04 15:29 ` Richard Biener
0 siblings, 1 reply; 15+ messages in thread
From: Joseph Myers @ 2014-12-04 15:24 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches, jason
On Thu, 4 Dec 2014, Richard Biener wrote:
> So what does this all mean in practice for optimization passes?
I don't know what it means in terms of how to fix the various existing
problems - it's simply how I think a fixed compiler should behave.
> When b) does not apply then the given stpcpy special-casing shows
> that even then this is not enough. So should that special-casing
> and any extension of it add
>
> && in_system_header_at (DECL_SOURCE_LOCATION (newdecl))
>
> ?
I think that would be logically correct (for allowing stpcpy calls to be
generated in optimization if the user included <string.h> with
_POSIX_C_SOURCE=200809L defined, for example, but not if they used
-std=c11 without feature test macros and declared their own stpcpy). But
the same should apply to any optimization of stpcpy calls written by the
user - they can only be assumed to have standard stpcpy semantics if (a)
the selected standard includes stpcpy, e.g. -std=gnu11 or (b) stpcpy was
declared in a system header, not just by the user.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-04 15:24 ` Joseph Myers
@ 2014-12-04 15:29 ` Richard Biener
2014-12-04 15:45 ` Joseph Myers
0 siblings, 1 reply; 15+ messages in thread
From: Richard Biener @ 2014-12-04 15:29 UTC (permalink / raw)
To: Joseph Myers; +Cc: gcc-patches, jason
On Thu, 4 Dec 2014, Joseph Myers wrote:
> On Thu, 4 Dec 2014, Richard Biener wrote:
>
> > So what does this all mean in practice for optimization passes?
>
> I don't know what it means in terms of how to fix the various existing
> problems - it's simply how I think a fixed compiler should behave.
>
> > When b) does not apply then the given stpcpy special-casing shows
> > that even then this is not enough. So should that special-casing
> > and any extension of it add
> >
> > && in_system_header_at (DECL_SOURCE_LOCATION (newdecl))
> >
> > ?
>
> I think that would be logically correct (for allowing stpcpy calls to be
> generated in optimization if the user included <string.h> with
> _POSIX_C_SOURCE=200809L defined, for example, but not if they used
> -std=c11 without feature test macros and declared their own stpcpy). But
> the same should apply to any optimization of stpcpy calls written by the
> user - they can only be assumed to have standard stpcpy semantics if (a)
> the selected standard includes stpcpy, e.g. -std=gnu11 or (b) stpcpy was
> declared in a system header, not just by the user.
Yeah - it is that current difference that appears most odd to me.
We assume stpcpy semantics (stick BUILT_IN_STPCPY on the decl) as
soon as we see a (compatible?) decl but we do not allow us to
generate a call to it because semantics may be different(!?).
OTOH this also means the user cannot provide a conforming
implementation on his own and get that used by GCC without editing
system headers or including a header with -isystem or similar
tricks.
Richard.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-04 15:29 ` Richard Biener
@ 2014-12-04 15:45 ` Joseph Myers
2014-12-08 12:30 ` Richard Biener
0 siblings, 1 reply; 15+ messages in thread
From: Joseph Myers @ 2014-12-04 15:45 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches, jason
On Thu, 4 Dec 2014, Richard Biener wrote:
> OTOH this also means the user cannot provide a conforming
> implementation on his own and get that used by GCC without editing
> system headers or including a header with -isystem or similar
> tricks.
Well - you could have a pragma / attribute for that purpose (declaring
"this program is providing a version of function X that has the semantics
GCC expects for function X", so GCC can both generate and optimize calls).
Such a pragma / attribute could also override targetm.libc_has_function
(for the case of the user providing their own definition of something
missing from their system's standard libraries). A related case would be
declaring somehow "I will be linking in libm, even though this translation
unit doesn't appear to be using libm functions, so calls to libm functions
can be implicitly generated", if GCC were made to avoid introducing uses
of libm. (Again, this would be a matter of providing a cleaner interface
rather than something that currently can't be expressed at all - the
proposed definition of what it means to use libm explicitly implies that
"if (0) (void) sqrt (0);" says that libm is being used.)
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-04 15:45 ` Joseph Myers
@ 2014-12-08 12:30 ` Richard Biener
2014-12-08 12:45 ` Jakub Jelinek
2014-12-08 22:43 ` Joseph Myers
0 siblings, 2 replies; 15+ messages in thread
From: Richard Biener @ 2014-12-08 12:30 UTC (permalink / raw)
To: Joseph Myers; +Cc: gcc-patches, jason
On Thu, 4 Dec 2014, Joseph Myers wrote:
> On Thu, 4 Dec 2014, Richard Biener wrote:
>
> > OTOH this also means the user cannot provide a conforming
> > implementation on his own and get that used by GCC without editing
> > system headers or including a header with -isystem or similar
> > tricks.
>
> Well - you could have a pragma / attribute for that purpose (declaring
> "this program is providing a version of function X that has the semantics
> GCC expects for function X", so GCC can both generate and optimize calls).
> Such a pragma / attribute could also override targetm.libc_has_function
> (for the case of the user providing their own definition of something
> missing from their system's standard libraries). A related case would be
> declaring somehow "I will be linking in libm, even though this translation
> unit doesn't appear to be using libm functions, so calls to libm functions
> can be implicitly generated", if GCC were made to avoid introducing uses
> of libm. (Again, this would be a matter of providing a cleaner interface
> rather than something that currently can't be expressed at all - the
> proposed definition of what it means to use libm explicitly implies that
> "if (0) (void) sqrt (0);" says that libm is being used.)
I tried to come up with a patch that adds extra checks but the existing
way of having 'implicit' vs. 'explicit' only available as a flag rather
than making the explicitely declared builtin decl available makes
it harder than necessary. I also run into the issue that we
remove all cgraph edges during GIMPLE optimizations thus embedding
the "is there already a use of the builtin" in the new abstraction
doesn't fly.
This means the frontend has to provide a "used" flag to the middle-end
as well as a "declared" flag. For providing a declared flag there
is already the place where we special-case STPCPY, for providing
a "used" flag I don't see any obvious place.
I'm not pushing this further for stage3, but for stage1 I'd like
to eventually address this by splitting up builtin_info_type's
'implicit_p' into a flags array providing implicit_p, declared_p,
used_p and maybe declared_in_system_header_p. Would you be
willing to fill in the gap computing "used_p" in the C frontend?
My non-working abstraction for middle-end folders looks like
/* Return the decl for the builtin function FNCODE or NULL_TREE if it
cannot
be emitted by GCC. */
tree
builtin_decl (enum built_in_function fncode)
{
tree decl = builtin_decl_implicit (fncode);
if (decl)
return decl;
decl = builtin_decl_explicit (fncode);
if (!decl)
return NULL_TREE;
/* We cannot use a builtin that has not been declared explicitely. */
if (!(builtin_info.flags[fncode] & bif_declared_p))
return NULL_TREE;
/* We can use a builtin that has been declared explicitely only if
the program contains a reference to it already. */
cgraph_node *node = cgraph_node::get_for_asmname (DECL_ASSEMBLER_NAME
(decl));
if (!node || !node->callers)
return NULL_TREE;
return decl;
}
which currently fails because of us having removing cgraph edges
at the points the function is called. Thus the cgraph caller
check would be replaced by a check for 'used_p'. We'd still
get __builtin_exp10 emitted instead of the user-declared "exp10"
variant (we don't have access to that decl).
Without the 'used_p' flag work the rest would be equivalent to
setting implicit_p for explicit declarations we see (the originally
proposed patch which follows the stpcpy example).
Thanks,
Richard.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-08 12:30 ` Richard Biener
@ 2014-12-08 12:45 ` Jakub Jelinek
2014-12-08 13:00 ` Richard Biener
2014-12-08 22:43 ` Joseph Myers
1 sibling, 1 reply; 15+ messages in thread
From: Jakub Jelinek @ 2014-12-08 12:45 UTC (permalink / raw)
To: Richard Biener; +Cc: Joseph Myers, gcc-patches, jason
On Mon, Dec 08, 2014 at 01:24:12PM +0100, Richard Biener wrote:
> I'm not pushing this further for stage3, but for stage1 I'd like
> to eventually address this by splitting up builtin_info_type's
> 'implicit_p' into a flags array providing implicit_p, declared_p,
> used_p and maybe declared_in_system_header_p. Would you be
> willing to fill in the gap computing "used_p" in the C frontend?
The used_p thing might be problematic, I'd expect that several packages
use libm functions somewhere in dead code or when it is folded into
a constant and don't link with -lm, if those dead or optimized away
uses would be counted as uses nevertheless, then if optimizers create new
libm references because of those, I'd be afraid such programs wouldn't link
anymore.
Jakub
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-08 12:45 ` Jakub Jelinek
@ 2014-12-08 13:00 ` Richard Biener
2014-12-08 13:04 ` Jakub Jelinek
2014-12-08 22:47 ` Joseph Myers
0 siblings, 2 replies; 15+ messages in thread
From: Richard Biener @ 2014-12-08 13:00 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Joseph Myers, gcc-patches, jason
On Mon, 8 Dec 2014, Jakub Jelinek wrote:
> On Mon, Dec 08, 2014 at 01:24:12PM +0100, Richard Biener wrote:
> > I'm not pushing this further for stage3, but for stage1 I'd like
> > to eventually address this by splitting up builtin_info_type's
> > 'implicit_p' into a flags array providing implicit_p, declared_p,
> > used_p and maybe declared_in_system_header_p. Would you be
> > willing to fill in the gap computing "used_p" in the C frontend?
>
> The used_p thing might be problematic, I'd expect that several packages
> use libm functions somewhere in dead code or when it is folded into
> a constant and don't link with -lm, if those dead or optimized away
> uses would be counted as uses nevertheless, then if optimizers create new
> libm references because of those, I'd be afraid such programs wouldn't link
> anymore.
Same applies to your STPCPY special-casing, even without introducing
a use.
The alternative is to decide "used" in the middle-end at one point,
for example at the end of all_lowering_passes where hopefully
we have constant folded and removed dead code enough. We can also
compute an overall "uses libm" flag to fix the testcase I reported
(of course we'd like to re-compute that at LTO time).
Do you think that's better? It's of course less well-defined what
is a "use" of exp10 then (as opposed to what Joseph specified
with a reference outside of sizeof() and similar contexts).
Richard.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-08 13:00 ` Richard Biener
@ 2014-12-08 13:04 ` Jakub Jelinek
2014-12-08 22:47 ` Joseph Myers
1 sibling, 0 replies; 15+ messages in thread
From: Jakub Jelinek @ 2014-12-08 13:04 UTC (permalink / raw)
To: Richard Biener; +Cc: Joseph Myers, gcc-patches, jason
On Mon, Dec 08, 2014 at 01:54:21PM +0100, Richard Biener wrote:
> On Mon, 8 Dec 2014, Jakub Jelinek wrote:
>
> > On Mon, Dec 08, 2014 at 01:24:12PM +0100, Richard Biener wrote:
> > > I'm not pushing this further for stage3, but for stage1 I'd like
> > > to eventually address this by splitting up builtin_info_type's
> > > 'implicit_p' into a flags array providing implicit_p, declared_p,
> > > used_p and maybe declared_in_system_header_p. Would you be
> > > willing to fill in the gap computing "used_p" in the C frontend?
> >
> > The used_p thing might be problematic, I'd expect that several packages
> > use libm functions somewhere in dead code or when it is folded into
> > a constant and don't link with -lm, if those dead or optimized away
> > uses would be counted as uses nevertheless, then if optimizers create new
> > libm references because of those, I'd be afraid such programs wouldn't link
> > anymore.
>
> Same applies to your STPCPY special-casing, even without introducing
> a use.
Well, the important difference there is that stpcpy is in libc, not libm,
and you get the former by default usually (-nostdlib is very rare).
Yes, supposedly overall uses libc, uses libm flags would be reasonable.
> The alternative is to decide "used" in the middle-end at one point,
> for example at the end of all_lowering_passes where hopefully
> we have constant folded and removed dead code enough. We can also
> compute an overall "uses libm" flag to fix the testcase I reported
> (of course we'd like to re-compute that at LTO time).
>
> Do you think that's better? It's of course less well-defined what
> is a "use" of exp10 then (as opposed to what Joseph specified
> with a reference outside of sizeof() and similar contexts).
Jakub
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-08 12:30 ` Richard Biener
2014-12-08 12:45 ` Jakub Jelinek
@ 2014-12-08 22:43 ` Joseph Myers
1 sibling, 0 replies; 15+ messages in thread
From: Joseph Myers @ 2014-12-08 22:43 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches, jason
On Mon, 8 Dec 2014, Richard Biener wrote:
> I'm not pushing this further for stage3, but for stage1 I'd like
> to eventually address this by splitting up builtin_info_type's
> 'implicit_p' into a flags array providing implicit_p, declared_p,
> used_p and maybe declared_in_system_header_p. Would you be
> willing to fill in the gap computing "used_p" in the C frontend?
C_DECL_USED is the right notion of "used" with the front end, in standard
terms (i.e. the notion that requires a definition of the function to be
present somewhere), though as noted some people may be relying on calls
being optimized out. (Of course such people could get implicitly
generated libm calls at present anyway; the point of checking "used" is to
restrict call generation to cases where we know that some library with the
function will be linked in, and that the function will have the right
semantics.)
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-08 13:00 ` Richard Biener
2014-12-08 13:04 ` Jakub Jelinek
@ 2014-12-08 22:47 ` Joseph Myers
2014-12-09 8:58 ` Richard Biener
1 sibling, 1 reply; 15+ messages in thread
From: Joseph Myers @ 2014-12-08 22:47 UTC (permalink / raw)
To: Richard Biener; +Cc: Jakub Jelinek, gcc-patches, jason
On Mon, 8 Dec 2014, Richard Biener wrote:
> The alternative is to decide "used" in the middle-end at one point,
> for example at the end of all_lowering_passes where hopefully
> we have constant folded and removed dead code enough. We can also
> compute an overall "uses libm" flag to fix the testcase I reported
> (of course we'd like to re-compute that at LTO time).
If you do that, of course any optimizations before deciding "used" need to
be conservative - assume that any function except the one you're
optimizing a call of is not "used".
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] Mark explicit decls as implicit when we've seen a prototype
2014-12-08 22:47 ` Joseph Myers
@ 2014-12-09 8:58 ` Richard Biener
0 siblings, 0 replies; 15+ messages in thread
From: Richard Biener @ 2014-12-09 8:58 UTC (permalink / raw)
To: Joseph Myers; +Cc: Jakub Jelinek, gcc-patches, jason
On Mon, 8 Dec 2014, Joseph Myers wrote:
> On Mon, 8 Dec 2014, Richard Biener wrote:
>
> > The alternative is to decide "used" in the middle-end at one point,
> > for example at the end of all_lowering_passes where hopefully
> > we have constant folded and removed dead code enough. We can also
> > compute an overall "uses libm" flag to fix the testcase I reported
> > (of course we'd like to re-compute that at LTO time).
>
> If you do that, of course any optimizations before deciding "used" need to
> be conservative - assume that any function except the one you're
> optimizing a call of is not "used".
Yes. I guess I'm willing to consider a new langhook that for C evaluates
C_DECL_USED. We still have to find a suitable point to query it -
with the earliest point is after parsing finished (thus when we
finalize the TU). At that point all constant expression folding
should have happened (up to the point required by the language) - but
I suppose C_DECL_USED is still set even if all calls were constant
folded away.
Note that computing a middle-end "C_DECL_USED" can be done from
gimplification (possibly after folding the calls there once).
Same for a global "libm function used" flag (where at some point
we might need a target hook to allow specifying whether a call
is from libm).
Richard.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2014-12-09 8:58 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-04 11:01 [PATCH] Mark explicit decls as implicit when we've seen a prototype Richard Biener
2014-12-04 11:14 ` Alexander Monakov
2014-12-04 14:06 ` Jason Merrill
2014-12-04 15:05 ` Joseph Myers
2014-12-04 15:17 ` Richard Biener
2014-12-04 15:24 ` Joseph Myers
2014-12-04 15:29 ` Richard Biener
2014-12-04 15:45 ` Joseph Myers
2014-12-08 12:30 ` Richard Biener
2014-12-08 12:45 ` Jakub Jelinek
2014-12-08 13:00 ` Richard Biener
2014-12-08 13:04 ` Jakub Jelinek
2014-12-08 22:47 ` Joseph Myers
2014-12-09 8:58 ` Richard Biener
2014-12-08 22:43 ` Joseph Myers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).