From 50dc9a88c1edf862816c804f8ea93443d257180c Mon Sep 17 00:00:00 2001 From: Diego Novillo Date: Wed, 18 Aug 2004 18:21:23 +0000 Subject: [PATCH] tree-dfa.c (add_referenced_var): Only global variables are call-clobbered. * tree-dfa.c (add_referenced_var): Only global variables are call-clobbered. * tree-flow.h (struct ptr_info_def): Add field pt_global_mem. * tree-ssa-alias.c (compute_points_to_and_addr_escape): Mark all pointers dereferenced if the statement dereferences them. (create_name_tags): Do not create memory tags for pointers that have PT_ANYTHING set. Also check if PT_VARS is not empty before creating a name tag. (compute_flow_sensitive_aliasing): Don't mark call-clobbered variables that share the same alias set with a pointer that may point anywhere. (add_may_alias): Add FIXME comment to remove clobbering aliased variables and tags. (replace_may_alias): Likewise. (set_pt_anything): Do not clear PT_VARS nor IS_DEREFERENCED. (merge_pointed_to_info): If the original variable has not points-to information, call set_pt_anything. (add_pointed_to_var): Do not prevent adding a pointed-to variable if the pointers is PT_ANYTHING. If the variable is a global, set PT_GLOBAL_MEM. (collect_points_to_info_r): Don't assume that PLUS_EXPRs of pointer type only come in PTR+OFFSET flavours. Always call merge_pointed_to_info on PHI arguments that are SSA_NAMEs. (get_nmt_for): Mark call-clobbered tags whose pointer points to global memory. * tree-ssa-operands.c (opf_kill_def, opf_no_vops): Switch values. (get_indirect_ref_operands): Always clear OPF_KILL_DEF from FLAGS. (add_stmt_operand): Abort if the caller tried to add a killing definition for a memory tag. * tree-ssa.c (verify_flow_sensitive_alias_info): Remove unnecessary checks. From-SVN: r86198 --- gcc/ChangeLog | 37 +++++++++++ gcc/tree-dfa.c | 6 +- gcc/tree-flow.h | 3 + gcc/tree-ssa-alias.c | 134 ++++++++++++++++++---------------------- gcc/tree-ssa-operands.c | 37 +++++++---- gcc/tree-ssa.c | 12 ---- 6 files changed, 129 insertions(+), 100 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6dc33062d4a..d4e6bc38b7c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,40 @@ +2004-08-18 Diego Novillo + + * tree-dfa.c (add_referenced_var): Only global variables are + call-clobbered. + * tree-flow.h (struct ptr_info_def): Add field pt_global_mem. + * tree-ssa-alias.c (compute_points_to_and_addr_escape): Mark + all pointers dereferenced if the statement dereferences them. + (create_name_tags): Do not create memory tags for pointers + that have PT_ANYTHING set. + Also check if PT_VARS is not empty before creating a name tag. + (compute_flow_sensitive_aliasing): Don't mark call-clobbered + variables that share the same alias set with a pointer that + may point anywhere. + (add_may_alias): Add FIXME comment to remove clobbering + aliased variables and tags. + (replace_may_alias): Likewise. + (set_pt_anything): Do not clear PT_VARS nor IS_DEREFERENCED. + (merge_pointed_to_info): If the original variable has not + points-to information, call set_pt_anything. + (add_pointed_to_var): Do not prevent adding a pointed-to + variable if the pointers is PT_ANYTHING. + If the variable is a global, set PT_GLOBAL_MEM. + (collect_points_to_info_r): Don't assume that PLUS_EXPRs of + pointer type only come in PTR+OFFSET flavours. + Always call merge_pointed_to_info on PHI arguments that are + SSA_NAMEs. + (get_nmt_for): Mark call-clobbered tags whose pointer points + to global memory. + * tree-ssa-operands.c (opf_kill_def, opf_no_vops): Switch + values. + (get_indirect_ref_operands): Always clear OPF_KILL_DEF from + FLAGS. + (add_stmt_operand): Abort if the caller tried to add a killing + definition for a memory tag. + * tree-ssa.c (verify_flow_sensitive_alias_info): Remove + unnecessary checks. + 2004-08-18 J"orn Rennecke * sh.h (CONDITIONAL_REGISTER_USAGE): Don't exclude fixed registers diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 0273406df84..b8a9b03324f 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -903,10 +903,8 @@ add_referenced_var (tree var, struct walk_state *walk_state) v_ann->uid = num_referenced_vars; VARRAY_PUSH_TREE (referenced_vars, var); - /* Initially assume that all memory variables are - call-clobbered. This will be refined later by the alias - analyzer. */ - if (needs_to_live_in_memory (var)) + /* Global variables are always call-clobbered. */ + if (is_global_var (var)) mark_call_clobbered (var); /* If an initialized global variable then register the initializer diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 0e60e411e28..ca5897afa49 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -62,6 +62,9 @@ struct ptr_info_def GTY(()) /* Nonzero if this pointer is dereferenced. */ unsigned int is_dereferenced : 1; + /* Nonzero if this pointer points to a global variable. */ + unsigned int pt_global_mem : 1; + /* Set of variables that this pointer may point to. */ bitmap pt_vars; diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index a344384b426..8cfc65ad35f 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -653,16 +653,14 @@ compute_points_to_and_addr_escape (struct alias_info *ai) collect_points_to_info_for (ai, op); - pi = SSA_NAME_PTR_INFO (op); + pi = SSA_NAME_PTR_INFO (op); if (ptr_is_dereferenced_by (op, stmt, &is_store)) { - /* If we found OP to point to a set of variables or - malloc, then mark it as being dereferenced. In a - subsequent pass, dereferenced pointers that point - to a set of variables will be assigned a name tag - to alias all the variables OP points to. */ - if (pi->pt_malloc || pi->pt_vars) - pi->is_dereferenced = 1; + /* Mark OP as dereferenced. In a subsequent pass, + dereferenced pointers that point to a set of + variables will be assigned a name tag to alias + all the variables OP points to. */ + pi->is_dereferenced = 1; /* Keep track of how many time we've dereferenced each pointer. Again, we don't need to grow @@ -762,15 +760,16 @@ create_name_tags (struct alias_info *ai) tree ptr = VARRAY_TREE (ai->processed_ptrs, i); struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); - if (!pi->is_dereferenced) + if (pi->pt_anything || !pi->is_dereferenced) { /* No name tags for pointers that have not been - dereferenced. */ + dereferenced or point to an arbitrary location. */ pi->name_mem_tag = NULL_TREE; continue; } - if (pi->pt_vars) + if (pi->pt_vars + && bitmap_first_set_bit (pi->pt_vars) >= 0) { size_t j; tree old_name_tag = pi->name_mem_tag; @@ -859,38 +858,14 @@ compute_flow_sensitive_aliasing (struct alias_info *ai) if (pi->value_escapes_p || pi->pt_anything) { /* If PTR escapes or may point to anything, then its associated - memory tags are call-clobbered. */ + memory tags and pointed-to variables are call-clobbered. */ if (pi->name_mem_tag) mark_call_clobbered (pi->name_mem_tag); if (v_ann->type_mem_tag) mark_call_clobbered (v_ann->type_mem_tag); - /* If PTR may point to anything, mark call-clobbered all the - addressables with the same alias set as the type pointed-to by - PTR. */ - if (pi->pt_anything) - { - HOST_WIDE_INT ptr_set; - ptr_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr))); - for (j = 0; j < ai->num_addressable_vars; j++) - { - struct alias_map_d *alias_map = ai->addressable_vars[j]; - if (alias_map->set == ptr_set) - mark_call_clobbered (alias_map->var); - } - } - - /* If PTR's value may escape and PTR is never dereferenced, we - need to mark all the variables PTR points-to as - call-clobbered. Note that we only need do this it PTR is - never dereferenced. If PTR is dereferenced, it will have a - name memory tag, which will have been marked call-clobbered. - This will in turn mark the pointed-to variables as - call-clobbered when we call add_may_alias below. */ - if (pi->value_escapes_p - && pi->name_mem_tag == NULL_TREE - && pi->pt_vars) + if (pi->pt_vars) EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, mark_call_clobbered (referenced_var (j))); } @@ -1684,7 +1659,9 @@ add_may_alias (tree var, tree alias) if (alias == VARRAY_TREE (v_ann->may_aliases, i)) return; - /* If VAR is a call-clobbered variable, so is its new ALIAS. */ + /* If VAR is a call-clobbered variable, so is its new ALIAS. + FIXME, call-clobbering should only depend on whether an address + escapes. It should be independent of aliasing. */ if (is_call_clobbered (var)) mark_call_clobbered (alias); @@ -1705,7 +1682,9 @@ replace_may_alias (tree var, size_t i, tree new_alias) var_ann_t v_ann = var_ann (var); VARRAY_TREE (v_ann->may_aliases, i) = new_alias; - /* If VAR is a call-clobbered variable, so is NEW_ALIAS. */ + /* If VAR is a call-clobbered variable, so is NEW_ALIAS. + FIXME, call-clobbering should only depend on whether an address + escapes. It should be independent of aliasing. */ if (is_call_clobbered (var)) mark_call_clobbered (new_alias); @@ -1724,8 +1703,6 @@ set_pt_anything (tree ptr) pi->pt_anything = 1; pi->pt_malloc = 0; - pi->pt_vars = NULL; - pi->is_dereferenced = 0; /* The pointer used to have a name tag, but we now found it pointing to an arbitrary location. The name tag needs to be renamed and @@ -1812,6 +1789,8 @@ merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig) orig_pi->pt_vars); } } + else + set_pt_anything (dest); } @@ -1882,14 +1861,14 @@ add_pointed_to_var (struct alias_info *ai, tree ptr, tree value) uid = var_ann (pt_var)->uid; bitmap_set_bit (ai->addresses_needed, uid); - /* If PTR has already been found to point anywhere, don't - add the variable to PTR's points-to set. */ - if (!pi->pt_anything) - { - if (pi->pt_vars == NULL) - pi->pt_vars = BITMAP_GGC_ALLOC (); - bitmap_set_bit (pi->pt_vars, uid); - } + if (pi->pt_vars == NULL) + pi->pt_vars = BITMAP_GGC_ALLOC (); + bitmap_set_bit (pi->pt_vars, uid); + + /* If the variable is a global, mark the pointer as pointing to + global memory (which will make its tag a global variable). */ + if (is_global_var (pt_var)) + pi->pt_global_mem = 1; } } @@ -1937,17 +1916,33 @@ collect_points_to_info_r (tree var, tree stmt, void *data) tree op0 = TREE_OPERAND (rhs, 0); tree op1 = TREE_OPERAND (rhs, 1); - if (TREE_CODE (op0) == SSA_NAME - && POINTER_TYPE_P (TREE_TYPE (op0))) - merge_pointed_to_info (ai, var, op0); - else if (TREE_CODE (op1) == SSA_NAME - && POINTER_TYPE_P (TREE_TYPE (op1))) - merge_pointed_to_info (ai, var, op1); - else if (TREE_CODE (op0) == ADDR_EXPR) - add_pointed_to_var (ai, var, op0); - else if (TREE_CODE (op1) == ADDR_EXPR) - add_pointed_to_var (ai, var, op1); - else + /* Both operands may be of pointer type. FIXME: Shouldn't + we just expect PTR + OFFSET always? */ + if (POINTER_TYPE_P (TREE_TYPE (op0))) + { + if (TREE_CODE (op0) == SSA_NAME) + merge_pointed_to_info (ai, var, op0); + else if (TREE_CODE (op0) == ADDR_EXPR) + add_pointed_to_var (ai, var, op0); + else + add_pointed_to_expr (var, op0); + } + + if (POINTER_TYPE_P (TREE_TYPE (op1))) + { + if (TREE_CODE (op1) == SSA_NAME) + merge_pointed_to_info (ai, var, op1); + else if (TREE_CODE (op1) == ADDR_EXPR) + add_pointed_to_var (ai, var, op1); + else + add_pointed_to_expr (var, op1); + } + + /* Neither operand is a pointer? VAR can be pointing + anywhere. FIXME: Is this right? If we get here, we + found PTR = INT_CST + INT_CST. */ + if (!POINTER_TYPE_P (TREE_TYPE (op0)) + && !POINTER_TYPE_P (TREE_TYPE (op1))) add_pointed_to_expr (var, rhs); } @@ -1980,12 +1975,7 @@ collect_points_to_info_r (tree var, tree stmt, void *data) if (TREE_CODE (var) == ADDR_EXPR) add_pointed_to_var (ai, lhs, var); else if (TREE_CODE (var) == SSA_NAME) - { - if (bitmap_bit_p (ai->ssa_names_visited, SSA_NAME_VERSION (var))) - merge_pointed_to_info (ai, lhs, var); - else - set_pt_anything (lhs); - } + merge_pointed_to_info (ai, lhs, var); else if (is_gimple_min_invariant (var)) add_pointed_to_expr (lhs, var); else @@ -2106,13 +2096,11 @@ get_nmt_for (tree ptr) if (tag == NULL_TREE) tag = create_memory_tag (TREE_TYPE (TREE_TYPE (ptr)), false); - /* If PTR is a PARM_DECL, its memory tag should be considered a global - variable. */ - if (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL) - mark_call_clobbered (tag); - - /* Similarly, if PTR points to malloc, then TAG is a global. */ - if (pi->pt_malloc) + /* If PTR is a PARM_DECL, it points to a global variable or malloc, + then its name tag should be considered a global variable. */ + if (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL + || pi->pt_malloc + || pi->pt_global_mem) mark_call_clobbered (tag); return tag; diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 4b899eec526..230167f84e9 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -89,7 +89,7 @@ Boston, MA 02111-1307, USA. */ #define opf_is_def (1 << 0) /* Operand is the target of an assignment expression. */ -#define opf_kill_def (1 << 2) +#define opf_kill_def (1 << 1) /* No virtual operands should be created in the expression. This is used when traversing ADDR_EXPR nodes which have different semantics than @@ -97,7 +97,7 @@ Boston, MA 02111-1307, USA. */ need to consider are indices into arrays. For instance, &a.b[i] should generate a USE of 'i' but it should not generate a VUSE for 'a' nor a VUSE for 'b'. */ -#define opf_no_vops (1 << 1) +#define opf_no_vops (1 << 2) /* Array for building all the def operands. */ static GTY (()) varray_type build_defs; @@ -1273,6 +1273,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags) tree ptr = *pptr; stmt_ann_t ann = stmt_ann (stmt); + /* Stores into INDIRECT_REF operands are never killing definitions. */ + flags &= ~opf_kill_def; if (SSA_VAR_P (ptr)) { @@ -1456,20 +1458,31 @@ add_stmt_operand (tree *var_p, tree stmt, int flags) { if (v_ann->is_alias_tag) { - /* Alias tagged vars get regular V_MAY_DEF */ + /* Alias tagged vars get V_MAY_DEF to avoid breaking + def-def chains with the other variables in their + alias sets. */ if (s_ann) s_ann->makes_aliased_stores = 1; append_v_may_def (var); } - else if ((flags & opf_kill_def) - && v_ann->mem_tag_kind == NOT_A_TAG) - /* V_MUST_DEF for non-aliased non-GIMPLE register - variable definitions. Avoid memory tags. */ - append_v_must_def (var); + else if (flags & opf_kill_def) + { +#if defined ENABLE_CHECKING + /* Only regular variables may get a V_MUST_DEF + operand. */ + if (v_ann->mem_tag_kind != NOT_A_TAG) + abort (); +#endif + /* V_MUST_DEF for non-aliased, non-GIMPLE register + variable definitions. */ + append_v_must_def (var); + } else - /* Call-clobbered variables & memory tags get - V_MAY_DEF */ - append_v_may_def (var); + { + /* Add a V_MAY_DEF for call-clobbered variables and + memory tags. */ + append_v_may_def (var); + } } else { @@ -1506,6 +1519,8 @@ add_stmt_operand (tree *var_p, tree stmt, int flags) } else { + /* Similarly, append a virtual uses for VAR itself, when + it is an alias tag. */ if (v_ann->is_alias_tag) append_vuse (var); diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index eb6f9676617..743c0843366 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -433,18 +433,6 @@ verify_flow_sensitive_alias_info (void) goto err; } - if (pi->pt_anything && (pi->pt_malloc || pi->pt_vars)) - { - error ("Pointers that point to anything should not point to malloc or other vars"); - goto err; - } - - if (pi->pt_malloc && pi->pt_vars) - { - error ("Pointers pointing to malloc get a unique tag and cannot point to other vars"); - goto err; - } - if (pi->name_mem_tag && !pi->pt_malloc && (pi->pt_vars == NULL -- 2.30.2