aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2020-11-14 13:52:36 +0100
committerJan Hubicka <jh@suse.cz>2020-11-14 13:52:36 +0100
commit520d5ad337eaa15860a5a964daf7ca46cf31c029 (patch)
tree9d875db97de3265cd0cffe2a2c000dc3eb7ffa53 /gcc/gimple.c
parent2873c8af66e1248734bb638a49e6bc53f5e45382 (diff)
downloadgcc-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.c53
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;
}