public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2)] Improved modref
@ 2021-12-12 10:38 Jan Hubicka
0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-12-12 10:38 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:3e40f07606c458ec6f05c2c9ea04be828bc4aeca
commit 3e40f07606c458ec6f05c2c9ea04be828bc4aeca
Author: Jan Hubicka <jh@suse.cz>
Date: Sat Dec 11 20:48:26 2021 +0100
Improved modref
Diff:
---
gcc/doc/invoke.texi | 8 +++
gcc/ipa-modref-tree.c | 7 ++-
gcc/ipa-modref-tree.h | 21 ++++---
gcc/ipa-modref.c | 161 +++++++++++++++++++++++++++++---------------------
4 files changed, 122 insertions(+), 75 deletions(-)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3bddfbaae6a..cd03fd93c7c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13587,6 +13587,14 @@ The maximum number of backtrack attempts the scheduler should make
when modulo scheduling a loop. Larger values can exponentially increase
compilation time.
+@item max-inline-functions-called-once-loop-depth
+Maximal loop depth of a call considered by inline heuristics that tries to
+inline all functions called once.
+
+@item max-inline-functions-called-once-insns
+Maximal estimated size of functions produced while inlining functions called
+once.
+
@item max-inline-insns-single
Several parameters control the tree inliner used in GCC@. This number sets the
maximum number of instructions (counted in GCC's internal representation) in a
diff --git a/gcc/ipa-modref-tree.c b/gcc/ipa-modref-tree.c
index 47fd929864e..8b86757c632 100644
--- a/gcc/ipa-modref-tree.c
+++ b/gcc/ipa-modref-tree.c
@@ -36,7 +36,8 @@ modref_access_node::operator == (modref_access_node &a) const
{
if (parm_index != a.parm_index)
return false;
- if (parm_index != MODREF_UNKNOWN_PARM)
+ if (parm_index != MODREF_UNKNOWN_PARM
+ && parm_index != MODREF_GLOBAL_MEMORY_PARM)
{
if (parm_offset_known != a.parm_offset_known)
return false;
@@ -613,7 +614,9 @@ modref_access_node::insert (vec <modref_access_node, va_gc> *&accesses,
bool
modref_access_node::range_info_useful_p () const
{
- return parm_index != MODREF_UNKNOWN_PARM && parm_offset_known
+ return parm_index != MODREF_UNKNOWN_PARM
+ && parm_index != MODREF_GLOBAL_MEMORY_PARM
+ && parm_offset_known
&& (known_size_p (size)
|| known_size_p (max_size)
|| known_ge (offset, 0));
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 2145308fda4..4b68475b30e 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -88,6 +88,7 @@ struct GTY(()) modref_access_node
bool useful_for_kill_p () const
{
return parm_offset_known && parm_index != MODREF_UNKNOWN_PARM
+ && parm_index != MODREF_GLOBAL_MEMORY_PARM
&& parm_index != MODREF_RETSLOT_PARM && known_size_p (size)
&& known_eq (max_size, size);
}
@@ -526,7 +527,8 @@ struct GTY((user)) modref_tree
unsigned int max_accesses,
modref_tree <T> *other, vec <modref_parm_map> *parm_map,
modref_parm_map *static_chain_map,
- bool record_accesses)
+ bool record_accesses,
+ bool promote_unknown_to_global = false)
{
if (!other || every_base)
return false;
@@ -581,11 +583,11 @@ struct GTY((user)) modref_tree
{
modref_access_node a = *access_node;
- if (a.parm_index != MODREF_UNKNOWN_PARM && parm_map)
+ if (a.parm_index != MODREF_UNKNOWN_PARM
+ && a.parm_index != MODREF_GLOBAL_MEMORY_PARM
+ && parm_map)
{
- if (a.parm_index == MODREF_GLOBAL_MEMORY_PARM)
- ;
- else if (a.parm_index >= (int)parm_map->length ())
+ if (a.parm_index >= (int)parm_map->length ())
a.parm_index = MODREF_UNKNOWN_PARM;
else
{
@@ -600,6 +602,9 @@ struct GTY((user)) modref_tree
a.parm_index = m.parm_index;
}
}
+ if (a.parm_index == MODREF_UNKNOWN_PARM
+ && promote_unknown_to_global)
+ a.parm_index = MODREF_GLOBAL_MEMORY_PARM;
changed |= insert (max_bases, max_refs, max_accesses,
base_node->base, ref_node->ref,
a, record_accesses);
@@ -618,12 +623,14 @@ struct GTY((user)) modref_tree
bool merge (tree fndecl,
modref_tree <T> *other, vec <modref_parm_map> *parm_map,
modref_parm_map *static_chain_map,
- bool record_accesses)
+ bool record_accesses,
+ bool promote_unknown_to_global = false)
{
return merge (opt_for_fn (fndecl, param_modref_max_bases),
opt_for_fn (fndecl, param_modref_max_refs),
opt_for_fn (fndecl, param_modref_max_accesses),
- other, parm_map, static_chain_map, record_accesses);
+ other, parm_map, static_chain_map, record_accesses,
+ promote_unknown_to_global);
}
/* Copy OTHER to THIS. */
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 1cf9609e8f3..1c0b16f7040 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -869,6 +869,76 @@ parm_map_for_ptr (tree op)
return parm_map;
}
+/* 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, bool use_escape, bool load)
+{
+ if (flags & EAF_UNUSED)
+ return true;
+ if (load && (flags & EAF_NO_DIRECT_READ))
+ return true;
+ if (!load
+ && (flags & (EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER))
+ == (EAF_NO_DIRECT_CLOBBER | EAF_NO_INDIRECT_CLOBBER))
+ return true;
+ if (use_escape && !(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,
+ bool use_escape, bool load)
+{
+ int implicit_flags = 0;
+ tree callee = gimple_call_fndecl (call);
+
+ /* Do not use escape info when it may get imroved: that is when we
+ run in IPA mode, or call is indirect (and may be promoted to direct)
+ or call is recursive. */
+ if (!callee)
+ use_escape = false;
+ else if (recursive_call_p (current_function_decl, callee))
+ use_escape = 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,
+ use_escape, load))
+ 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,
+ use_escape, load))
+ return true;
+ return false;
+}
+
+
/* Analyze memory accesses (loads, stores and kills) performed
by the function. Set also side_effects, calls_interposable
and nondeterminism flags. */
@@ -1195,7 +1265,8 @@ modref_access_analysis::merge_call_side_effects
(gimple *stmt, modref_summary *callee_summary,
cgraph_node *callee_node, bool record_adjustments)
{
- int flags = gimple_call_flags (stmt);
+ gcall *call = as_a <gcall *> (stmt);
+ int flags = gimple_call_flags (call);
/* Nothing to do for non-looping cont functions. */
if ((flags & (ECF_CONST | ECF_NOVOPS))
@@ -1258,10 +1329,10 @@ modref_access_analysis::merge_call_side_effects
fprintf (dump_file, " Parm map:");
auto_vec <modref_parm_map, 32> parm_map;
- parm_map.safe_grow_cleared (gimple_call_num_args (stmt), true);
- for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
+ parm_map.safe_grow_cleared (gimple_call_num_args (call), true);
+ for (unsigned i = 0; i < gimple_call_num_args (call); i++)
{
- parm_map[i] = parm_map_for_ptr (gimple_call_arg (stmt, i));
+ parm_map[i] = parm_map_for_ptr (gimple_call_arg (call, i));
if (dump_file)
{
fprintf (dump_file, " %i", parm_map[i].parm_index);
@@ -1275,9 +1346,9 @@ modref_access_analysis::merge_call_side_effects
}
modref_parm_map chain_map;
- if (gimple_call_chain (stmt))
+ if (gimple_call_chain (call))
{
- chain_map = parm_map_for_ptr (gimple_call_chain (stmt));
+ chain_map = parm_map_for_ptr (gimple_call_chain (call));
if (dump_file)
{
fprintf (dump_file, "static chain %i", chain_map.parm_index);
@@ -1297,7 +1368,7 @@ modref_access_analysis::merge_call_side_effects
if (m_always_executed
&& callee_summary->kills.length ()
&& (!cfun->can_throw_non_call_exceptions
- || !stmt_could_throw_p (cfun, stmt)))
+ || !stmt_could_throw_p (cfun, call)))
{
/* Watch for self recursive updates. */
auto_vec<modref_access_node, 32> saved_kills;
@@ -1330,14 +1401,18 @@ modref_access_analysis::merge_call_side_effects
changed |= m_summary->loads->merge (current_function_decl,
callee_summary->loads,
&parm_map, &chain_map,
- record_adjustments);
+ record_adjustments,
+ !may_access_nonescaping_parm_p
+ (call, flags, !m_ipa, true));
/* Merge in stores. */
if (!ignore_stores_p (current_function_decl, flags))
{
changed |= m_summary->stores->merge (current_function_decl,
callee_summary->stores,
&parm_map, &chain_map,
- record_adjustments);
+ record_adjustments,
+ !may_access_nonescaping_parm_p
+ (call, flags, !m_ipa, false));
if (!m_summary->writes_errno
&& callee_summary->writes_errno)
{
@@ -1385,58 +1460,6 @@ 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. */
@@ -1471,12 +1494,18 @@ modref_access_analysis::process_fnspec (gcall *call)
IDENTIFIER_POINTER (DECL_NAME (gimple_call_fndecl (call))));
if (!ignore_stores_p (current_function_decl, flags))
{
- record_global_memory_store ();
- record_global_memory_load ();
+ if (!may_access_nonescaping_parm_p (call, flags, !m_ipa, false))
+ record_global_memory_store ();
+ else
+ record_unknown_store ();
+ if (!may_access_nonescaping_parm_p (call, flags, !m_ipa, true))
+ record_global_memory_load ();
+ else
+ record_unknown_load ();
}
else
{
- if (!may_access_nonescaping_parm_p (call, flags))
+ if (!may_access_nonescaping_parm_p (call, flags, !m_ipa, true))
record_global_memory_load ();
else
record_unknown_load ();
@@ -1486,7 +1515,7 @@ modref_access_analysis::process_fnspec (gcall *call)
/* Process fnspec. */
if (fnspec.global_memory_read_p ())
{
- if (may_access_nonescaping_parm_p (call, flags))
+ if (may_access_nonescaping_parm_p (call, flags, !m_ipa, true))
record_unknown_load ();
else
record_global_memory_load ();
@@ -1523,7 +1552,7 @@ modref_access_analysis::process_fnspec (gcall *call)
return;
if (fnspec.global_memory_written_p ())
{
- if (may_access_nonescaping_parm_p (call, flags))
+ if (may_access_nonescaping_parm_p (call, flags, !m_ipa, false))
record_unknown_store ();
else
record_global_memory_store ();
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-12-12 10:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-12 10:38 [gcc(refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2)] Improved 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).