diff options
author | bbooth <bbooth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-10 21:41:08 +0000 |
---|---|---|
committer | bbooth <bbooth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-10 21:41:08 +0000 |
commit | 2cf24776875d22c8713d227df0ed663a10e739a5 (patch) | |
tree | 390a758454170e0dc2e6aea71342ec3d64fd2501 /gcc/tree-ssa-operands.c | |
parent | deeb83d60346e094b6636a49606677384a699502 (diff) | |
download | gcc-2cf24776875d22c8713d227df0ed663a10e739a5.tar.gz |
* doc/tree-ssa.texi: Remove references to VDEF and add descriptions
of V_MAY_DEF and V_MUST_DEF.
* tree-dfa.c (dfa_stats_d): Add num_v_must_defs and rename
num_vdefs to num_v_may_defs.
(compute_immediate_uses_for_stmt): Rename occurences of vdef
to v_may_def.
(redirect_immediate_uses): Ditto.
(dump_dfa_stats): Ditto. Also added code to dump num_v_must_defs.
(collect_dfa_stats_r): Rename occurences of vdef to v_may_def.
Also add code to sum up the number of v_must_defs.
(vdefs_disappeared_p): Replace with...
(v_may_defs_disappeared_p): This.
(v_must_defs_disappeared_p): New function.
(mark_new_vars_to_rename): Rename occurences of vdef to v_may_def.
Also add code to mark new variables found in V_MUST_DEFs for
renameing.
* tree-flow.h (stmt_ann_d): Add v_must_def_ops and replace
vdef_ops to v_may_def_ops.
(get_vdef_ops): Replace with...
(get_v_may_def_ops): This.
* tree-flow-inline.h (get_vdef_ops): Replace with...
(get_v_may_def_ops): This.
(get_v_must_def_ops): New function.
(get_vdef_result_ptr): Replace with...
(get_v_may_def_result_ptr): This.
(get_vdef_op_ptr): Ditto with...
(get_v_may_def_op_ptr); This.
(get_v_must_def_op_ptr): New function.
* tree-into-ssa.c (mark_def_sites): Rename occurences of vdef
to v_may_def. Also add code to mark statements with
V_MUST_DEFs as definition sites.
(rewrite_stmt): Rename occurences of vdef to v_may_def. Also
add code to register new V_MUST_DEFs made by the statement.
* tree-outof-ssa.c (VIRTUAL_PARTITION): Update comments.
(check_replaceable): Rename occurences of vdef to v_may_def. Also
add check for V_MUST_DEFs.
(find_replaceable_in_bb): Ditto.
* tree-pretty-print.c (dump_vops): Rename occurences of vdef
to v_may_def. Also add code to dump V_MUST_DEFs.
* tree-sra.c (mark_all_vdefs): Replace with...
(mark_all_v_may_defs): This.
(mark_all_v_must_defs): New function.
(create_scalar_copies): Replace call to mark_all_vdefs with
calls to mark_all_v_may_defs and mark_all_v_must_defs.
(scalarize_structures): Rename occurences of vdef to v_may_def.
Also add a check for V_MUST_DEFs.
(scalarize_modify_expr): Rename occurences of vdef to v_may_def.
* tree-ssa-alias.c (global_var): Update comment.
(compute_may_aliases): Ditto.
(compute_points_to_and_addr_escape): Rename occurences of vdef
to v_may_def. Also add code to mark variables in V_MUST_DEF
operands as being written to.
(group_aliases): Update comment.
(maybe_create_global_var): Ditto.
* tree-ssa.c (verify_ssa): Rename occurences of vdef to v_may_def.
Also add a check for V_MUST_DEFs on GIMPLE registers.
(replace_immediate_uses): Rename occurences of vdef to v_may_def.
* tree-ssa-ccp.c (visit_stmt): Rename occurences of vdef
to v_may_def. Also add code to mark all V_MUST_DEF operands
VARYING.
(initialize): Ditto.
(set_rhs): Rename occurences of vdef to v_may_def. Also add
code to update SSA_NAMEs in V_MUST_DEFs.
* tree-ssa-copy.c (cprop_into_stmt): Rename occurences of vdef
to v_may_def.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Rename
occurences of vdef to v_may_def. Also add code to mark statements
with V_MUST_DEFs as necessary.
(propagate_necessity): Rename occurences of vdef to v_may_def.
* tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Rename
occurences of vdef to v_may_def. Also add code to mark operands
in V_MUST_DEFs for renaming.
(eliminate_redundant_computations): Rename occurences of vdef
to v_may_def.
(record_equivalences_from_stmt): Rename occurences of vdef
to v_may_def. Also add code to record VUSEs for V_MUST_DEFs.
(optimize_stmt): Remove unnesessary variable vdefs. Update
comment.
(register_definitions_for_stmt): Rename occurences of vdef
to v_may_def. Also add code to register definitions made with
V_MUST_DEFs.
* tree-ssa-dse.c (fix_stmt_vdefs): Replace with...
(fix_stmt_v_may_defs): This.
(fix_phi_uses): Rename occurences of vdef to v_may_def.
(dse_optimize_stmt): Ditto.
* tree-ssa-live.c (create_ssa_var_map): Rename occurences of vdef
to v_may_def. Also add code to mark V_MUST_DEF operands as being
used in virtual operators.
* tree-ssa-loop.c (mark_defs_for_rewrite): Rename occurences of
vdef to v_may_def. Also add code to mark V_MUST_DEF operands for
renaming.
* tree-ssa-operands.c (opf_kill_def): New flag for killing
definitions.
(build_vdefs): Renamed to...
(build_v_may_defs): This.
(build_v_must_defs): New variable.
(voperands_d): Add v_must_def_ops and replace vdef_ops with
v_may_def_ops.
(append_vdef): Replace with...
(append_v_may_def): This.
(append_v_must_def): New function.
(NUM_FREE): Increment for V_MUST_DEF
(optype_freelist): Increment its size for V_MUST_DEF
(allocate_vdef_optype): Replace with...
(allocate_v_may_def_optype): This.
(allocate_v_must_def_optype): New function.
(free_vdefs): Replace with...
(free_v_may_defs): This.
(free_v_must_defs): New function.
(remove_vdefs): Replace with...
(remove_v_may_defs): This.
(remove_v_must_defs): New function.
(init_ssa_operands): Rename occurences of vdef to v_may_def. Also
add code to initialize build_v_must_defs.
(finalize_ssa_vdefs): Replace with...
(finalize_ssa_v_may_defs): This.
(finalize_ssa_vuses): Rename occurences of vdef to v_may_def.
(finalize_ssa_v_must_defs): New function.
(finalize_ssa_stmt_operands): Replace call to finalize_ssa_vdefs
with calls to finalize_ssa_v_may_defs and finalize_ssa_v_must_defs.
(verify_start_operands): Rename occurences of vdef to v_may_def.
Also add check for build_v_must_defs.
(get_stmt_operands): Rename occurences of vdef to v_may_def.
Also add code to handle V_MUST_DEFs and to use opf_kill_def for
killing definitions.
(get_expr_operands): Update comment and use opf_kill_def for
killing definitions.
(add_stmt_operand): Replace code that appends VDEFs with code
that appends V_MUST_DEFs when opf_kill_def is set and V_MAY_DEFs
otherwise.
(add_call_clobber_ops): Update comments.
* tree-ssa-operands.h (vdef_optype_d): Replace with...
(v_may_def_optype_d): This.
(v_must_def_optype_d): New structure.
(VDEF_OPS): Replace with...
(V_MAY_DEF_OPS): This.
(STMT_VDEF_OPS): Same with...
(STMT_V_MAY_DEF_OPS): This.
(NUM_VDEFS): And...
(NUM_V_MAY_DEFS): This.
(VDEF_RESULT_PTR): As well as...
(V_MAY_DEF_RESULT_PTR): This.
(VDEF_RESULT): Same goes for...
(V_MAY_DEF_RESULT): This.
(VDEF_OP_PTR): And...
(V_MAY_DEF_OP_PTR): This.
(VDEF_OP): And...
(V_MAY_DEF_OP): This.
(V_MUST_DEF_OPS): New macro.
(STMT_V_MUST_DEF_OPS): Ditto.
(NUM_V_MUST_DEFS): Ditto.
(V_MUST_DEF_OP_PTR): Ditto.
(V_MUST_DEF_OP): Ditto.
(remove_vdefs): Replace signature with...
(remove_v_may_defs): This.
(remove_v_must_defs): New function signature.
* tree-ssa-pre.c (subst_phis): Replace call to remove_vdefs
with calls to remove_v_may_defs and remove_v_must_defs.
(process_left_occs_and_kills): Rename occurences of vdef to v_may_def.
Also add code that marks left occurences of operands in V_MUST_DEFs.
* tree-tailcall.c (find_tail_calls): Rename occurences of vdef
to v_may_def. Also add check for V_MUST_DEFs.
(eliminate_tail_call):Rename occurences of vdef to v_may_def.
testsuite:
* gcc.dg/tree-ssa/20031015-1.c: Scan for
V_MAY_DEF instead of VDEF.
* gcc.dg/tree-ssa/20040517-1.c: Ditto.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@82947 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r-- | gcc/tree-ssa-operands.c | 309 |
1 files changed, 234 insertions, 75 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index cc246ce45be..eae021ecf80 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -37,9 +37,13 @@ Boston, MA 02111-1307, USA. */ /* By default, operands are loaded. */ #define opf_none 0 -/* Operand is the target of an assignment expression. */ +/* Operand is the target of an assignment expression or a + call-clobbered variable */ #define opf_is_def (1 << 0) +/* Operand is the target of an assignment expression. */ +#define opf_kill_def (1 << 2) + /* No virtual operands should be created in the expression. This is used when traversing ADDR_EXPR nodes which have different semantics than other expressions. Inside an ADDR_EXPR node, the only operands that we @@ -54,27 +58,32 @@ static GTY (()) varray_type build_defs; /* Array for building all the use operands. */ static GTY (()) varray_type build_uses; -/* Array for building all the vdef operands. */ -static GTY (()) varray_type build_vdefs; +/* Array for building all the v_may_def operands. */ +static GTY (()) varray_type build_v_may_defs; /* Array for building all the vuse operands. */ static GTY (()) varray_type build_vuses; +/* Array for building all the v_must_def operands. */ +static GTY (()) varray_type build_v_must_defs; + #ifdef ENABLE_CHECKING tree check_build_stmt; #endif typedef struct voperands_d { - vdef_optype vdef_ops; + v_may_def_optype v_may_def_ops; vuse_optype vuse_ops; + v_must_def_optype v_must_def_ops; } *voperands_t; static void note_addressable (tree, stmt_ann_t); static void get_expr_operands (tree, tree *, int, voperands_t); static inline void append_def (tree *, tree); static inline void append_use (tree *, tree); -static void append_vdef (tree, tree, voperands_t); +static void append_v_may_def (tree, tree, voperands_t); +static void append_v_must_def (tree, tree, voperands_t); static void add_call_clobber_ops (tree, voperands_t); static void add_call_read_ops (tree, voperands_t); static void add_stmt_operand (tree *, tree, int, voperands_t); @@ -85,8 +94,8 @@ struct freelist_d GTY((chain_next ("%h.next"))) struct freelist_d *next; }; -#define NUM_FREE 4 -static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0} }; +#define NUM_FREE 5 +static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0}, {0} }; static inline void * @@ -155,17 +164,17 @@ allocate_use_optype (unsigned num) return use_ops; } -static inline vdef_optype -allocate_vdef_optype (unsigned num) +static inline v_may_def_optype +allocate_v_may_def_optype (unsigned num) { - vdef_optype vdef_ops; + v_may_def_optype v_may_def_ops; unsigned size; - size = sizeof (struct vdef_optype_d) + sizeof (tree) * ((num * 2) - 1); - vdef_ops = check_optype_freelist (num * 2); - if (!vdef_ops) - vdef_ops = ggc_alloc (size); - vdef_ops->num_vdefs = num; - return vdef_ops; + size = sizeof (struct v_may_def_optype_d) + sizeof (tree) * ((num * 2) - 1); + v_may_def_ops = check_optype_freelist (num * 2); + if (!v_may_def_ops) + v_may_def_ops = ggc_alloc (size); + v_may_def_ops->num_v_may_defs = num; + return v_may_def_ops; } static inline vuse_optype @@ -181,6 +190,19 @@ allocate_vuse_optype (unsigned num) return vuse_ops; } +static inline v_must_def_optype +allocate_v_must_def_optype (unsigned num) +{ + v_must_def_optype v_must_def_ops; + unsigned size; + size = sizeof (struct v_must_def_optype_d) + sizeof (tree *) * (num - 1); + v_must_def_ops = check_optype_freelist (num); + if (!v_must_def_ops) + v_must_def_ops = ggc_alloc (size); + v_must_def_ops->num_v_must_defs = num; + return v_must_def_ops; +} + static inline void free_uses (use_optype *uses, bool dealloc) { @@ -215,13 +237,24 @@ free_vuses (vuse_optype *vuses, bool dealloc) } static inline void -free_vdefs (vdef_optype *vdefs, bool dealloc) +free_v_may_defs (v_may_def_optype *v_may_defs, bool dealloc) +{ + if (*v_may_defs) + { + if (dealloc) + add_optype_freelist (*v_may_defs, (*v_may_defs)->num_v_may_defs); + *v_may_defs = NULL; + } +} + +static inline void +free_v_must_defs (v_must_def_optype *v_must_defs, bool dealloc) { - if (*vdefs) + if (*v_must_defs) { if (dealloc) - add_optype_freelist (*vdefs, (*vdefs)->num_vdefs); - *vdefs = NULL; + add_optype_freelist (*v_must_defs, (*v_must_defs)->num_v_must_defs); + *v_must_defs = NULL; } } @@ -236,15 +269,24 @@ remove_vuses (tree stmt) } void -remove_vdefs (tree stmt) +remove_v_may_defs (tree stmt) { stmt_ann_t ann; ann = stmt_ann (stmt); if (ann) - free_vdefs (&(ann->vdef_ops), true); + free_v_may_defs (&(ann->v_may_def_ops), true); } +void +remove_v_must_defs (tree stmt) +{ + stmt_ann_t ann; + + ann = stmt_ann (stmt); + if (ann) + free_v_must_defs (&(ann->v_must_def_ops), true); +} void init_ssa_operands (void) @@ -253,8 +295,9 @@ init_ssa_operands (void) VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs"); VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses"); - VARRAY_TREE_INIT (build_vdefs, 10, "build vdefs"); + VARRAY_TREE_INIT (build_v_may_defs, 10, "build v_may_defs"); VARRAY_TREE_INIT (build_vuses, 10, "build vuses"); + VARRAY_TREE_INIT (build_v_must_defs, 10, "build v_must_defs"); for (x = 0; x < NUM_FREE; x++) optype_freelist[x].next = NULL; @@ -328,29 +371,29 @@ finalize_ssa_uses (tree stmt) } static void -finalize_ssa_vdefs (tree stmt) +finalize_ssa_v_may_defs (tree stmt) { unsigned num, x; - vdef_optype vdef_ops; + v_may_def_optype v_may_def_ops; stmt_ann_t ann; - num = VARRAY_ACTIVE_SIZE (build_vdefs); + num = VARRAY_ACTIVE_SIZE (build_v_may_defs); if (num == 0) return; #ifdef ENABLE_CHECKING - /* VDEFs must be entered in pairs of result/uses. */ + /* V_MAY_DEFs must be entered in pairs of result/uses. */ if (num % 2 != 0) abort(); #endif - vdef_ops = allocate_vdef_optype (num / 2); + v_may_def_ops = allocate_v_may_def_optype (num / 2); for (x = 0; x < num; x++) - vdef_ops->vdefs[x] = VARRAY_TREE (build_vdefs, x); - VARRAY_CLEAR (build_vdefs); + v_may_def_ops->v_may_defs[x] = VARRAY_TREE (build_v_may_defs, x); + VARRAY_CLEAR (build_v_may_defs); ann = stmt_ann (stmt); - ann->vdef_ops = vdef_ops; + ann->v_may_def_ops = v_may_def_ops; } static inline void @@ -359,12 +402,12 @@ finalize_ssa_vuses (tree stmt) unsigned num, x; stmt_ann_t ann; vuse_optype vuse_ops; - vdef_optype vdefs; + v_may_def_optype v_may_defs; #ifdef ENABLE_CHECKING - if (VARRAY_ACTIVE_SIZE (build_vdefs) > 0) + if (VARRAY_ACTIVE_SIZE (build_v_may_defs) > 0) { - fprintf (stderr, "Please finalize VDEFs before finalize VUSES.\n"); + fprintf (stderr, "Please finalize V_MAY_DEFs before finalize VUSES.\n"); abort (); } #endif @@ -374,42 +417,42 @@ finalize_ssa_vuses (tree stmt) return; /* Remove superfluous VUSE operands. If the statement already has a - VDEF operation for a variable 'a', then a VUSE for 'a' is not - needed because VDEFs imply a VUSE of the variable. For instance, + V_MAY_DEF operation for a variable 'a', then a VUSE for 'a' is not + needed because V_MAY_DEFs imply a VUSE of the variable. For instance, suppose that variable 'a' is aliased: # VUSE <a_2> - # a_3 = VDEF <a_2> + # a_3 = V_MAY_DEF <a_2> a = a + 1; - The VUSE <a_2> is superfluous because it is implied by the VDEF + The VUSE <a_2> is superfluous because it is implied by the V_MAY_DEF operation. */ ann = stmt_ann (stmt); - vdefs = VDEF_OPS (ann); - if (NUM_VDEFS (vdefs) > 0) + v_may_defs = V_MAY_DEF_OPS (ann); + if (NUM_V_MAY_DEFS (v_may_defs) > 0) { size_t i, j; for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++) { bool found = false; - for (j = 0; j < NUM_VDEFS (vdefs); j++) + for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++) { - tree vuse_var, vdef_var; + tree vuse_var, v_may_def_var; tree vuse = VARRAY_TREE (build_vuses, i); - tree vdef = VDEF_OP (vdefs, j); + tree v_may_def = V_MAY_DEF_OP (v_may_defs, j); if (TREE_CODE (vuse) == SSA_NAME) vuse_var = SSA_NAME_VAR (vuse); else vuse_var = vuse; - if (TREE_CODE (vdef) == SSA_NAME) - vdef_var = SSA_NAME_VAR (vdef); + if (TREE_CODE (v_may_def) == SSA_NAME) + v_may_def_var = SSA_NAME_VAR (v_may_def); else - vdef_var = vdef; + v_may_def_var = v_may_def; - if (vuse_var == vdef_var) + if (vuse_var == v_may_def_var) { found = true; break; @@ -450,6 +493,32 @@ finalize_ssa_vuses (tree stmt) ann->vuse_ops = vuse_ops; } +static void +finalize_ssa_v_must_defs (tree stmt) +{ + unsigned num, x; + stmt_ann_t ann; + v_must_def_optype v_must_def_ops; + + num = VARRAY_ACTIVE_SIZE (build_v_must_defs); + if (num == 0) + return; + +#ifdef ENABLE_CHECKING + /* There should only be a single V_MUST_DEF per assignment. */ + if (TREE_CODE (stmt) == MODIFY_EXPR && num > 1) + abort (); +#endif + + v_must_def_ops = allocate_v_must_def_optype (num); + for (x = 0; x < num ; x++) + v_must_def_ops->v_must_defs[x] = VARRAY_TREE (build_v_must_defs, x); + VARRAY_POP_ALL (build_v_must_defs); + + ann = stmt_ann (stmt); + ann->v_must_def_ops = v_must_def_ops; +} + extern void finalize_ssa_stmt_operands (tree stmt) { @@ -460,7 +529,8 @@ finalize_ssa_stmt_operands (tree stmt) finalize_ssa_defs (stmt); finalize_ssa_uses (stmt); - finalize_ssa_vdefs (stmt); + finalize_ssa_v_must_defs (stmt); + finalize_ssa_v_may_defs (stmt); finalize_ssa_vuses (stmt); #ifdef ENABLE_CHECKING @@ -476,7 +546,8 @@ verify_start_operands (tree stmt ATTRIBUTE_UNUSED) if (VARRAY_ACTIVE_SIZE (build_defs) > 0 || VARRAY_ACTIVE_SIZE (build_uses) > 0 || VARRAY_ACTIVE_SIZE (build_vuses) > 0 - || VARRAY_ACTIVE_SIZE (build_vdefs) > 0) + || VARRAY_ACTIVE_SIZE (build_v_may_defs) > 0 + || VARRAY_ACTIVE_SIZE (build_v_must_defs) > 0) abort (); if (check_build_stmt != NULL) abort(); @@ -517,7 +588,7 @@ append_use (tree *use_p, tree stmt ATTRIBUTE_UNUSED) operands. */ static void -append_vdef (tree var, tree stmt, voperands_t prev_vops) +append_v_may_def (tree var, tree stmt, voperands_t prev_vops) { stmt_ann_t ann; size_t i; @@ -532,9 +603,9 @@ append_vdef (tree var, tree stmt, voperands_t prev_vops) /* Don't allow duplicate entries. */ - for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vdefs); i += 2) + for (i = 0; i < VARRAY_ACTIVE_SIZE (build_v_may_defs); i += 2) { - tree result = VARRAY_TREE (build_vdefs, i); + tree result = VARRAY_TREE (build_v_may_defs, i); if (var == result || (TREE_CODE (result) == SSA_NAME && var == SSA_NAME_VAR (result))) @@ -542,32 +613,32 @@ append_vdef (tree var, tree stmt, voperands_t prev_vops) } /* If the statement already had virtual definitions, see if any of the - existing VDEFs matches VAR. If so, re-use it, otherwise add a new - VDEF for VAR. */ + existing V_MAY_DEFs matches VAR. If so, re-use it, otherwise add a new + V_MAY_DEF for VAR. */ result = NULL_TREE; source = NULL_TREE; if (prev_vops) - for (i = 0; i < NUM_VDEFS (prev_vops->vdef_ops); i++) + for (i = 0; i < NUM_V_MAY_DEFS (prev_vops->v_may_def_ops); i++) { - result = VDEF_RESULT (prev_vops->vdef_ops, i); + result = V_MAY_DEF_RESULT (prev_vops->v_may_def_ops, i); if (result == var || (TREE_CODE (result) == SSA_NAME && SSA_NAME_VAR (result) == var)) { - source = VDEF_OP (prev_vops->vdef_ops, i); + source = V_MAY_DEF_OP (prev_vops->v_may_def_ops, i); break; } } - /* If no previous VDEF operand was found for VAR, create one now. */ + /* If no previous V_MAY_DEF operand was found for VAR, create one now. */ if (source == NULL_TREE) { result = var; source = var; } - VARRAY_PUSH_TREE (build_vdefs, result); - VARRAY_PUSH_TREE (build_vdefs, source); + VARRAY_PUSH_TREE (build_v_may_defs, result); + VARRAY_PUSH_TREE (build_v_may_defs, source); } @@ -626,6 +697,61 @@ append_vuse (tree var, tree stmt, voperands_t prev_vops) VARRAY_PUSH_TREE (build_vuses, var); } +/* Add VAR to the list of virtual must definitions for STMT. If PREV_VOPS + is not NULL, the existing entries are preserved and no new entries are + added here. This is done to preserve the SSA numbering of virtual + operands. */ + +static void +append_v_must_def (tree var, tree stmt, voperands_t prev_vops) +{ + stmt_ann_t ann; + size_t i; + bool found; + tree v_must_def; + +#ifdef ENABLE_CHECKING + if (check_build_stmt != stmt) + abort(); +#endif + + ann = stmt_ann (stmt); + + /* Don't allow duplicate entries. */ + for (i = 0; i < VARRAY_ACTIVE_SIZE (build_v_must_defs); i++) + { + tree v_must_def_var = VARRAY_TREE (build_v_must_defs, i); + if (var == v_must_def_var + || (TREE_CODE (v_must_def_var) == SSA_NAME + && var == SSA_NAME_VAR (v_must_def_var))) + return; + } + + /* If the statement already had virtual must defs, see if any of the + existing V_MUST_DEFs matches VAR. If so, re-use it, otherwise add a new + V_MUST_DEF for VAR. */ + found = false; + v_must_def = NULL_TREE; + if (prev_vops) + for (i = 0; i < NUM_V_MUST_DEFS (prev_vops->v_must_def_ops); i++) + { + v_must_def = V_MUST_DEF_OP (prev_vops->v_must_def_ops, i); + if (v_must_def == var + || (TREE_CODE (v_must_def) == SSA_NAME + && SSA_NAME_VAR (v_must_def) == var)) + { + found = true; + break; + } + } + + /* If VAR existed already in PREV_VOPS, re-use it. */ + if (found) + var = v_must_def; + + VARRAY_PUSH_TREE (build_v_must_defs, var); +} + /* External entry point which by-passes the previous vops mechanism. */ void @@ -676,12 +802,14 @@ get_stmt_operands (tree stmt) /* Before removing existing virtual operands, save them in PREV_VOPS so that we can re-use their SSA versions. */ - prev_vops.vdef_ops = VDEF_OPS (ann); + prev_vops.v_may_def_ops = V_MAY_DEF_OPS (ann); prev_vops.vuse_ops = VUSE_OPS (ann); + prev_vops.v_must_def_ops = V_MUST_DEF_OPS (ann); /* Dont free the previous values to memory since we're still using them. */ - free_vdefs (&(ann->vdef_ops), false); + free_v_may_defs (&(ann->v_may_def_ops), false); free_vuses (&(ann->vuse_ops), false); + free_v_must_defs (&(ann->v_must_def_ops), false); start_ssa_stmt_operands (stmt); @@ -690,7 +818,15 @@ get_stmt_operands (tree stmt) { case MODIFY_EXPR: get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none, &prev_vops); - get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, &prev_vops); + if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF + || TREE_CODE (TREE_OPERAND (stmt, 0)) == COMPONENT_REF + || TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR + || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR) + get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, + &prev_vops); + else + get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), + opf_is_def | opf_kill_def, &prev_vops); break; case COND_EXPR: @@ -792,8 +928,9 @@ get_stmt_operands (tree stmt) finalize_ssa_stmt_operands (stmt); /* Now free the previous virtual ops to memory. */ - free_vdefs (&(prev_vops.vdef_ops), true); + free_v_may_defs (&(prev_vops.v_may_def_ops), true); free_vuses (&(prev_vops.vuse_ops), true); + free_v_must_defs (&(prev_vops.v_must_def_ops), true); /* Clear the modified bit for STMT. Subsequent calls to get_stmt_operands for this statement will do nothing until the @@ -806,7 +943,7 @@ get_stmt_operands (tree stmt) /* Recursively scan the expression pointed by EXPR_P in statement STMT. FLAGS is one of the OPF_* constants modifying how to interpret the - operands found. PREV_VOPS is as in append_vdef and append_vuse. */ + operands found. PREV_VOPS is as in append_v_may_def and append_vuse. */ static void get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) @@ -1053,7 +1190,15 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) if (code == MODIFY_EXPR) { get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none, prev_vops); - get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def, prev_vops); + if (TREE_CODE (TREE_OPERAND (expr, 0)) == ARRAY_REF + || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF + || TREE_CODE (TREE_OPERAND (expr, 0)) == REALPART_EXPR + || TREE_CODE (TREE_OPERAND (expr, 0)) == IMAGPART_EXPR) + get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def, + prev_vops); + else + get_expr_operands (stmt, &TREE_OPERAND (expr, 0), + opf_is_def | opf_kill_def, prev_vops); return; } @@ -1104,7 +1249,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) operands. PREV_VOPS is used when adding virtual operands to statements that - already had them (See append_vdef and append_vuse). */ + already had them (See append_v_may_def and append_vuse). */ static void add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops) @@ -1193,9 +1338,21 @@ add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops) /* The variable is not aliased or it is an alias tag. */ if (flags & opf_is_def) { - append_vdef (var, stmt, prev_vops); if (v_ann->is_alias_tag) - s_ann->makes_aliased_stores = 1; + { + /* Alias tagged vars get regular V_MAY_DEF */ + s_ann->makes_aliased_stores = 1; + append_v_may_def (var, stmt, prev_vops); + } + 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, stmt, prev_vops); + else + /* Call-clobbered variables & memory tags get + V_MAY_DEF */ + append_v_may_def (var, stmt, prev_vops); } else { @@ -1220,10 +1377,10 @@ add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops) references to the members of the variable's alias set. This fixes the bug in gcc.c-torture/execute/20020503-1.c. */ if (v_ann->is_alias_tag) - append_vdef (var, stmt, prev_vops); + append_v_may_def (var, stmt, prev_vops); for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++) - append_vdef (VARRAY_TREE (aliases, i), stmt, prev_vops); + append_v_may_def (VARRAY_TREE (aliases, i), stmt, prev_vops); s_ann->makes_aliased_stores = 1; } @@ -1267,9 +1424,10 @@ add_call_clobber_ops (tree stmt, voperands_t prev_vops) call-clobbered variables. */ stmt_ann (stmt)->makes_clobbering_call = true; - /* If we had created .GLOBAL_VAR earlier, use it. Otherwise, add a VDEF - operand for every call clobbered variable. See compute_may_aliases for - the heuristic used to decide whether to create .GLOBAL_VAR or not. */ + /* If we had created .GLOBAL_VAR earlier, use it. Otherwise, add + a V_MAY_DEF operand for every call clobbered variable. See + compute_may_aliases for the heuristic used to decide whether + to create .GLOBAL_VAR or not. */ if (global_var) add_stmt_operand (&global_var, stmt, opf_is_def, prev_vops); else @@ -1280,7 +1438,8 @@ add_call_clobber_ops (tree stmt, voperands_t prev_vops) { tree var = referenced_var (i); - /* If VAR is read-only, don't add a VDEF, just a VUSE operand. */ + /* If VAR is read-only, don't add a V_MAY_DEF, just a + VUSE operand. */ if (!TREE_READONLY (var)) add_stmt_operand (&var, stmt, opf_is_def, prev_vops); else |