public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2)] Experimental modref changeset
@ 2021-12-09 19:12 Jan Hubicka
0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-12-09 19:12 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:77a13853beb2d782359867954c6c97f8e8e6b3da
commit 77a13853beb2d782359867954c6c97f8e8e6b3da
Author: Jan Hubicka <jh@suse.cz>
Date: Thu Dec 9 20:12:08 2021 +0100
Experimental modref changeset
Diff:
---
gcc/ipa-modref-tree.c | 7 ++-
gcc/ipa-modref-tree.h | 12 +++--
gcc/ipa-modref.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++----
gcc/tree-ssa-alias.c | 36 ++++++++++++++
4 files changed, 172 insertions(+), 14 deletions(-)
diff --git a/gcc/ipa-modref-tree.c b/gcc/ipa-modref-tree.c
index 0671fa76199..47fd929864e 100644
--- a/gcc/ipa-modref-tree.c
+++ b/gcc/ipa-modref-tree.c
@@ -625,7 +625,9 @@ modref_access_node::dump (FILE *out)
{
if (parm_index != MODREF_UNKNOWN_PARM)
{
- if (parm_index >= 0)
+ if (parm_index == MODREF_GLOBAL_MEMORY_PARM)
+ fprintf (out, " Base in global memory");
+ else if (parm_index >= 0)
fprintf (out, " Parm %i", parm_index);
else if (parm_index == MODREF_STATIC_CHAIN_PARM)
fprintf (out, " Static chain");
@@ -655,7 +657,8 @@ modref_access_node::dump (FILE *out)
tree
modref_access_node::get_call_arg (const gcall *stmt) const
{
- if (parm_index == MODREF_UNKNOWN_PARM)
+ if (parm_index == MODREF_UNKNOWN_PARM
+ || parm_index == MODREF_GLOBAL_MEMORY_PARM)
return NULL;
if (parm_index == MODREF_STATIC_CHAIN_PARM)
return gimple_call_chain (stmt);
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 35190c212ca..2145308fda4 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -48,10 +48,12 @@ enum modref_special_parms {
MODREF_UNKNOWN_PARM = -1,
MODREF_STATIC_CHAIN_PARM = -2,
MODREF_RETSLOT_PARM = -3,
+ /* Used for bases that points to memory that escapes from function. */
+ MODREF_GLOBAL_MEMORY_PARM = -4,
/* Used in modref_parm_map to tak references which can be removed
from the summary during summary update since they now points to loca
memory. */
- MODREF_LOCAL_MEMORY_PARM = -4
+ MODREF_LOCAL_MEMORY_PARM = -5
};
/* Modref record accesses relative to function parameters.
@@ -174,6 +176,7 @@ struct GTY((user)) modref_ref_node
in the caller. */
gcc_checking_assert (a.parm_index >= 0
|| a.parm_index == MODREF_STATIC_CHAIN_PARM
+ || a.parm_index == MODREF_GLOBAL_MEMORY_PARM
|| a.parm_index == MODREF_UNKNOWN_PARM);
if (!a.useful_p ())
@@ -580,7 +583,9 @@ struct GTY((user)) modref_tree
if (a.parm_index != MODREF_UNKNOWN_PARM && parm_map)
{
- if (a.parm_index >= (int)parm_map->length ())
+ if (a.parm_index == MODREF_GLOBAL_MEMORY_PARM)
+ ;
+ else if (a.parm_index >= (int)parm_map->length ())
a.parm_index = MODREF_UNKNOWN_PARM;
else
{
@@ -656,7 +661,8 @@ struct GTY((user)) modref_tree
if (ref_node->every_access)
return true;
FOR_EACH_VEC_SAFE_ELT (ref_node->accesses, k, access_node)
- if (access_node->parm_index == MODREF_UNKNOWN_PARM)
+ if (access_node->parm_index == MODREF_UNKNOWN_PARM
+ || access_node->parm_index == MODREF_GLOBAL_MEMORY_PARM)
return true;
}
}
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 9e537b04196..1cf9609e8f3 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -754,7 +754,7 @@ get_modref_function_summary (cgraph_node *func)
we don't want to return anything, even if we have summary for the target
function. */
enum availability avail;
- func = func->function_or_virtual_thunk_symbol
+ func = func->ultimate_alias_target
(&avail, current_function_decl ?
cgraph_node::get (current_function_decl) : NULL);
if (avail <= AVAIL_INTERPOSABLE)
@@ -892,6 +892,8 @@ private:
bool record_access_p (tree);
bool record_unknown_load ();
bool record_unknown_store ();
+ bool record_global_memory_load ();
+ bool record_global_memory_store ();
bool merge_call_side_effects (gimple *, modref_summary *,
cgraph_node *, bool);
modref_access_node get_access_for_fnspec (gcall *, attr_fnspec &,
@@ -1147,6 +1149,41 @@ modref_access_analysis::record_unknown_store ()
return changed;
}
+/* Record unknown load from gloal memory. */
+
+bool
+modref_access_analysis::record_global_memory_load ()
+{
+ bool changed = false;
+ modref_access_node a = {0, -1, -1,
+ 0, MODREF_GLOBAL_MEMORY_PARM, false, 0};
+
+ if (m_summary && !m_summary->loads->every_base)
+ changed |= m_summary->loads->insert (current_function_decl, 0, 0, a, false);
+ if (m_summary_lto && !m_summary_lto->loads->every_base)
+ changed |= m_summary_lto->loads->insert (current_function_decl,
+ 0, 0, a, false);
+ return changed;
+}
+
+/* Record unknown store from gloal memory. */
+
+bool
+modref_access_analysis::record_global_memory_store ()
+{
+ bool changed = false;
+ modref_access_node a = {0, -1, -1,
+ 0, MODREF_GLOBAL_MEMORY_PARM, false, 0};
+
+ if (m_summary && !m_summary->stores->every_base)
+ changed |= m_summary->stores->insert (current_function_decl,
+ 0, 0, a, false);
+ if (m_summary_lto && !m_summary_lto->stores->every_base)
+ changed |= m_summary_lto->stores->insert (current_function_decl,
+ 0, 0, a, false);
+ return changed;
+}
+
/* Merge side effects of call STMT to function with CALLEE_SUMMARY.
Return true if something changed.
If IGNORE_STORES is true, do not merge stores.
@@ -1349,6 +1386,57 @@ modref_access_analysis::get_access_for_fnspec (gcall *call, attr_fnspec &fnspec,
return a;
}
+/* Return true if ARG with EAF flags FLAGS can not make any caller's parameter
+ used even if they are not escaped. */
+
+static bool
+verify_arg (tree arg, int flags)
+{
+ if (flags & EAF_UNUSED)
+ return true;
+ if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE)))
+ return true;
+ if (is_gimple_constant (arg))
+ return true;
+ if (DECL_P (arg) && TREE_READONLY (arg))
+ return true;
+ if (TREE_CODE (arg) == ADDR_EXPR)
+ {
+ tree t = get_base_address (TREE_OPERAND (arg, 0));
+ if (is_gimple_constant (t))
+ return true;
+ if (DECL_P (t)
+ && (TREE_READONLY (t) || TREE_CODE (t) == FUNCTION_DECL))
+ return true;
+ }
+ return false;
+}
+
+/* Return true if STMT may access memory that is pointed to by parameters
+ of caller and which is not seen as an escape by PTA. */
+
+static bool
+may_access_nonescaping_parm_p (gcall *call, int callee_ecf_flags)
+{
+ int implicit_flags = false;
+
+ if (ignore_stores_p (current_function_decl, callee_ecf_flags))
+ implicit_flags |= ignore_stores_eaf_flags;
+ if (callee_ecf_flags & ECF_PURE)
+ implicit_flags |= implicit_pure_eaf_flags;
+ if (callee_ecf_flags & (ECF_CONST | ECF_NOVOPS))
+ implicit_flags |= implicit_const_eaf_flags;
+ if (gimple_call_chain (call)
+ && !verify_arg (gimple_call_chain (call),
+ gimple_call_static_chain_flags (call) | implicit_flags))
+ return true;
+ for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
+ if (!verify_arg (gimple_call_arg (call, i),
+ gimple_call_arg_flags (call, i) | implicit_flags))
+ return true;
+ return false;
+}
+
/* Apply side effects of call STMT to CUR_SUMMARY using FNSPEC.
If IGNORE_STORES is true ignore them.
Return false if no useful summary can be produced. */
@@ -1381,14 +1469,28 @@ modref_access_analysis::process_fnspec (gcall *call)
if (dump_file && gimple_call_builtin_p (call, BUILT_IN_NORMAL))
fprintf (dump_file, " Builtin with no fnspec: %s\n",
IDENTIFIER_POINTER (DECL_NAME (gimple_call_fndecl (call))));
- record_unknown_load ();
if (!ignore_stores_p (current_function_decl, flags))
- record_unknown_store ();
+ {
+ record_global_memory_store ();
+ record_global_memory_load ();
+ }
+ else
+ {
+ if (!may_access_nonescaping_parm_p (call, flags))
+ record_global_memory_load ();
+ else
+ record_unknown_load ();
+ }
return;
}
/* Process fnspec. */
if (fnspec.global_memory_read_p ())
- record_unknown_load ();
+ {
+ if (may_access_nonescaping_parm_p (call, flags))
+ record_unknown_load ();
+ else
+ record_global_memory_load ();
+ }
else
{
for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
@@ -1420,7 +1522,12 @@ modref_access_analysis::process_fnspec (gcall *call)
if (ignore_stores_p (current_function_decl, flags))
return;
if (fnspec.global_memory_written_p ())
- record_unknown_store ();
+ {
+ if (may_access_nonescaping_parm_p (call, flags))
+ record_unknown_store ();
+ else
+ record_global_memory_store ();
+ }
else
{
for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
@@ -1468,6 +1575,12 @@ modref_access_analysis::analyze_call (gcall *stmt)
simplified. */
int flags = gimple_call_flags (stmt);
+ if (dump_file)
+ {
+ fprintf (dump_file, " - Analyzing call:");
+ print_gimple_stmt (dump_file, stmt, 0);
+ }
+
if ((flags & (ECF_CONST | ECF_NOVOPS))
&& !(flags & ECF_LOOPING_CONST_OR_PURE))
{
@@ -4065,7 +4178,7 @@ ignore_edge (struct cgraph_edge *e)
if (!e->inline_failed)
return false;
enum availability avail;
- cgraph_node *callee = e->callee->function_or_virtual_thunk_symbol
+ cgraph_node *callee = e->callee->ultimate_alias_target
(&avail, e->caller);
return (avail <= AVAIL_INTERPOSABLE
@@ -4088,7 +4201,7 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
class ipa_call_summary *es
= ipa_call_summaries->get (callee_edge);
cgraph_node *callee
- = callee_edge->callee->function_or_virtual_thunk_symbol
+ = callee_edge->callee->ultimate_alias_target
(NULL, callee_edge->caller);
caller_parms_info
@@ -4578,7 +4691,7 @@ modref_propagate_in_scc (cgraph_node *component_node)
/* Get the callee and its summary. */
enum availability avail;
- callee = callee_edge->callee->function_or_virtual_thunk_symbol
+ callee = callee_edge->callee->ultimate_alias_target
(&avail, cur);
/* It is not necessary to re-process calls outside of the
@@ -5021,7 +5134,7 @@ modref_propagate_flags_in_scc (cgraph_node *component_node)
/* Get the callee and its summary. */
enum availability avail;
- callee = callee_edge->callee->function_or_virtual_thunk_symbol
+ callee = callee_edge->callee->ultimate_alias_target
(&avail, cur);
/* It is not necessary to re-process calls outside of the
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 3c253e2843f..32cdc4b9590 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2547,6 +2547,30 @@ refs_output_dependent_p (tree store1, tree store2)
return refs_may_alias_p_1 (&r1, &r2, false);
}
+/* Return ture if REF may access global memory. */
+
+bool
+ref_may_access_global_memory_p (ao_ref *ref)
+{
+ if (!ref->ref)
+ return true;
+ tree base = ao_ref_base (ref);
+ if (TREE_CODE (base) == MEM_REF
+ || TREE_CODE (base) == TARGET_MEM_REF)
+ {
+ if (ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0)))
+ return true;
+ }
+ else
+ {
+ if (!auto_var_in_fn_p (base, current_function_decl)
+ || pt_solution_includes (&cfun->gimple_df->escaped,
+ base))
+ return true;
+ }
+ return false;
+}
+
/* Returns true if and only if REF may alias any access stored in TT.
IF TBAA_P is true, use TBAA oracle. */
@@ -2555,6 +2579,7 @@ modref_may_conflict (const gcall *stmt,
modref_tree <alias_set_type> *tt, ao_ref *ref, bool tbaa_p)
{
alias_set_type base_set, ref_set;
+ bool global_memory_ok = false;
if (tt->every_base)
return true;
@@ -2605,6 +2630,17 @@ modref_may_conflict (const gcall *stmt,
if (num_tests >= max_tests)
return true;
+ if (access_node.parm_index == MODREF_GLOBAL_MEMORY_PARM)
+ {
+ if (global_memory_ok)
+ continue;
+ if (ref_may_access_global_memory_p (ref))
+ return true;
+ global_memory_ok = true;
+ num_tests++;
+ continue;
+ }
+
tree arg = access_node.get_call_arg (stmt);
if (!arg)
return true;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-12-09 19:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-09 19:12 [gcc(refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2)] Experimental modref changeset 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).