diff options
author | Jan Hubicka <jh@suse.cz> | 2020-11-14 13:52:36 +0100 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2020-11-14 13:52:36 +0100 |
commit | 520d5ad337eaa15860a5a964daf7ca46cf31c029 (patch) | |
tree | 9d875db97de3265cd0cffe2a2c000dc3eb7ffa53 /gcc/gimple.c | |
parent | 2873c8af66e1248734bb638a49e6bc53f5e45382 (diff) | |
download | gcc-520d5ad337eaa15860a5a964daf7ca46cf31c029.zip gcc-520d5ad337eaa15860a5a964daf7ca46cf31c029.tar.gz gcc-520d5ad337eaa15860a5a964daf7ca46cf31c029.tar.bz2 |
Detect EAF flags in ipa-modref
A minimal patch for the EAF flags discovery. It works only in local ipa-modref
and gives up on cyclic SSA graphs. It improves pt_solution_includes
disambiguations twice.
gcc/Changelog:
* gimple.c: Include ipa-modref-tree.h and ipa-modref.h.
(gimple_call_arg_flags): Use modref to determine flags.
* ipa-modref.c: Include gimple-ssa.h, tree-phinodes.h,
tree-ssa-operands.h, stringpool.h and tree-ssanames.h.
(analyze_ssa_name_flags): Declare.
(modref_summary::useful_p): Summary is also useful if arg flags are
known.
(dump_eaf_flags): New function.
(modref_summary::dump): Use it.
(get_modref_function_summary): Be read for current_function_decl
being NULL.
(memory_access_to): New function.
(deref_flags): New function.
(call_lhs_flags): New function.
(analyze_parms): New function.
(analyze_function): Use it.
* ipa-modref.h (struct modref_summary): Add arg_flags.
* doc/invoke.texi (ipa-modref-max-depth): Document.
* params.opt (ipa-modref-max-depth): New param.
Diffstat (limited to 'gcc/gimple.c')
-rw-r--r-- | gcc/gimple.c | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/gcc/gimple.c b/gcc/gimple.c index 60afc54..e3e508d 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -46,6 +46,8 @@ along with GCC; see the file COPYING3. If not see #include "asan.h" #include "langhooks.h" #include "attr-fnspec.h" +#include "ipa-modref-tree.h" +#include "ipa-modref.h" /* All the tuples have their operand vector (if present) at the very bottom @@ -1528,24 +1530,45 @@ int gimple_call_arg_flags (const gcall *stmt, unsigned arg) { attr_fnspec fnspec = gimple_call_fnspec (stmt); - - if (!fnspec.known_p ()) - return 0; - int flags = 0; - if (!fnspec.arg_specified_p (arg)) - ; - else if (!fnspec.arg_used_p (arg)) - flags = EAF_UNUSED; - else + if (fnspec.known_p ()) { - if (fnspec.arg_direct_p (arg)) - flags |= EAF_DIRECT; - if (fnspec.arg_noescape_p (arg)) - flags |= EAF_NOESCAPE; - if (fnspec.arg_readonly_p (arg)) - flags |= EAF_NOCLOBBER; + if (!fnspec.arg_specified_p (arg)) + ; + else if (!fnspec.arg_used_p (arg)) + flags = EAF_UNUSED; + else + { + if (fnspec.arg_direct_p (arg)) + flags |= EAF_DIRECT; + if (fnspec.arg_noescape_p (arg)) + flags |= EAF_NOESCAPE; + if (fnspec.arg_readonly_p (arg)) + flags |= EAF_NOCLOBBER; + } + } + tree callee = gimple_call_fndecl (stmt); + if (callee) + { + cgraph_node *node = cgraph_node::get (callee); + modref_summary *summary = node ? get_modref_function_summary (node) + : NULL; + + if (summary && summary->arg_flags.length () > arg) + { + int modref_flags = summary->arg_flags[arg]; + + /* We have possibly optimized out load. Be conservative here. */ + if (!node->binds_to_current_def_p ()) + { + if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED)) + modref_flags &= ~EAF_UNUSED; + if ((modref_flags & EAF_DIRECT) && !(flags & EAF_DIRECT)) + modref_flags &= ~EAF_DIRECT; + } + flags |= modref_flags; + } } return flags; } |