This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Improve ECF_NOTHROW flags for direct internal functions
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>, Richard Sandiford <richard dot sandiford at linaro dot org>
- Date: Thu, 17 Aug 2017 16:40:24 +0200
- Subject: Re: Improve ECF_NOTHROW flags for direct internal functions
- Authentication-results: sourceware.org; auth=none
- References: <87k222frr1.fsf@linaro.org> <CAFiYyc0ZZZeTYMtKmwiYL+fG=Re85V=9zdMVjBh+Qf_g8yO4sw@mail.gmail.com> <878tiifo82.fsf@linaro.org>
On Thu, Aug 17, 2017 at 1:06 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote
> Richard Biener <richard.guenther@gmail.com> writes:
>> On Thu, Aug 17, 2017 at 11:49 AM, Richard Sandiford
>> <richard.sandiford@linaro.org> wrote:
>>> Internal functions that map directly to an optab can only throw an
>>> exception for -fnon-call-exceptions. This patch handles that in
>>> internal_fn_flags, in a similar way to ATTR_*NOTHROW in builtins.def.
>>>
>>> (Functions that don't throw even for flag_non_call_exceptions should be
>>> explicitly marked ECF_NOTHROW in internal-fn.def.)
>>>
>>> Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install?
>>
>> Hmm. Note the outcome of flag_non_call_exceptions depends on the
>> current function and thus IPA passes querying flags would need to
>> push an appropriate function context. This means the function should
>> get a struct function * argument and opt_for_fn (fn, flag_non_call_exceptions)
>> should be used. It doesn't help very much that all callers don't have
>> any such context either which means this "optimization" looks like
>> in the wrong place :/ (the global value of flag_non_call_exceptions in
>> the IPA case isn't necessarily conservative).
>>
>> So if you insist then add a comment and add a && cfun check so
>> we're sure we are in non-IPA context (or in properly setup context).
>
> Bah. In that case, what should happen if a -fno-non-call-exceptions
> function is inlined into an -fnon-call-exceptions one? Should the call
> keep the NOTHROWness of the original function, or should it lose
> NOTHROWness (and thus gain an exception edge)?
nothrow-ness is tracked on the GIMPLE stmt via gimple_call_[set_]nothrow_p,
GIMPLE shouldn't look at flag_non_call_exceptions, it is basically part
of the IL.
> I guess the path of least resistance would be to add an extra check
> for this case in the places that need it, rather than relying solely
> on gimple_call_flags.
Well, gimple_call_flags works fine already (looking at the above in
addition to internal_fn_flags). call_expr_flags looks like it might not.
Richard.
>
> Thanks,
> Richard
>
>
>>
>> Richard.
>>
>>> Richard
>>>
>>>
>>> 2017-08-17 Richard Sandiford <richard.sandiford@linaro.org>
>>>
>>> gcc/
>>> * internal-fn.h (internal_fn_flags): Just declare and move
>>> the actual implementation out-of-line to...
>>> * internal-fn.c (internal_fn_flags): ...here. Set ECF_NOTHROW for
>>> directly-mapped internal functions if !flag_non_call_exceptions.
>>>
>>> Index: gcc/internal-fn.h
>>> ===================================================================
>>> --- gcc/internal-fn.h 2017-02-23 19:54:03.000000000 +0000
>>> +++ gcc/internal-fn.h 2017-08-17 09:05:37.459968561 +0100
>>> @@ -107,15 +107,7 @@ internal_fn_name (enum internal_fn fn)
>>> return internal_fn_name_array[(int) fn];
>>> }
>>>
>>> -/* Return the ECF_* flags for function FN. */
>>> -
>>> -extern const int internal_fn_flags_array[];
>>> -
>>> -static inline int
>>> -internal_fn_flags (enum internal_fn fn)
>>> -{
>>> - return internal_fn_flags_array[(int) fn];
>>> -}
>>> +extern int internal_fn_flags (enum internal_fn fn);
>>>
>>> /* Return fnspec for function FN. */
>>>
>>> Index: gcc/internal-fn.c
>>> ===================================================================
>>> --- gcc/internal-fn.c 2017-08-10 14:36:07.453493083 +0100
>>> +++ gcc/internal-fn.c 2017-08-17 09:05:37.459968561 +0100
>>> @@ -2814,3 +2814,18 @@ expand_PHI (internal_fn, gcall *)
>>> {
>>> gcc_unreachable ();
>>> }
>>> +
>>> +/* Return the ECF_* flags for function FN. */
>>> +
>>> +int
>>> +internal_fn_flags (enum internal_fn fn)
>>> +{
>>> + int flags = internal_fn_flags_array[(int) fn];
>>> + /* Functions that map to optabs can only throw a catchable exception
>>> + when non-call exceptions are enabled. The non-call exceptions in
>>> + these cases will typically come from things like IEEE exceptions,
>>> + divide by zero errors and SEGVs. */
>>> + if (direct_internal_fn_p (fn) && !flag_non_call_exceptions)
>>> + flags |= ECF_NOTHROW;
>>> + return flags;
>>> +}