diff options
author | Jan Hubicka <jh@suse.cz> | 2020-11-25 20:51:26 +0100 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2020-11-25 20:51:26 +0100 |
commit | bb07490abba850fd5b1d2d09d76d18b8bdc7d817 (patch) | |
tree | 088a7d9ff0a070269412fd9c22a3ce3861066442 /gcc/tree-ssa-structalias.c | |
parent | 5962efe9186559ada404ac8f9f56006648a5858e (diff) | |
download | gcc-bb07490abba850fd5b1d2d09d76d18b8bdc7d817.zip gcc-bb07490abba850fd5b1d2d09d76d18b8bdc7d817.tar.gz gcc-bb07490abba850fd5b1d2d09d76d18b8bdc7d817.tar.bz2 |
Add EAF_NODIRECTESCAPE flag
Main limitation of modref is the fact that it does not
track anything in memory. This is intentional - I wanted the initial
implementation to be cheap. However it also makes it very limited when it comes
to detecting noescape especially because it is paranoid about what memory
accesses may be used to copy (bits of) pointers.
This patch adds EAF_NODIRECTSCAPE that is weaker vairant of EAF_NOESCAPE where
we only know that the pointer itself does not escape, but memory pointed to
may. This is a lot more reliable to auto-detect that EAF_NOESCAPE and still
enables additional optimization. With patch we get nodirectscape flag for b
that enables in practice similar optimization as EAF_NOESCAPE for arrays of
integers that points nowhere :)
gcc/ChangeLog:
* gimple.c (gimple_call_arg_flags): Also imply EAF_NODIRECTESCAPE.
* tree-core.h (EAF_NODRECTESCAPE): New flag.
* tree-ssa-structalias.c (make_indirect_escape_constraint): New
function.
(handle_rhs_call): Hanlde EAF_NODIRECTESCAPE.
* ipa-modref.c (dump_eaf_flags): Print EAF_NODIRECTESCAPE.
(deref_flags): Dereference is always EAF_NODIRECTESCAPE.
(modref_lattice::init): Also set EAF_NODIRECTESCAPE.
(analyze_ssa_name_flags): Pure functions do not affect
EAF_NODIRECTESCAPE.
(analyze_params): Likewise.
(ipa_merge_modref_summary_after_inlining): Likewise.
(modref_merge_call_site_flags): Likewise.
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r-- | gcc/tree-ssa-structalias.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index a4832b7..9f4de96 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -3851,6 +3851,23 @@ make_escape_constraint (tree op) make_constraint_to (escaped_id, op); } +/* Make constraint necessary to make all indirect references + from VI escape. */ + +static void +make_indirect_escape_constraint (varinfo_t vi) +{ + struct constraint_expr lhs, rhs; + /* escaped = *(VAR + UNKNOWN); */ + lhs.type = SCALAR; + lhs.var = escaped_id; + lhs.offset = 0; + rhs.type = DEREF; + rhs.var = vi->id; + rhs.offset = UNKNOWN_OFFSET; + process_constraint (new_constraint (lhs, rhs)); +} + /* Add constraints to that the solution of VI is transitively closed. */ static void @@ -4026,7 +4043,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results) set. The argument would still get clobbered through the escape solution. */ if ((flags & EAF_NOCLOBBER) - && (flags & EAF_NOESCAPE)) + && (flags & (EAF_NOESCAPE | EAF_NODIRECTESCAPE))) { varinfo_t uses = get_call_use_vi (stmt); varinfo_t tem = new_var_info (NULL_TREE, "callarg", true); @@ -4036,9 +4053,11 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results) if (!(flags & EAF_DIRECT)) make_transitive_closure_constraints (tem); make_copy_constraint (uses, tem->id); + if (!(flags & (EAF_NOESCAPE | EAF_DIRECT))) + make_indirect_escape_constraint (tem); returns_uses = true; } - else if (flags & EAF_NOESCAPE) + else if (flags & (EAF_NOESCAPE | EAF_NODIRECTESCAPE)) { struct constraint_expr lhs, rhs; varinfo_t uses = get_call_use_vi (stmt); @@ -4061,6 +4080,8 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results) rhs.var = nonlocal_id; rhs.offset = 0; process_constraint (new_constraint (lhs, rhs)); + if (!(flags & (EAF_NOESCAPE | EAF_DIRECT))) + make_indirect_escape_constraint (tem); returns_uses = true; } else |