aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-alias.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r--gcc/tree-ssa-alias.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 7ce016b9096..1523aebac17 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -521,6 +521,8 @@ set_initial_properties (struct alias_info *ai)
referenced_var_iterator rvi;
tree var;
tree ptr;
+ bool any_pt_anything = false;
+ enum escape_type pt_anything_mask = 0;
FOR_EACH_REFERENCED_VAR (var, rvi)
{
@@ -543,8 +545,14 @@ set_initial_properties (struct alias_info *ai)
{
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
tree tag = symbol_mem_tag (SSA_NAME_VAR (ptr));
-
- if (pi->value_escapes_p)
+
+ /* A pointer that only escapes via a function return does not
+ add to the call clobber or call used solution.
+ To exclude ESCAPE_TO_PURE_CONST we would need to track
+ call used variables separately or compute those properly
+ in the operand scanner. */
+ if (pi->value_escapes_p
+ && pi->escape_mask & ~ESCAPE_TO_RETURN)
{
/* If PTR escapes then its associated memory tags and
pointed-to variables are call-clobbered. */
@@ -554,22 +562,16 @@ set_initial_properties (struct alias_info *ai)
if (tag)
mark_call_clobbered (tag, pi->escape_mask);
- if (pi->pt_vars)
+ /* Defer to points-to analysis if possible, otherwise
+ clobber all addressable variables. Parameters cannot
+ point to local memory though.
+ ??? Properly tracking which pointers point to non-local
+ memory only would make a big difference here. */
+ if (!clobber_what_p_points_to (ptr)
+ && !(pi->escape_mask & ESCAPE_IS_PARM))
{
- bitmap_iterator bi;
- unsigned int j;
- EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, bi)
- {
- tree alias = referenced_var (j);
-
- /* If you clobber one part of a structure, you
- clobber the entire thing. While this does not make
- the world a particularly nice place, it is necessary
- in order to allow C/C++ tricks that involve
- pointer arithmetic to work. */
- if (!unmodifiable_var_p (alias))
- mark_call_clobbered (alias, pi->escape_mask);
- }
+ any_pt_anything = true;
+ pt_anything_mask |= pi->escape_mask;
}
}
@@ -603,6 +605,21 @@ set_initial_properties (struct alias_info *ai)
MTAG_GLOBAL (tag) = true;
}
}
+
+ /* If a pt_anything pointer escaped we need to mark all addressable
+ variables call clobbered. */
+ if (any_pt_anything)
+ {
+ bitmap_iterator bi;
+ unsigned int j;
+
+ EXECUTE_IF_SET_IN_BITMAP (gimple_addressable_vars (cfun), 0, j, bi)
+ {
+ tree var = referenced_var (j);
+ if (!unmodifiable_var_p (var))
+ mark_call_clobbered (var, pt_anything_mask);
+ }
+ }
}
/* Compute which variables need to be marked call clobbered because