public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-2353] Implement EAF_NOT_RETURNED tracking in ipa-modref
@ 2021-07-16 12:22 Jan Hubicka
0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-07-16 12:22 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8da8ed435e9f01b37bf4ee57fa62509d44121c7d
commit r12-2353-g8da8ed435e9f01b37bf4ee57fa62509d44121c7d
Author: Jan Hubicka <jh@suse.cz>
Date: Fri Jul 16 14:21:29 2021 +0200
Implement EAF_NOT_RETURNED tracking in ipa-modref
2021-07-16 Jan Hubicka <hubicka@ucw.cz>
* ipa-modref.c (struct escape_entry): Use eaf_fleags_t.
(dump_eaf_flags): Dump EAF_NOT_RETURNED
(eaf_flags_useful_p): Use eaf_fleags_t; handle const functions
and EAF_NOT_RETURNED.
(modref_summary::useful_p): Likewise.
(modref_summary_lto::useful_p): Likewise.
(struct) modref_summary_lto: Use eaf_fleags_t.
(deref_flags): Handle EAF_NOT_RETURNED.
(struct escape_point): Use min_flags.
(modref_lattice::init): Add EAF_NOT_RETURNED.
(merge_call_lhs_flags): Ignore EAF_NOT_RETURNED functions
(analyze_ssa_name_flags): Clear EAF_NOT_RETURNED on return;
handle call flags.
(analyze_parms): Also analyze const functions; update conition on
flags usefulness.
(modref_write): Update streaming.
(read_section): Update streaming.
(remap_arg_flags): Use eaf_flags_t.
(modref_merge_call_site_flags): Hanlde EAF_NOT_RETURNED.
* ipa-modref.h: (eaf_flags_t): New typedef.
(struct modref_summary): Use eaf_flags_t.
* tree-core.h (EAF_NOT_RETURNED): New constant.
Diff:
---
gcc/ipa-modref.c | 71 ++++++++++++++++++++++++++++++++++++++------------------
gcc/ipa-modref.h | 3 ++-
gcc/tree-core.h | 3 +++
3 files changed, 54 insertions(+), 23 deletions(-)
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index d5a8332fb55..7b849c1cd7b 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -86,6 +86,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "tree-ssanames.h"
+
namespace {
/* We record fnspec specifiers for call edges since they depends on actual
@@ -135,7 +136,7 @@ struct escape_entry
/* Argument it escapes to. */
unsigned int arg;
/* Minimal flags known about the argument. */
- char min_flags;
+ eaf_flags_t min_flags;
/* Does it escape directly or indirectly? */
bool direct;
};
@@ -155,6 +156,8 @@ dump_eaf_flags (FILE *out, int flags, bool newline = true)
fprintf (out, " nodirectescape");
if (flags & EAF_UNUSED)
fprintf (out, " unused");
+ if (flags & EAF_NOT_RETURNED)
+ fprintf (out, " not_returned");
if (newline)
fprintf (out, "\n");
}
@@ -278,12 +281,17 @@ modref_summary::~modref_summary ()
/* Return true if FLAGS holds some useful information. */
static bool
-eaf_flags_useful_p (vec <unsigned char> &flags, int ecf_flags)
+eaf_flags_useful_p (vec <eaf_flags_t> &flags, int ecf_flags)
{
for (unsigned i = 0; i < flags.length (); i++)
- if (ecf_flags & ECF_PURE)
+ if (ecf_flags & ECF_CONST)
{
- if (flags[i] & (EAF_UNUSED | EAF_DIRECT))
+ if (flags[i] & (EAF_UNUSED | EAF_NOT_RETURNED))
+ return true;
+ }
+ else if (ecf_flags & ECF_PURE)
+ {
+ if (flags[i] & (EAF_UNUSED | EAF_DIRECT | EAF_NOT_RETURNED))
return true;
}
else
@@ -300,13 +308,15 @@ eaf_flags_useful_p (vec <unsigned char> &flags, int ecf_flags)
bool
modref_summary::useful_p (int ecf_flags, bool check_flags)
{
- if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
+ if (ecf_flags & ECF_NOVOPS)
return false;
if (arg_flags.length () && !check_flags)
return true;
if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags))
return true;
arg_flags.release ();
+ if (ecf_flags & ECF_CONST)
+ return false;
if (loads && !loads->every_base)
return true;
if (ecf_flags & ECF_PURE)
@@ -325,7 +335,7 @@ struct GTY(()) modref_summary_lto
more verbose and thus more likely to hit the limits. */
modref_records_lto *loads;
modref_records_lto *stores;
- auto_vec<unsigned char> GTY((skip)) arg_flags;
+ auto_vec<eaf_flags_t> GTY((skip)) arg_flags;
bool writes_errno;
modref_summary_lto ();
@@ -356,13 +366,15 @@ modref_summary_lto::~modref_summary_lto ()
bool
modref_summary_lto::useful_p (int ecf_flags, bool check_flags)
{
- if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
+ if (ecf_flags & ECF_NOVOPS)
return false;
if (arg_flags.length () && !check_flags)
return true;
if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags))
return true;
arg_flags.release ();
+ if (ecf_flags & ECF_CONST)
+ return false;
if (loads && !loads->every_base)
return true;
if (ecf_flags & ECF_PURE)
@@ -1317,6 +1329,8 @@ deref_flags (int flags, bool ignore_stores)
if ((flags & EAF_NOESCAPE) || ignore_stores)
ret |= EAF_NOESCAPE;
}
+ if (flags & EAF_NOT_RETURNED)
+ ret |= EAF_NOT_RETURNED;
return ret;
}
@@ -1332,7 +1346,7 @@ struct escape_point
int arg;
/* Flags already known about the argument (this can save us from recording
esape points if local analysis did good job already). */
- char min_flags;
+ eaf_flags_t min_flags;
/* Does value escape directly or indiretly? */
bool direct;
};
@@ -1366,7 +1380,7 @@ void
modref_lattice::init ()
{
flags = EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE | EAF_UNUSED
- | EAF_NODIRECTESCAPE;
+ | EAF_NODIRECTESCAPE | EAF_NOT_RETURNED;
open = true;
known = false;
}
@@ -1539,6 +1553,9 @@ merge_call_lhs_flags (gcall *call, int arg, int index, bool deref,
&& (flags & ERF_RETURN_ARG_MASK) != arg)
return;
+ if (gimple_call_arg_flags (call, arg) & (EAF_NOT_RETURNED | EAF_UNUSED))
+ return;
+
/* If return value is SSA name determine its flags. */
if (TREE_CODE (gimple_call_lhs (call)) == SSA_NAME)
{
@@ -1613,9 +1630,12 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
if (greturn *ret = dyn_cast <greturn *> (use_stmt))
{
if (gimple_return_retval (ret) == name)
- lattice[index].merge (~EAF_UNUSED);
+ lattice[index].merge (~(EAF_UNUSED | EAF_NOT_RETURNED));
else if (memory_access_to (gimple_return_retval (ret), name))
- lattice[index].merge_direct_load ();
+ {
+ lattice[index].merge_direct_load ();
+ lattice[index].merge (~EAF_NOT_RETURNED);
+ }
}
/* Account for LHS store, arg loads and flags from callee function. */
else if (gcall *call = dyn_cast <gcall *> (use_stmt))
@@ -1666,7 +1686,8 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
{
if (!(ecf_flags & (ECF_CONST | ECF_NOVOPS)))
{
- int call_flags = gimple_call_arg_flags (call, i);
+ int call_flags = gimple_call_arg_flags (call, i)
+ | EAF_NOT_RETURNED;
if (ignore_stores)
call_flags |= EAF_NOCLOBBER | EAF_NOESCAPE
| EAF_NODIRECTESCAPE;
@@ -1689,7 +1710,8 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
else
{
int call_flags = deref_flags
- (gimple_call_arg_flags (call, i), ignore_stores);
+ (gimple_call_arg_flags (call, i)
+ | EAF_NOT_RETURNED, ignore_stores);
if (!record_ipa)
lattice[index].merge (call_flags);
else
@@ -1819,8 +1841,8 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
unsigned int count = 0;
int ecf_flags = flags_from_decl_or_type (current_function_decl);
- /* For const functions we have nothing to gain by EAF flags. */
- if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
+ /* For novops functions we have nothing to gain by EAF flags. */
+ if (ecf_flags & ECF_NOVOPS)
return;
for (tree parm = DECL_ARGUMENTS (current_function_decl); parm;
@@ -1863,7 +1885,11 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
/* For pure functions we have implicit NOCLOBBER
and NOESCAPE. */
if (ecf_flags & ECF_PURE)
- flags &= ~(EAF_NOCLOBBER | EAF_NOESCAPE | EAF_NODIRECTESCAPE);
+ flags &= (EAF_UNUSED | EAF_DIRECT | EAF_NOT_RETURNED);
+ /* Only useful flags for const function are EAF_NOT_RETURNED and
+ EAF_UNUSED. */
+ if (ecf_flags & ECF_CONST)
+ flags &= (EAF_UNUSED | EAF_NOT_RETURNED);
if (flags)
{
@@ -2518,7 +2544,7 @@ modref_write ()
streamer_write_uhwi (ob, r->arg_flags.length ());
for (unsigned int i = 0; i < r->arg_flags.length (); i++)
- streamer_write_char_stream (ob->main_stream, r->arg_flags[i]);
+ streamer_write_uhwi (ob, r->arg_flags[i]);
write_modref_records (r->loads, ob);
write_modref_records (r->stores, ob);
@@ -2609,7 +2635,7 @@ read_section (struct lto_file_decl_data *file_data, const char *data,
modref_sum_lto->arg_flags.reserve_exact (args);
for (unsigned int i = 0; i < args; i++)
{
- unsigned char flags = streamer_read_uchar (&ib);
+ eaf_flags_t flags = streamer_read_uhwi (&ib);
if (modref_sum)
modref_sum->arg_flags.quick_push (flags);
if (modref_sum_lto)
@@ -2713,9 +2739,9 @@ modref_read (void)
/* Recompute arg_flags for param adjustments in INFO. */
static void
-remap_arg_flags (auto_vec <unsigned char> &arg_flags, clone_info *info)
+remap_arg_flags (auto_vec <eaf_flags_t> &arg_flags, clone_info *info)
{
- auto_vec<unsigned char> old = arg_flags.copy ();
+ auto_vec<eaf_flags_t> old = arg_flags.copy ();
int max = -1;
size_t i;
ipa_adjusted_param *p;
@@ -3665,8 +3691,9 @@ modref_merge_call_site_flags (escape_summary *sum,
flags |= EAF_NOESCAPE | EAF_NOCLOBBER | EAF_NODIRECTESCAPE;
flags_lto |= EAF_NOESCAPE | EAF_NOCLOBBER | EAF_NODIRECTESCAPE;
}
- flags |= ee->min_flags;
- flags_lto |= ee->min_flags;
+ /* Returning the value is already accounted to at local propagation. */
+ flags |= ee->min_flags | EAF_NOT_RETURNED;
+ flags_lto |= ee->min_flags | EAF_NOT_RETURNED;
if (!(flags & EAF_UNUSED)
&& cur_summary && ee->parm_index < cur_summary->arg_flags.length ())
{
diff --git a/gcc/ipa-modref.h b/gcc/ipa-modref.h
index 8af62b30d5e..498cc2414ac 100644
--- a/gcc/ipa-modref.h
+++ b/gcc/ipa-modref.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#define IPA_MODREF_H
typedef modref_tree <alias_set_type> modref_records;
+typedef unsigned short eaf_flags_t;
/* Single function summary. */
@@ -29,7 +30,7 @@ struct GTY(()) modref_summary
/* Load and stores in function (transitively closed to all callees) */
modref_records *loads;
modref_records *stores;
- auto_vec<unsigned char> GTY((skip)) arg_flags;
+ auto_vec<eaf_flags_t> GTY((skip)) arg_flags;
bool writes_errno;
modref_summary ();
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 23cd289bcc3..93916090432 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -114,6 +114,9 @@ struct die_struct;
referenced by it can escape. */
#define EAF_NODIRECTESCAPE (1 << 4)
+/* Nonzero if the argument does not escape to return value. */
+#define EAF_NOT_RETURNED (1 << 8)
+
/* Call return flags. */
/* Mask for the argument number that is returned. Lower two bits of
the return flags, encodes argument slots zero to three. */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-07-16 12:22 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-16 12:22 [gcc r12-2353] Implement EAF_NOT_RETURNED tracking in ipa-modref Jan Hubicka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).