[PATCH] clarify comments for implicit_p flag for built-ins
Richard Biener
richard.guenther@gmail.com
Fri Nov 30 08:15:00 GMT 2018
On Wed, Nov 28, 2018 at 7:18 PM Martin Sebor <msebor@gmail.com> wrote:
>
> On 11/28/18 6:35 AM, Richard Biener wrote:
> > On Tue, Nov 27, 2018 at 3:52 AM Martin Sebor <msebor@gmail.com> wrote:
> >>
> >> Ping: https://gcc.gnu.org/ml/gcc-patches/2018-11/msg01759.html
> >>
> >> If there are no objections or suggestions for tweaks I'll commit
> >> this updated comment this week.
> >
> > Please do not commit such changes w/o approval.
>
> Let me follow up on this separately.
>
>
> > Does the new comments match existing usage, for example in gimplify.c
> > where we do
> >
> > static void
> > build_stack_save_restore (gcall **save, gcall **restore)
> > {
> > tree tmp_var;
> >
> > *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
> > tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
> > gimple_call_set_lhs (*save, tmp_var);
> >
> > *restore
> > = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
> > 1, tmp_var);
> > }
> >
> > ?
>
> I don't know why this code uses builtin_decl_implicit here. I don't
> think it's necessary or even correct. If builtin_decl_implicit were
> to return null gimple_build_call() would ICE. Replacing it with
> builtin_decl_explicit passes an x86_64 bootstrap and regression test.
>
> I see the same pattern in some of the other calls to
> builtin_decl_implicit with non-library built-ins. E.g., in
> gimplify_function_tree:
>
> x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
> call = gimple_build_call (x, 1, integer_zero_node);
>
> > +/* Return the tree node for the built-in function declaration corresponding
> > + to FNCODE if its IMPLICIT_P flag has been set or NULL otherwise.
> > + IMPLICIT_P is clear for library built-ins that GCC implements but that
> > + may not be implemented in the runtime library on the target. See also
> > + the DEF_BUILTIN macro in builtins.def. */
> > +
> >
> > it isn't exactly helpful to specify when IMPLICIT_P is not set. When is it
> > actually set?
> >
> > My understanding of the difference is that the compiler may create a call
> > to a builtin_decl_implicit decl but _not_ to a builtin_decl_explicit one
> > unless a call to such function already existed.
>
> This sounds like an important detail to capture but I'm not sure
> I quite understand it to do so.
>
> Besides the BUILT_IN_STACK question above, cp/cp-gimplify.c for
> example calls builtin_decl_explicit with BUILT_IN_UNREACHABLE
> to unconditionally insert a call to the built-in. It does that
> whether or not a call to the built-in has been seen in the program.
> E.g., this:
>
> int f () { }
> int g () { return f (); }
>
> ends up with a __builtin_unreachable call (IMPLICIT is set here
> so the result would be the same if cp/cp-gimplify.c called
> builtin_decl_implicit instead, but that seems beside the point).
>
> > Note we set the implicit flag during gimplification if we see such decl
> > referenced and it is marked as properly declared by the FE.
>
> I see this in gimplify.c:
>
> /* If we see a call to a declared builtin or see its address
> being taken (we can unify those cases here) then we can mark
> the builtin for implicit generation by GCC. */
> if (TREE_CODE (op0) == FUNCTION_DECL
> && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
> && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
> set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
>
> This makes sense to me for library built-ins but for others like
> __builtin_unreachable it seems unnecessary. Their IMPLICIT flag
> is already set. The only calls to set_builtin_decl_implicit_p
> that I can find that clear the IMPLICIT flag are in the VMS
> back-end for BUILT_IN_FWRITE (apparently because the function
> is non-standard there).
>
> >
> > Overall your patch is an improvement I think but maybe you can
> > refer to builtins.def in the documentation for builtin_decl_implicit?
>
> Sure, I'm happy to adjust it once we're confident our understanding
> of how the flag works is correct. In light of your comments I for
> one don't feel I'm there yet.
Everytime I get to the difference of implicit vs. explicit I am confused
as well. Thus I am not saying I completely capture the difference...
(given all the inconsistencies in uses throughout the GCC codebase).
In fact I fail to see the need to have both - having only _implicit would
seem enough for the middle-end ...
Richard.
> Thanks
> Martin
>
> >
> >> On 11/20/18 1:24 PM, Martin Sebor wrote:
> >>> On 11/20/2018 11:02 AM, Martin Sebor wrote:
> >>>> Would the updated comments in the attached patch more accurately
> >>>> describe the purpose of the IMPLICIT_P flag and
> >>>> the builtin_decl_explicit() and builtin_decl_implicit() functions?
> >>>>
> >>>> I ended up here while trying to understand the differences between
> >>>> the functions on different targets and decide which one should be
> >>>> used to diagnose bugs like the one below:
> >>>>
> >>>> long double fabsl (); // missing prototype
> >>>>
> >>>> long double f (int x)
> >>>> {
> >>>> return fabsl (x); // want a warning here
> >>>> }
> >>>>
> >>>> I think we want the warning regardless of IMPLICIT_P so the warning
> >>>> code should call builtin_decl_explicit() to obtain fabsl's expected
> >>>> type, even if the target's runtime doesn't support the function on
> >>>> the basis of the comment:
> >>>>
> >>>> When a program uses floorf we may assume that the floorf function
> >>>> has the expected meaning
> >>>
> >>> Actually, some more testing suggests the comment in builtins.def
> >>> (either the original or the patched one) isn't entirely accurate
> >>> or helpful to understanding the purpose of the flag:
> >>>
> >>> IMPLICIT specifies condition when the builtin can be produced by
> >>> compiler. For instance C90 reserves floorf function, but does not
> >>> define it's meaning. When user uses floorf we may assume that the
> >>> floorf has the meaning we expect, but we can't produce floorf by
> >>> simplifying floor((double)float) since the runtime need not
> >>> implement it.
> >>>
> >>> Given the following code:
> >>>
> >>> float floorf ();
> >>>
> >>> void f (void)
> >>> {
> >>> if (floorf (0.0f))
> >>> __builtin_abort ();
> >>> }
> >>>
> >>> in C90 mode, BUILT_IN_FLOORF's IMPLICIT flag is clear and GCC
> >>> doesn't seem to assume anything about the call to the function,
> >>> contrary to the comment ("we may assume the meaning we expect").
> >>> The comment also doesn't explain when IMPLICIT may be set.
> >>>
> >>> I've updated the comment a bit more to more accurately describe
> >>> when I think the flag is set or clear, and how it's used.
> >>> Corrections or further clarification are appreciated.
> >>>
> >>> Thanks
> >>> Martin
> >>
>
More information about the Gcc-patches
mailing list