[PATCH] Mark explicit decls as implicit when we've seen a prototype

Richard Biener rguenther@suse.de
Mon Dec 8 12:30:00 GMT 2014


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.



More information about the Gcc-patches mailing list