On Tue, Oct 6, 2020 at 9:21 AM Alexandre Oliva <[email protected]> wrote:
>
> On Oct 6, 2020, Richard Biener <[email protected]> wrote:
>
> > On October 6, 2020 3:15:02 AM GMT+02:00, Alexandre Oliva
> > <[email protected]> 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