Bug 98925 - Extend ipa-prop to handle return functions for slot optimization
Summary: Extend ipa-prop to handle return functions for slot optimization
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: ipa (show other bugs)
Version: 11.0
: P3 enhancement
Target Milestone: ---
Assignee: Jan Hubicka
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2021-02-01 18:37 UTC by Sergei Trofimovich
Modified: 2024-09-21 00:34 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-11-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2021-02-01 18:37:46 UTC
Moving out https://gcc.gnu.org/PR98499#c9 to a separate enhancement PR:

Right now analyze_ssa_name_flags() does not perform detailed modref analysis of return slot optimization and falls back to conservative assumption:

    analyze_ssa_name_flags()

          /* Return slot optiomization would require bit of propagation;
             give up for now.  */
          if (gimple_call_return_slot_opt_p (call)
              && gimple_call_lhs (call) != NULL_TREE
              && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call))))
            {
              if (dump_file)
                fprintf (dump_file, "%*s  Unhandled return slot opt\n",
                         depth * 4, "");
              lattice[index].merge (0);
            }

I don't know what would be a good test for it.

If I don't overstimate modref and alias analysis   destructor should disappear completely in the example below (from https://gcc.gnu.org/PR98499#c4):

struct string {
  char * _M_buf;
  // local store
  char _M_local_buf[16];

  __attribute__((noinline)) string() : _M_buf(_M_local_buf) {}

  ~string() {
    if (_M_buf != _M_local_buf)
      __builtin_trap();
  }

  string(const string &__str); // no copies
};

// main.cc

__attribute__((noinline)) static string dir_name() { return string(); }
class Importer {
  string base_path;

public:
  __attribute__((noinline)) Importer() : base_path (dir_name()) {}
};

int main() {
  Importer imp;
}
Comment 1 Jan Hubicka 2021-02-01 19:11:17 UTC
> If I don't overstimate modref and alias analysis   destructor should disappear
> completely in the example below (from https://gcc.gnu.org/PR98499#c4):
> 
> struct string {
>   char * _M_buf;
>   // local store
>   char _M_local_buf[16];
> 
>   __attribute__((noinline)) string() : _M_buf(_M_local_buf) {}
> 
>   ~string() {
>     if (_M_buf != _M_local_buf)
>       __builtin_trap();
>   }
> 
>   string(const string &__str); // no copies
> };

To see that _M_buf == _M_local_buf at the destruction time would require
tracking the aggregate alue from the inlinined constructor to destructor
which is something fitting to ipa-prop.

Modref can helip in case _M_buf is initialized to NULL.  In that case
the address of return value would be non-escaping and we could optimize
the if condition to true (is we did incorrectly before).

I have WIP patch for this and will discuss with Martin Jambor the jump
functions for return values.

Thanks!
Honza
Comment 2 Jan Hubicka 2021-11-07 22:17:38 UTC
Modref now handles return slots.
However as discussed in earlier comment we also need return function in ipa-prop to propagate constant from callee to caller. So I am keeping the PR to track this (I think it would be useful especially for offlined ctors)
Comment 3 Jan Hubicka 2023-11-22 13:24:45 UTC
Return value range propagation was added in r:53ba8d669550d3a1f809048428b97ca607f95cf5

however it works on scalar return values only for now. Extending it to aggregates is a logical next step and should not be terribly hard.

The code also misses logic for IPA streaming so it works only in ealry and late opts.