On Thu, Apr 22, 2021 at 12:30 PM Jakub Jelinek via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Wed, Apr 21, 2021 at 06:01:07PM -0700, H.J. Lu via Gcc-patches wrote:
> > How about this?
> >
> > @item general_regs_only
> > @cindex @code{general_regs_only} function attribute, x86
> > The @code{general_regs_only} function attribute informs the compiler
> > that the function uses only general purpose registers.  When the
> > compiler inlines a function with the @code{always_inline} attribute,
> > target-specific compilation options may lead to inline failures.
> > The @code{general_regs_only} attribute, if applicable, can be used
> > together with the @code{always_inline} attribute to reduce inlining
> > failure.
>
> I don't really like this attribute.
> It is very specific to what you want to solve and doesn't address the
> general problem, that always_inline means different things in different
> code, and that is a problem for many targets, not just one.
>
> As has been written, in some cases it means inline always, error
> whenever it is called indirectly which can't be optimized into a direct
> call that can be inlined and error whenever the inlining fails for other
> reasons.
>
> Another case, e.g. in the glibc fortify wrappers, is inline always
> when the call is direct or an indirect call can be optimized into a direct
> call and error when the inlining fails, but support indirect calls without
> errors.
>
> Another case, which is most of the x86/aarch64/arm etc. intrinsics, is
> inline always unless there is a target mismatch (roughly what is
> actually implemented).
>
> Because from the always_inline attribute it is impossible to determine which
> one of those it is (for the indirect calls the rule could be
> gnu_inline extern inline means indirect calls are ok, anything else means
> indirect calls are bad), we need new syntax to distinguish those cases.
>
> general_regs_only attribute doesn't seem to be it, e.g. for the glibc
> fortify wrappers cases I don't see why we should forbid using floating point
> in such inlines.
>
> So IMHO we need some new attribute for one of those, or optional parameter
> to always_inline.
>
> For the intrinsic case, ideal would be if we could record which ISA flags
> (or more generally which options) are required and which are not.  Either
> have some syntax where those would be explicitly specified in attribute (but
> frankly that would be a maintainance nightmare), or derive those from
> surrounding pragmas.  Right now we have those wrapped in
> #ifndef __AVX2__
> #pragma GCC push_options
> #pragma GCC target("avx2")
> #define __DISABLE_AVX2__
> #endif /* __AVX2__ */
>
> ...
>
> #ifdef __DISABLE_AVX2__
> #undef __DISABLE_AVX2__
> #pragma GCC pop_options
> #endif /* __DISABLE_AVX2__ */
>
> The question is if the pragma GCC target right now behaves incrementally
> or not, whether
> #pragma GCC target("avx2")
> adds -mavx2 to options if it was missing before and nothing otherwise, or if
> it switches other options off.  If it is incremental, we could e.g. try to
> use the second least significant bit of global_options_set.x_* to mean
> this option has been set explicitly by some surrounding #pragma GCC target.
> The normal tests - global_options_set.x_flag_whatever could still work
> fine because they wouldn't care if the option was explicit from anywhere
> (command line or GCC target or target attribute) and just & 2 would mean
> it was explicit from pragma GCC target; though there is the case of
> bitfields... And then the inlining decision could check the & 2 flags to
> see what is required and what is just from command line.
> Or we can have some other pragma GCC that would be like target but would
> have flags that are explicit (and could e.g. be more restricted, to ISA
> options only, and let those use in addition to #pragma GCC target.

I'm still curious as to what you think will break if always-inline does what
it is documented to do.

Richard.

>         Jakub
>

Reply via email to