From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1075) id 6542C3858419; Sun, 12 Dec 2021 10:38:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6542C3858419 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Jan Hubicka To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2)] Improved modref X-Act-Checkin: gcc X-Git-Author: Jan Hubicka X-Git-Refname: refs/users/hubicka/heads/honza-gcc-benchmark-branch-v2 X-Git-Oldrev: 77a13853beb2d782359867954c6c97f8e8e6b3da X-Git-Newrev: 3e40f07606c458ec6f05c2c9ea04be828bc4aeca Message-Id: <20211212103843.6542C3858419@sourceware.org> Date: Sun, 12 Dec 2021 10:38:43 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Dec 2021 10:38:43 -0000 https://gcc.gnu.org/g:3e40f07606c458ec6f05c2c9ea04be828bc4aeca commit 3e40f07606c458ec6f05c2c9ea04be828bc4aeca Author: Jan Hubicka 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 *&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 *other, vec *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 *other, vec *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 (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 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 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 ();