Re: [PATCH v3] rs6000: Fix some issues in rs6000_can_inline_p [PR102059]

2022-02-08 Thread Bill Schmidt via Gcc-patches
Hi!

>From some discussion today, I think we want to limit the scope of
this patch to just the power8-fusion flag that's causing trouble for
now, given stage 4.  We've talked about making power8-fusion a do-
nothing flag, since it doesn't add much benefit now and probably
shouldn't be a separate flag anyway.  Having it as a meaningless
flag makes it more palatable to add an exception for it in the
inlining path.

Others, feel free to weigh in.

Thanks,
Bill

On 1/5/22 1:34 AM, Kewen.Lin wrote:
> Hi,
>
> This patch is to fix the inconsistent behaviors for non-LTO mode
> and LTO mode.  As Martin pointed out, currently the function
> rs6000_can_inline_p simply makes it inlinable if callee_tree is
> NULL, but it's unexpected, we should use the command line options
> from target_option_default_node as default.
>
> It replaces rs6000_isa_flags with target_option_default_node when
> caller_tree is NULL since it's more straightforward and doesn't
> suffer from some bug not to keep rs6000_isa_flags as default.
>
> It also extends the scope of the check for the case that callee
> has explicit set options, inlining in test case pr102059-5.c can
> happen unexpectedly before, it's fixed accordingly.
>
> As Richi/Mike pointed out, some tuning flags like MASK_P8_FUSION
> can be neglected for always inlining, this patch also takes some
> flags when the callee is attributed by always_inline.
>
> v1: https://gcc.gnu.org/pipermail/gcc-patches/2021-September/578552.html
> v2: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586112.html
>
> This patch is one re-post of this updated version[1] and also
> rebased and adjusted on top of the related commit r12-6219.
>
> Bootstrapped and regtested on powerpc64-linux-gnu P8 and
> powerpc64le-linux-gnu P9 and P10.
>
> Is it ok for trunk?
>
> [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586296.html
>
> BR,
> Kewen
> -
> gcc/ChangeLog:
>
>   PR target/102059
>   * config/rs6000/rs6000.c (rs6000_can_inline_p): Adjust with
>   target_option_default_node and consider always_inline_safe flags.
>
> gcc/testsuite/ChangeLog:
>
>   PR target/102059
>   * gcc.target/powerpc/pr102059-4.c: New test.
>   * gcc.target/powerpc/pr102059-5.c: New test.
>   * gcc.target/powerpc/pr102059-6.c: New test.
>   * gcc.target/powerpc/pr102059-7.c: New test.
>   * gcc.target/powerpc/pr102059-8.c: New test.
>   * gcc.dg/lto/pr102059-1_0.c: Remove unneeded option.
>
>


Re: [PATCH v3] rs6000: Fix some issues in rs6000_can_inline_p [PR102059]

2022-02-07 Thread Kewen.Lin via Gcc-patches
Hi Segher,

Thanks for the comments!

on 2022/2/7 下午3:53, Segher Boessenkool wrote:
> Hi!
> 
> On Wed, Jan 05, 2022 at 03:34:41PM +0800, Kewen.Lin wrote:
>> This patch is to fix the inconsistent behaviors for non-LTO mode
>> and LTO mode.  As Martin pointed out, currently the function
>> rs6000_can_inline_p simply makes it inlinable if callee_tree is
>> NULL, but it's unexpected, we should use the command line options
>> from target_option_default_node as default.
> 
>> --- a/gcc/config/rs6000/rs6000.c
>> +++ b/gcc/config/rs6000/rs6000.c
>> @@ -25379,55 +25379,87 @@ rs6000_update_ipa_fn_target_info (unsigned int 
>> , const gimple *stmt)
>>  static bool
>>  rs6000_can_inline_p (tree caller, tree callee)
>>  {
>> -  bool ret = false;
>>tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
>>tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
>>  
>> -  /* If the callee has no option attributes, then it is ok to inline.  */
>> +  /* If the caller/callee has option attributes, then use them.
>> + Otherwise, use the command line options.  */
>>if (!callee_tree)
>> -ret = true;
>> -
>> -  else
>> -{
>> -  HOST_WIDE_INT caller_isa;
>> -  struct cl_target_option *callee_opts = TREE_TARGET_OPTION 
>> (callee_tree);
>> -  HOST_WIDE_INT callee_isa = callee_opts->x_rs6000_isa_flags;
>> -  HOST_WIDE_INT explicit_isa = callee_opts->x_rs6000_isa_flags_explicit;
>> +callee_tree = target_option_default_node;
>> +  if (!caller_tree)
>> +caller_tree = target_option_default_node;
>> +
>> +  struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
>> +  struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
>> +  HOST_WIDE_INT caller_isa = caller_opts->x_rs6000_isa_flags;
>> +  HOST_WIDE_INT callee_isa = callee_opts->x_rs6000_isa_flags;
>> +
>> +  bool always_inline
>> += DECL_DISREGARD_INLINE_LIMITS (callee)
>> +  && lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee));
>> +
>> +  /* Some features can be tolerated for always inlines.  */
>> +  unsigned HOST_WIDE_INT always_inline_safe_mask
>> +/* Fusion option masks.  */
>> += OPTION_MASK_P8_FUSION | OPTION_MASK_P10_FUSION
>> +  | OPTION_MASK_P8_FUSION_SIGN | OPTION_MASK_P10_FUSION
>> +  | OPTION_MASK_P10_FUSION_LD_CMPI | OPTION_MASK_P10_FUSION_2LOGICAL
>> +  | OPTION_MASK_P10_FUSION_LOGADD | OPTION_MASK_P10_FUSION_ADDLOG
>> +  | OPTION_MASK_P10_FUSION_2ADD
>> +  /* Like fusion, some option masks which are just for optimization.  */
>> +  | OPTION_MASK_SAVE_TOC_INDIRECT | OPTION_MASK_PCREL_OPT;
> 
> Why is this?  I would expect only two or three options to be *not* safe!
> 
> You have a strange mix of internal options (the FUSION* things) and some
> other options that do not change the semantics at all.  But this is true
> for almost *all* options we have!  What would not allow a callee that is
> allowed to use some newer ISA's insns into a caller that does not allow
> them?  Both when it ends up using those insns and when it does not, the
> end result is valid.  If there is something internal to GCC that causes
> ICEs we need to do something about *that*!
> 

The reason why I used these options is that all of them are mainly for
performance purpose, they are not to control if some insns are available
to generate.  Sorry that if they look strangely mixed.

IMHO it's not "true for almost *all* options we have".  For the
options at the beginning of rs6000 options manual page.

  -mpowerpc-gpopt  [guarding bifs]
  -mpowerpc-gfxopt [guarding bifs]
  -mpowerpc64
  -mmfcrf
  -mpopcntb  [guarding bifs]
  -mpopcntd  [guarding bifs]
  -mfprnd
  -mcmpb  [guarding bifs]
  -mhard-dfp  [guarding bifs]
  ...

Imagining that if the callee has some built-in functions or some inline
assembly which requires the related hardware feature provided, I think we
shouldn't claim they are safe even with always_inline.  For example, for
built-in functions, there will be some error messages without related
features supported.

>> +  /* Some features are totally safe for inlining (or always inlines),
>> + let's exclude them from the following checkings.  */
>> +  HOST_WIDE_INT safe_mask = always_inline ? always_inline_safe_mask : 0;
>> +  cgraph_node *callee_node = cgraph_node::get (callee);
>> +  if (ipa_fn_summaries && ipa_fn_summaries->get (callee_node) != NULL)
>> +{
>> +  unsigned int info = ipa_fn_summaries->get (callee_node)->target_info;
>> +  if ((info & RS6000_FN_TARGET_INFO_HTM) == 0)
>> +safe_mask |= OPTION_MASK_HTM;
>> +}
> 
> always_inline means *always*.  If the compiler cannot do this it should
> not, but then error; in all other cases it should do it.
> 

Maybe there are some user cases we want to tolerate?  Like this PR?

> This patch is pretty much equal to not allowing any inlining if the
> caller and callee have not identical compilation options.  So sure, it
> causes us to not have any unwanted inlining, but it does 

Re: [PATCH v3] rs6000: Fix some issues in rs6000_can_inline_p [PR102059]

2022-02-06 Thread Segher Boessenkool
Hi!

On Wed, Jan 05, 2022 at 03:34:41PM +0800, Kewen.Lin wrote:
> This patch is to fix the inconsistent behaviors for non-LTO mode
> and LTO mode.  As Martin pointed out, currently the function
> rs6000_can_inline_p simply makes it inlinable if callee_tree is
> NULL, but it's unexpected, we should use the command line options
> from target_option_default_node as default.

> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -25379,55 +25379,87 @@ rs6000_update_ipa_fn_target_info (unsigned int 
> , const gimple *stmt)
>  static bool
>  rs6000_can_inline_p (tree caller, tree callee)
>  {
> -  bool ret = false;
>tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
>tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
>  
> -  /* If the callee has no option attributes, then it is ok to inline.  */
> +  /* If the caller/callee has option attributes, then use them.
> + Otherwise, use the command line options.  */
>if (!callee_tree)
> -ret = true;
> -
> -  else
> -{
> -  HOST_WIDE_INT caller_isa;
> -  struct cl_target_option *callee_opts = TREE_TARGET_OPTION 
> (callee_tree);
> -  HOST_WIDE_INT callee_isa = callee_opts->x_rs6000_isa_flags;
> -  HOST_WIDE_INT explicit_isa = callee_opts->x_rs6000_isa_flags_explicit;
> +callee_tree = target_option_default_node;
> +  if (!caller_tree)
> +caller_tree = target_option_default_node;
> +
> +  struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
> +  struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
> +  HOST_WIDE_INT caller_isa = caller_opts->x_rs6000_isa_flags;
> +  HOST_WIDE_INT callee_isa = callee_opts->x_rs6000_isa_flags;
> +
> +  bool always_inline
> += DECL_DISREGARD_INLINE_LIMITS (callee)
> +  && lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee));
> +
> +  /* Some features can be tolerated for always inlines.  */
> +  unsigned HOST_WIDE_INT always_inline_safe_mask
> +/* Fusion option masks.  */
> += OPTION_MASK_P8_FUSION | OPTION_MASK_P10_FUSION
> +  | OPTION_MASK_P8_FUSION_SIGN | OPTION_MASK_P10_FUSION
> +  | OPTION_MASK_P10_FUSION_LD_CMPI | OPTION_MASK_P10_FUSION_2LOGICAL
> +  | OPTION_MASK_P10_FUSION_LOGADD | OPTION_MASK_P10_FUSION_ADDLOG
> +  | OPTION_MASK_P10_FUSION_2ADD
> +  /* Like fusion, some option masks which are just for optimization.  */
> +  | OPTION_MASK_SAVE_TOC_INDIRECT | OPTION_MASK_PCREL_OPT;

Why is this?  I would expect only two or three options to be *not* safe!

You have a strange mix of internal options (the FUSION* things) and some
other options that do not change the semantics at all.  But this is true
for almost *all* options we have!  What would not allow a callee that is
allowed to use some newer ISA's insns into a caller that does not allow
them?  Both when it ends up using those insns and when it does not, the
end result is valid.  If there is something internal to GCC that causes
ICEs we need to do something about *that*!

> +  /* Some features are totally safe for inlining (or always inlines),
> + let's exclude them from the following checkings.  */
> +  HOST_WIDE_INT safe_mask = always_inline ? always_inline_safe_mask : 0;
> +  cgraph_node *callee_node = cgraph_node::get (callee);
> +  if (ipa_fn_summaries && ipa_fn_summaries->get (callee_node) != NULL)
> +{
> +  unsigned int info = ipa_fn_summaries->get (callee_node)->target_info;
> +  if ((info & RS6000_FN_TARGET_INFO_HTM) == 0)
> + safe_mask |= OPTION_MASK_HTM;
> +}

always_inline means *always*.  If the compiler cannot do this it should
not, but then error; in all other cases it should do it.

This patch is pretty much equal to not allowing any inlining if the
caller and callee have not identical compilation options.  So sure, it
causes us to not have any unwanted inlining, but it does that by
preventing all other inlining at the same time.


Segher


PING^3 [PATCH v3] rs6000: Fix some issues in rs6000_can_inline_p [PR102059]

2022-02-06 Thread Kewen.Lin via Gcc-patches
Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587635.html

BR,
Kewen

>> on 2022/1/5 下午3:34, Kewen.Lin via Gcc-patches wrote:
>>> Hi,
>>>
>>> This patch is to fix the inconsistent behaviors for non-LTO mode
>>> and LTO mode.  As Martin pointed out, currently the function
>>> rs6000_can_inline_p simply makes it inlinable if callee_tree is
>>> NULL, but it's unexpected, we should use the command line options
>>> from target_option_default_node as default.
>>>
>>> It replaces rs6000_isa_flags with target_option_default_node when
>>> caller_tree is NULL since it's more straightforward and doesn't
>>> suffer from some bug not to keep rs6000_isa_flags as default.
>>>
>>> It also extends the scope of the check for the case that callee
>>> has explicit set options, inlining in test case pr102059-5.c can
>>> happen unexpectedly before, it's fixed accordingly.
>>>
>>> As Richi/Mike pointed out, some tuning flags like MASK_P8_FUSION
>>> can be neglected for always inlining, this patch also takes some
>>> flags when the callee is attributed by always_inline.
>>>
>>> v1: https://gcc.gnu.org/pipermail/gcc-patches/2021-September/578552.html
>>> v2: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586112.html
>>>
>>> This patch is one re-post of this updated version[1] and also
>>> rebased and adjusted on top of the related commit r12-6219.
>>>
>>> Bootstrapped and regtested on powerpc64-linux-gnu P8 and
>>> powerpc64le-linux-gnu P9 and P10.
>>>
>>> Is it ok for trunk?
>>>
>>> [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586296.html
>>>
>>> BR,
>>> Kewen
>>> -
>>> gcc/ChangeLog:
>>>
>>> PR target/102059
>>> * config/rs6000/rs6000.c (rs6000_can_inline_p): Adjust with
>>> target_option_default_node and consider always_inline_safe flags.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> PR target/102059
>>> * gcc.target/powerpc/pr102059-4.c: New test.
>>> * gcc.target/powerpc/pr102059-5.c: New test.
>>> * gcc.target/powerpc/pr102059-6.c: New test.
>>> * gcc.target/powerpc/pr102059-7.c: New test.
>>> * gcc.target/powerpc/pr102059-8.c: New test.
>>> * gcc.dg/lto/pr102059-1_0.c: Remove unneeded option.
>>>
>>>


PING^2 [PATCH v3] rs6000: Fix some issues in rs6000_can_inline_p [PR102059]

2022-01-25 Thread Kewen.Lin via Gcc-patches
Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587635.html

BR,
Kewen

> 
> on 2022/1/5 下午3:34, Kewen.Lin via Gcc-patches wrote:
>> Hi,
>>
>> This patch is to fix the inconsistent behaviors for non-LTO mode
>> and LTO mode.  As Martin pointed out, currently the function
>> rs6000_can_inline_p simply makes it inlinable if callee_tree is
>> NULL, but it's unexpected, we should use the command line options
>> from target_option_default_node as default.
>>
>> It replaces rs6000_isa_flags with target_option_default_node when
>> caller_tree is NULL since it's more straightforward and doesn't
>> suffer from some bug not to keep rs6000_isa_flags as default.
>>
>> It also extends the scope of the check for the case that callee
>> has explicit set options, inlining in test case pr102059-5.c can
>> happen unexpectedly before, it's fixed accordingly.
>>
>> As Richi/Mike pointed out, some tuning flags like MASK_P8_FUSION
>> can be neglected for always inlining, this patch also takes some
>> flags when the callee is attributed by always_inline.
>>
>> v1: https://gcc.gnu.org/pipermail/gcc-patches/2021-September/578552.html
>> v2: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586112.html
>>
>> This patch is one re-post of this updated version[1] and also
>> rebased and adjusted on top of the related commit r12-6219.
>>
>> Bootstrapped and regtested on powerpc64-linux-gnu P8 and
>> powerpc64le-linux-gnu P9 and P10.
>>
>> Is it ok for trunk?
>>
>> [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586296.html
>>
>> BR,
>> Kewen
>> -
>> gcc/ChangeLog:
>>
>>  PR target/102059
>>  * config/rs6000/rs6000.c (rs6000_can_inline_p): Adjust with
>>  target_option_default_node and consider always_inline_safe flags.
>>
>> gcc/testsuite/ChangeLog:
>>
>>  PR target/102059
>>  * gcc.target/powerpc/pr102059-4.c: New test.
>>  * gcc.target/powerpc/pr102059-5.c: New test.
>>  * gcc.target/powerpc/pr102059-6.c: New test.
>>  * gcc.target/powerpc/pr102059-7.c: New test.
>>  * gcc.target/powerpc/pr102059-8.c: New test.
>>  * gcc.dg/lto/pr102059-1_0.c: Remove unneeded option.
>>
>>
> 



PING^1 [PATCH v3] rs6000: Fix some issues in rs6000_can_inline_p [PR102059]

2022-01-18 Thread Kewen.Lin via Gcc-patches
Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587635.html

BR,
Kewen

on 2022/1/5 下午3:34, Kewen.Lin via Gcc-patches wrote:
> Hi,
> 
> This patch is to fix the inconsistent behaviors for non-LTO mode
> and LTO mode.  As Martin pointed out, currently the function
> rs6000_can_inline_p simply makes it inlinable if callee_tree is
> NULL, but it's unexpected, we should use the command line options
> from target_option_default_node as default.
> 
> It replaces rs6000_isa_flags with target_option_default_node when
> caller_tree is NULL since it's more straightforward and doesn't
> suffer from some bug not to keep rs6000_isa_flags as default.
> 
> It also extends the scope of the check for the case that callee
> has explicit set options, inlining in test case pr102059-5.c can
> happen unexpectedly before, it's fixed accordingly.
> 
> As Richi/Mike pointed out, some tuning flags like MASK_P8_FUSION
> can be neglected for always inlining, this patch also takes some
> flags when the callee is attributed by always_inline.
> 
> v1: https://gcc.gnu.org/pipermail/gcc-patches/2021-September/578552.html
> v2: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586112.html
> 
> This patch is one re-post of this updated version[1] and also
> rebased and adjusted on top of the related commit r12-6219.
> 
> Bootstrapped and regtested on powerpc64-linux-gnu P8 and
> powerpc64le-linux-gnu P9 and P10.
> 
> Is it ok for trunk?
> 
> [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586296.html
> 
> BR,
> Kewen
> -
> gcc/ChangeLog:
> 
>   PR target/102059
>   * config/rs6000/rs6000.c (rs6000_can_inline_p): Adjust with
>   target_option_default_node and consider always_inline_safe flags.
> 
> gcc/testsuite/ChangeLog:
> 
>   PR target/102059
>   * gcc.target/powerpc/pr102059-4.c: New test.
>   * gcc.target/powerpc/pr102059-5.c: New test.
>   * gcc.target/powerpc/pr102059-6.c: New test.
>   * gcc.target/powerpc/pr102059-7.c: New test.
>   * gcc.target/powerpc/pr102059-8.c: New test.
>   * gcc.dg/lto/pr102059-1_0.c: Remove unneeded option.
> 
> 



[PATCH v3] rs6000: Fix some issues in rs6000_can_inline_p [PR102059]

2022-01-04 Thread Kewen.Lin via Gcc-patches
Hi,

This patch is to fix the inconsistent behaviors for non-LTO mode
and LTO mode.  As Martin pointed out, currently the function
rs6000_can_inline_p simply makes it inlinable if callee_tree is
NULL, but it's unexpected, we should use the command line options
from target_option_default_node as default.

It replaces rs6000_isa_flags with target_option_default_node when
caller_tree is NULL since it's more straightforward and doesn't
suffer from some bug not to keep rs6000_isa_flags as default.

It also extends the scope of the check for the case that callee
has explicit set options, inlining in test case pr102059-5.c can
happen unexpectedly before, it's fixed accordingly.

As Richi/Mike pointed out, some tuning flags like MASK_P8_FUSION
can be neglected for always inlining, this patch also takes some
flags when the callee is attributed by always_inline.

v1: https://gcc.gnu.org/pipermail/gcc-patches/2021-September/578552.html
v2: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586112.html

This patch is one re-post of this updated version[1] and also
rebased and adjusted on top of the related commit r12-6219.

Bootstrapped and regtested on powerpc64-linux-gnu P8 and
powerpc64le-linux-gnu P9 and P10.

Is it ok for trunk?

[1] https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586296.html

BR,
Kewen
-
gcc/ChangeLog:

PR target/102059
* config/rs6000/rs6000.c (rs6000_can_inline_p): Adjust with
target_option_default_node and consider always_inline_safe flags.

gcc/testsuite/ChangeLog:

PR target/102059
* gcc.target/powerpc/pr102059-4.c: New test.
* gcc.target/powerpc/pr102059-5.c: New test.
* gcc.target/powerpc/pr102059-6.c: New test.
* gcc.target/powerpc/pr102059-7.c: New test.
* gcc.target/powerpc/pr102059-8.c: New test.
* gcc.dg/lto/pr102059-1_0.c: Remove unneeded option.


---
 gcc/config/rs6000/rs6000.c| 110 +++---
 gcc/testsuite/gcc.dg/lto/pr102059-1_0.c   |   2 +-
 gcc/testsuite/gcc.target/powerpc/pr102059-4.c |  24 
 gcc/testsuite/gcc.target/powerpc/pr102059-5.c |  20 
 gcc/testsuite/gcc.target/powerpc/pr102059-6.c |  95 +++
 gcc/testsuite/gcc.target/powerpc/pr102059-7.c |  22 
 gcc/testsuite/gcc.target/powerpc/pr102059-8.c |  22 
 7 files changed, 255 insertions(+), 40 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr102059-4.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr102059-5.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr102059-6.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr102059-7.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr102059-8.c

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 7d07b47d9e3..60e131f2191 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -25379,55 +25379,87 @@ rs6000_update_ipa_fn_target_info (unsigned int , 
const gimple *stmt)
 static bool
 rs6000_can_inline_p (tree caller, tree callee)
 {
-  bool ret = false;
   tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
   tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
 
-  /* If the callee has no option attributes, then it is ok to inline.  */
+  /* If the caller/callee has option attributes, then use them.
+ Otherwise, use the command line options.  */
   if (!callee_tree)
-ret = true;
-
-  else
-{
-  HOST_WIDE_INT caller_isa;
-  struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
-  HOST_WIDE_INT callee_isa = callee_opts->x_rs6000_isa_flags;
-  HOST_WIDE_INT explicit_isa = callee_opts->x_rs6000_isa_flags_explicit;
+callee_tree = target_option_default_node;
+  if (!caller_tree)
+caller_tree = target_option_default_node;
+
+  struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
+  struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+  HOST_WIDE_INT caller_isa = caller_opts->x_rs6000_isa_flags;
+  HOST_WIDE_INT callee_isa = callee_opts->x_rs6000_isa_flags;
+
+  bool always_inline
+= DECL_DISREGARD_INLINE_LIMITS (callee)
+  && lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee));
+
+  /* Some features can be tolerated for always inlines.  */
+  unsigned HOST_WIDE_INT always_inline_safe_mask
+/* Fusion option masks.  */
+= OPTION_MASK_P8_FUSION | OPTION_MASK_P10_FUSION
+  | OPTION_MASK_P8_FUSION_SIGN | OPTION_MASK_P10_FUSION
+  | OPTION_MASK_P10_FUSION_LD_CMPI | OPTION_MASK_P10_FUSION_2LOGICAL
+  | OPTION_MASK_P10_FUSION_LOGADD | OPTION_MASK_P10_FUSION_ADDLOG
+  | OPTION_MASK_P10_FUSION_2ADD
+  /* Like fusion, some option masks which are just for optimization.  */
+  | OPTION_MASK_SAVE_TOC_INDIRECT | OPTION_MASK_PCREL_OPT;
+
+  /* Some features are totally safe for inlining (or always inlines),
+ let's exclude them from the following checkings.  */
+  HOST_WIDE_INT safe_mask = always_inline ?