diff options
-rw-r--r-- | gcc/ipa-fnsummary.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/concat5.adb | 9 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/concat5_pkg1.adb | 18 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/concat5_pkg1.ads | 5 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/concat5_pkg2.adb | 10 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/concat5_pkg2.ads | 5 | ||||
-rw-r--r-- | gcc/trans-mem.cc | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.cc | 65 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.h | 10 | ||||
-rw-r--r-- | gcc/tree-ssa-dce.cc | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-dse.cc | 4 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.cc | 15 |
12 files changed, 93 insertions, 54 deletions
diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc index 0d7e395..b12e7a1 100644 --- a/gcc/ipa-fnsummary.cc +++ b/gcc/ipa-fnsummary.cc @@ -2587,7 +2587,7 @@ points_to_local_or_readonly_memory_p (tree t) && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)) && t == ssa_default_def (cfun, DECL_RESULT (current_function_decl))) return true; - return !ptr_deref_may_alias_global_p (t); + return !ptr_deref_may_alias_global_p (t, false); } if (TREE_CODE (t) == ADDR_EXPR) return refs_local_or_readonly_memory_p (TREE_OPERAND (t, 0)); diff --git a/gcc/testsuite/gnat.dg/concat5.adb b/gcc/testsuite/gnat.dg/concat5.adb new file mode 100644 index 0000000..fabf248 --- /dev/null +++ b/gcc/testsuite/gnat.dg/concat5.adb @@ -0,0 +1,9 @@ +-- { dg-do run } +-- { dg-options "-O" } + +with Concat5_Pkg1; use Concat5_Pkg1; + +procedure Concat5 is +begin + Scan ("-RTS=none"); +end; diff --git a/gcc/testsuite/gnat.dg/concat5_pkg1.adb b/gcc/testsuite/gnat.dg/concat5_pkg1.adb new file mode 100644 index 0000000..c32f5af --- /dev/null +++ b/gcc/testsuite/gnat.dg/concat5_pkg1.adb @@ -0,0 +1,18 @@ +with Concat5_Pkg2; use Concat5_Pkg2; + +package body Concat5_Pkg1 is + + procedure Make_Failed (S : String); + pragma No_Inline (Make_Failed); + + procedure Make_Failed (S : String) is + begin + Compare (S); + end; + + procedure Scan (S : String) is + begin + Make_Failed ("option " & S & " should start with '--'"); + end; + +end Concat5_Pkg1; diff --git a/gcc/testsuite/gnat.dg/concat5_pkg1.ads b/gcc/testsuite/gnat.dg/concat5_pkg1.ads new file mode 100644 index 0000000..7f46d87 --- /dev/null +++ b/gcc/testsuite/gnat.dg/concat5_pkg1.ads @@ -0,0 +1,5 @@ +package Concat5_Pkg1 is + + procedure Scan (S : String); + +end Concat5_Pkg1; diff --git a/gcc/testsuite/gnat.dg/concat5_pkg2.adb b/gcc/testsuite/gnat.dg/concat5_pkg2.adb new file mode 100644 index 0000000..98bd388 --- /dev/null +++ b/gcc/testsuite/gnat.dg/concat5_pkg2.adb @@ -0,0 +1,10 @@ +package body Concat5_Pkg2 is + + procedure Compare (S : String) is + begin + if S /= "option -RTS=none should start with '--'" then + raise Program_Error; + end if; + end; + +end Concat5_Pkg2; diff --git a/gcc/testsuite/gnat.dg/concat5_pkg2.ads b/gcc/testsuite/gnat.dg/concat5_pkg2.ads new file mode 100644 index 0000000..2931ffd --- /dev/null +++ b/gcc/testsuite/gnat.dg/concat5_pkg2.ads @@ -0,0 +1,5 @@ +package Concat5_Pkg2 is + + procedure Compare (S : String); + +end Concat5_Pkg2; diff --git a/gcc/trans-mem.cc b/gcc/trans-mem.cc index e9feac2..ae2921f 100644 --- a/gcc/trans-mem.cc +++ b/gcc/trans-mem.cc @@ -1400,7 +1400,7 @@ thread_private_new_memory (basic_block entry_block, tree x) /* Search DEF chain to find the original definition of this address. */ do { - if (ptr_deref_may_alias_global_p (x)) + if (ptr_deref_may_alias_global_p (x, true)) { /* Address escapes. This is not thread-private. */ retval = mem_non_local; diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc index 50bd47b..063f189 100644 --- a/gcc/tree-ssa-alias.cc +++ b/gcc/tree-ssa-alias.cc @@ -210,10 +210,12 @@ dump_alias_stats (FILE *s) } -/* Return true, if dereferencing PTR may alias with a global variable. */ +/* Return true, if dereferencing PTR may alias with a global variable. + When ESCAPED_LOCAL_P is true escaped local memory is also considered + global. */ bool -ptr_deref_may_alias_global_p (tree ptr) +ptr_deref_may_alias_global_p (tree ptr, bool escaped_local_p) { struct ptr_info_def *pi; @@ -230,7 +232,7 @@ ptr_deref_may_alias_global_p (tree ptr) return true; /* ??? This does not use TBAA to prune globals ptr may not access. */ - return pt_solution_includes_global (&pi->pt); + return pt_solution_includes_global (&pi->pt, escaped_local_p); } /* Return true if dereferencing PTR may alias DECL. @@ -480,37 +482,44 @@ ptrs_compare_unequal (tree ptr1, tree ptr2) return false; } -/* Returns whether reference REF to BASE may refer to global memory. */ +/* Returns whether reference REF to BASE may refer to global memory. + When ESCAPED_LOCAL_P is true escaped local memory is also considered + global. */ static bool -ref_may_alias_global_p_1 (tree base) +ref_may_alias_global_p_1 (tree base, bool escaped_local_p) { if (DECL_P (base)) - return is_global_var (base); + return (is_global_var (base) + || (escaped_local_p + && pt_solution_includes (&cfun->gimple_df->escaped, base))); else if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF) - return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0)); + return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0), + escaped_local_p); return true; } bool -ref_may_alias_global_p (ao_ref *ref) +ref_may_alias_global_p (ao_ref *ref, bool escaped_local_p) { tree base = ao_ref_base (ref); - return ref_may_alias_global_p_1 (base); + return ref_may_alias_global_p_1 (base, escaped_local_p); } bool -ref_may_alias_global_p (tree ref) +ref_may_alias_global_p (tree ref, bool escaped_local_p) { tree base = get_base_address (ref); - return ref_may_alias_global_p_1 (base); + return ref_may_alias_global_p_1 (base, escaped_local_p); } -/* Return true whether STMT may clobber global memory. */ +/* Return true whether STMT may clobber global memory. + When ESCAPED_LOCAL_P is true escaped local memory is also considered + global. */ bool -stmt_may_clobber_global_p (gimple *stmt) +stmt_may_clobber_global_p (gimple *stmt, bool escaped_local_p) { tree lhs; @@ -531,7 +540,7 @@ stmt_may_clobber_global_p (gimple *stmt) case GIMPLE_ASSIGN: lhs = gimple_assign_lhs (stmt); return (TREE_CODE (lhs) != SSA_NAME - && ref_may_alias_global_p (lhs)); + && ref_may_alias_global_p (lhs, escaped_local_p)); case GIMPLE_CALL: return true; default: @@ -2567,30 +2576,6 @@ refs_output_dependent_p (tree store1, tree store2) return refs_may_alias_p_1 (&r1, &r2, false); } -/* Return ture if REF may access global memory. */ - -bool -ref_may_access_global_memory_p (ao_ref *ref) -{ - if (!ref->ref) - return true; - tree base = ao_ref_base (ref); - if (TREE_CODE (base) == MEM_REF - || TREE_CODE (base) == TARGET_MEM_REF) - { - if (ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0))) - return true; - } - else - { - if (!auto_var_in_fn_p (base, current_function_decl) - || pt_solution_includes (&cfun->gimple_df->escaped, - base)) - return true; - } - return false; -} - /* Returns true if and only if REF may alias any access stored in TT. IF TBAA_P is true, use TBAA oracle. */ @@ -2654,7 +2639,7 @@ modref_may_conflict (const gcall *stmt, { if (global_memory_ok) continue; - if (ref_may_access_global_memory_p (ref)) + if (ref_may_alias_global_p (ref, true)) return true; global_memory_ok = true; num_tests++; @@ -2990,7 +2975,7 @@ ref_maybe_used_by_stmt_p (gimple *stmt, ao_ref *ref, bool tbaa_p) return is_global_var (base); else if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF) - return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0)); + return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0), false); return false; } diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index dfb2127..fa081ab 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -121,18 +121,18 @@ extern tree ao_ref_alias_ptr_type (ao_ref *); extern tree ao_ref_base_alias_ptr_type (ao_ref *); extern bool ao_ref_alignment (ao_ref *, unsigned int *, unsigned HOST_WIDE_INT *); -extern bool ptr_deref_may_alias_global_p (tree); +extern bool ptr_deref_may_alias_global_p (tree, bool); extern bool ptr_derefs_may_alias_p (tree, tree); extern bool ptrs_compare_unequal (tree, tree); -extern bool ref_may_alias_global_p (tree); -extern bool ref_may_alias_global_p (ao_ref *); +extern bool ref_may_alias_global_p (tree, bool); +extern bool ref_may_alias_global_p (ao_ref *, bool); extern bool refs_may_alias_p (tree, tree, bool = true); extern bool refs_may_alias_p_1 (ao_ref *, ao_ref *, bool); extern bool refs_anti_dependent_p (tree, tree); extern bool refs_output_dependent_p (tree, tree); extern bool ref_maybe_used_by_stmt_p (gimple *, tree, bool = true); extern bool ref_maybe_used_by_stmt_p (gimple *, ao_ref *, bool = true); -extern bool stmt_may_clobber_global_p (gimple *); +extern bool stmt_may_clobber_global_p (gimple *, bool); extern bool stmt_may_clobber_ref_p (gimple *, tree, bool = true); extern bool stmt_may_clobber_ref_p_1 (gimple *, ao_ref *, bool = true); extern bool call_may_clobber_ref_p (gcall *, tree, bool = true); @@ -171,7 +171,7 @@ extern void dump_alias_stats (FILE *); extern unsigned int compute_may_aliases (void); extern bool pt_solution_empty_p (const pt_solution *); extern bool pt_solution_singleton_or_null_p (struct pt_solution *, unsigned *); -extern bool pt_solution_includes_global (struct pt_solution *); +extern bool pt_solution_includes_global (struct pt_solution *, bool); extern bool pt_solution_includes (struct pt_solution *, const_tree); extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *); extern void pt_solution_reset (struct pt_solution *); diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc index 2a13ea3..34ce8ab 100644 --- a/gcc/tree-ssa-dce.cc +++ b/gcc/tree-ssa-dce.cc @@ -315,7 +315,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive) } if ((gimple_vdef (stmt) && keep_all_vdefs_p ()) - || stmt_may_clobber_global_p (stmt)) + || stmt_may_clobber_global_p (stmt, true)) { mark_stmt_necessary (stmt, true); return; diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc index 3beaed3..881a2d0 100644 --- a/gcc/tree-ssa-dse.cc +++ b/gcc/tree-ssa-dse.cc @@ -1030,7 +1030,7 @@ dse_classify_store (ao_ref *ref, gimple *stmt, just pretend the stmt makes itself dead. Otherwise fail. */ if (defs.is_empty ()) { - if (ref_may_alias_global_p (ref)) + if (ref_may_alias_global_p (ref, false)) return DSE_STORE_LIVE; if (by_clobber_p) @@ -1062,7 +1062,7 @@ dse_classify_store (ao_ref *ref, gimple *stmt, { /* But if the store is to global memory it is definitely not dead. */ - if (ref_may_alias_global_p (ref)) + if (ref_may_alias_global_p (ref, false)) return DSE_STORE_LIVE; defs.unordered_remove (i); } diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc index d318f88..581bdcf 100644 --- a/gcc/tree-ssa-structalias.cc +++ b/gcc/tree-ssa-structalias.cc @@ -6995,10 +6995,12 @@ pt_solution_singleton_or_null_p (struct pt_solution *pt, unsigned *uid) return true; } -/* Return true if the points-to solution *PT includes global memory. */ +/* Return true if the points-to solution *PT includes global memory. + If ESCAPED_LOCAL_P is true then escaped local variables are also + considered global. */ bool -pt_solution_includes_global (struct pt_solution *pt) +pt_solution_includes_global (struct pt_solution *pt, bool escaped_local_p) { if (pt->anything || pt->nonlocal @@ -7009,12 +7011,17 @@ pt_solution_includes_global (struct pt_solution *pt) || pt->vars_contains_escaped_heap) return true; + if (escaped_local_p && pt->vars_contains_escaped) + return true; + /* 'escaped' is also a placeholder so we have to look into it. */ if (pt->escaped) - return pt_solution_includes_global (&cfun->gimple_df->escaped); + return pt_solution_includes_global (&cfun->gimple_df->escaped, + escaped_local_p); if (pt->ipa_escaped) - return pt_solution_includes_global (&ipa_escaped_pt); + return pt_solution_includes_global (&ipa_escaped_pt, + escaped_local_p); return false; } |