On Tue, Oct 6, 2020 at 9:21 AM Alexandre Oliva <ol...@adacore.com> wrote:
>
> On Oct  6, 2020, Richard Biener <richard.guent...@gmail.com> wrote:
>
> > On October 6, 2020 3:15:02 AM GMT+02:00, Alexandre Oliva 
> > <ol...@adacore.com> wrote:
> >>
> >> This is a first step towards enabling the sincos optimization in Ada.
> >>
> >> The issue this patch solves is that sincos takes the type to be looked
> >> up with mathfn_built_in from variables or temporaries in which results
> >> of sin and cos are stored.  In Ada, sin and cos are declared in an
> >> internal aux package, with uses thereof in a standard generic package,
> >> which ensures that the types are not what mathfn_built_in expects.
>
> > But are they not compatible?
>
> They are, in that they use the same underlying representation, but
> they're distinct types, not associated with the same TYPE_MAIN_VARIANT.
>
> In Ada it's not unusual to have multiple floating-point types unrelated
> to each other, even if they share identical underlying representation.
> Each such type is a distinct type, in a similar sense that in C++ each
> struct type holding a single double field is a distinct type.
>
> Each such distinct FP type gets a different instantiation of
> Ada.Numerics.Generic_Elementary_Functions, just as a C++ template taking
> a parameter type would get different instantiations for such different
> struct types.
>
>
> Overall, it's a very confusing situation.  We use these alternate types
> to declare the Sin and Cos functions imported from libm as intrinsics
> (separate patch I've written very recently, yet to be contributed), and
> they get matched to the libm intrinsics despite the distinct types, we
> issue calls to them, passing variables of the alternate types without
> explicit conversions, but when the sincos pass looks up the sincos/cexpi
> intrinsic, it uses the alternate type taken from the variable and fails,
> rather than the types declared as taken by the builtins.

OK, I see.  mathfn_built_in expects a type inter-operating with
the C ABI types (float_type_node, double_type_node, etc.) where
"inter-operating" means having the same main variant.

Now, I guess for the sincos pass we want to combine sinl + cosl
to sincosl, independent on the case where the result would be
assigned to a 'double' when 'double == long double'?  Now
what about sinl + cos when 'double == long double'?  What I'm after
is rather than going with sth like your patch use the original
builtin code to derive the canonical C ABI type, sort-of a "reverse"
mathfn_built_in.  In execute_cse_sincos_1 we have the

      switch (gimple_call_combined_fn (use_stmt))
        {
        CASE_CFN_COS:
          seen_cos |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
          break;

        CASE_CFN_SIN:
          seen_sin |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
          break;

        CASE_CFN_CEXPI:
          seen_cexpi |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
          break;

        default:;
        }

switch so we _do_ have an idea what builtins we call and thus
we could add a

tree
mathfn_type (combined_fn fn)
{
  switch (fn)
    {
    case all-double-typed-fns:
       return double_type_node;
    case ...:
...
}

function that might prove useful in other places we're trying to find
a "matching" alternate builtin function?  Maybe this function can
also simply look at the implicit/explicit defined decls but at least
for the case of lrint using the return value will be misleading.

Richard.


> --
> Alexandre Oliva, happy hacker
> https://FSFLA.org/blogs/lxo/
> Free Software Activist
> GNU Toolchain Engineer

Reply via email to