Richard Biener <richard.guent...@gmail.com> writes:
> On Thu, Aug 17, 2017 at 11:49 AM, Richard Sandiford
> <richard.sandif...@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)?

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.

Thanks,
Richard


>
> Richard.
>
>> Richard
>>
>>
>> 2017-08-17  Richard Sandiford  <richard.sandif...@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;
>> +}

Reply via email to