+2004-06-10 Brian Booth <bbooth@redhat.com>
+
+ * 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.
+
2004-06-10 Vladimir Makarov <vmakarov@redhat.com>
PR target/15653
variable @code{a}. Real definition are also known as @dfn{killing
definitions}. Similarly, the use of @code{a} reads all its bits.
-In contrast, virtual operands represent partial or ambiguous
-references to a variable. For instance, given
+In contrast, virtual operands are used with variables that can have
+a partial or ambiguous reference. This includes structures, arrays,
+globals, and aliased variables. In these cases, we have two types of
+definitions. For globals, structures, and arrays, we can determine from
+a statement whether a variable of these types has a killing definition.
+If the variable does, then the statement is marked as having a
+@dfn{must definition} of that variable. However, if a statement is only
+defining a part of the variable (ie. a field in a structure), or if we
+know that a statement might define the variable but we cannot say for sure,
+then we mark that statement as having a @dfn{may definition}. For
+instance, given
@smallexample
@{
p = &a;
else
p = &b;
- # a = VDEF <a>
- # b = VDEF <b>
+ # a = V_MAY_DEF <a>
+ # b = V_MAY_DEF <b>
*p = 5;
# VUSE <a>
@}
@end smallexample
-Notice that @code{VDEF} operands have two copies of the referenced
+Notice that @code{V_MAY_DEF} operands have two copies of the referenced
variable. This indicates that this is not a killing definition of
that variable. In this case we refer to it as a @dfn{may definition}
or @dfn{aliased store}. The presence of the second copy of the
-variable in the @code{VDEF} operand will become important when the
+variable in the @code{V_MAY_DEF} operand will become important when the
function is converted into SSA form. This will be used to link all
the non-killing definitions to prevent optimizations from making
incorrect assumptions about them.
Operands are collected by @file{tree-ssa-operands.c}. They are stored
inside each statement's annotation and can be accessed with
-@code{DEF_OPS}, @code{USE_OPS}, @code{VDEF_OPS} and @code{VUSE_OPS}.
-The following are all the accessor macros available to access USE
-operands. To access all the other operand arrays, just change the
-name accordingly:
+@code{DEF_OPS}, @code{USE_OPS}, @code{V_MAY_DEF_OPS},
+@code{V_MUST_DEF_OPS} and @code{VUSE_OPS}. The following are all the
+accessor macros available to access USE operands. To access all the
+other operand arrays, just change the name accordingly:
@defmac USE_OPS (@var{ann})
Returns the array of operands used by the statement with annotation
print_ops (tree stmt)
@{
vuse_optype vuses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
def_optype defs;
use_optype uses;
stmt_ann_t ann;
for (i = 0; i < NUM_USES (uses); i++)
print_generic_expr (stderr, USE_OP (uses, i), 0);
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
- print_generic_expr (stderr, VDEF_OP (vdefs, i), 0);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ print_generic_expr (stderr, V_MAY_DEF_OP (v_may_defs, i), 0);
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ print_generic_expr (stderr, V_MUST_DEF_OP (v_must_defs, i), 0);
vuses = VUSE_OPS (ann);
for (i = 0; i < NUM_VUSES (vuses); i++)
p_6 = &b;
# p_1 = PHI <p_4(1), p_6(2)>;
- # a_7 = VDEF <a_3>;
- # b_8 = VDEF <b_5>;
+ # a_7 = V_MAY_DEF <a_3>;
+ # b_8 = V_MAY_DEF <b_5>;
*p_1 = 3;
- # a_9 = VDEF <a_7>
+ # a_9 = V_MAY_DEF <a_7>
# VUSE <b_8>
a_9 = b_8 + 2;
+2004-06-10 Brian Booth <bbooth@redhat.com>
+
+ * gcc.dg/tree-ssa/20031015-1.c: Scan for
+ V_MAY_DEF instead of VDEF.
+ * gcc.dg/tree-ssa/20040517-1.c: Ditto.
+
2004-06-10 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/14957
return 0;
}
-/* { dg-final { scan-tree-dump-times "VDEF" 2 "alias" } } */
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF" 2 "alias" } } */
malloc functions may clobber global memory. Only the function result
does not alias any other pointer.
Hence, we must have a VDEF for a before and after the call to foo(). */
-/* { dg-final { scan-tree-dump-times "VDEF" 2 "ssa"} } */
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF" 1 "ssa"} } */
long num_phis;
long num_phi_args;
int max_num_phi_args;
- long num_vdefs;
+ long num_v_may_defs;
long num_vuses;
+ long num_v_must_defs;
};
size_t i;
use_optype uses;
vuse_optype vuses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
stmt_ann_t ann;
#ifdef ENABLE_CHECKING
add_immediate_use (imm_rdef_stmt, stmt);
}
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- tree vuse = VDEF_OP (vdefs, i);
+ tree vuse = V_MAY_DEF_OP (v_may_defs, i);
tree imm_rdef_stmt = SSA_NAME_DEF_STMT (vuse);
if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (vuse)))
add_immediate_use (imm_rdef_stmt, stmt);
stmt_ann_t ann = get_stmt_ann (old);
use_optype uses = USE_OPS (ann);
vuse_optype vuses = VUSE_OPS (ann);
- vdef_optype vdefs = VDEF_OPS (ann);
+ v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
unsigned int i;
/* Look at USE_OPS or VUSE_OPS according to FLAGS. */
for (i = 0; i < NUM_VUSES (vuses); i++)
redirect_immediate_use (VUSE_OP (vuses, i), old, new);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
- redirect_immediate_use (VDEF_OP (vdefs, i), old, new);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ redirect_immediate_use (V_MAY_DEF_OP (v_may_defs, i), old, new);
}
fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
SCALE (size), LABEL (size));
- size = dfa_stats.num_vdefs * sizeof (tree *);
+ size = dfa_stats.num_v_may_defs * sizeof (tree *);
total += size;
- fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs,
+ fprintf (file, fmt_str_1, "V_MAY_DEF operands", dfa_stats.num_v_may_defs,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_v_must_defs * sizeof (tree *);
+ total += size;
+ fprintf (file, fmt_str_1, "V_MUST_DEF operands", dfa_stats.num_v_must_defs,
SCALE (size), LABEL (size));
size = dfa_stats.num_phis * sizeof (struct tree_phi_node);
dfa_stats_p->num_stmt_anns++;
dfa_stats_p->num_defs += NUM_DEFS (DEF_OPS (ann));
dfa_stats_p->num_uses += NUM_USES (USE_OPS (ann));
- dfa_stats_p->num_vdefs += NUM_VDEFS (VDEF_OPS (ann));
+ dfa_stats_p->num_v_may_defs +=
+ NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann));
dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann));
+ dfa_stats_p->num_v_must_defs +=
+ NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann));
break;
}
add_referenced_var (var, NULL);
}
+/* Return true if V_MAY_DEFS_AFTER contains fewer entries than
+ V_MAY_DEFS_BEFORE. Note that this assumes that both varrays
+ are V_MAY_DEF operands for the same statement. */
+
+static inline bool
+v_may_defs_disappeared_p (v_may_def_optype v_may_defs_before,
+ v_may_def_optype v_may_defs_after)
+{
+ /* If there was nothing before, nothing could've disappeared. */
+ if (v_may_defs_before == NULL)
+ return false;
+
+ /* All/some of them gone. */
+ if (v_may_defs_after == NULL
+ || NUM_V_MAY_DEFS (v_may_defs_before) >
+ NUM_V_MAY_DEFS (v_may_defs_after))
+ return true;
+
+ return false;
+}
-/* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE.
- Note that this assumes that both varrays are VDEF operands for the same
- statement. */
+/* Return true if V_MUST_DEFS_AFTER contains fewer entries than
+ V_MUST_DEFS_BEFORE. Note that this assumes that both varrays
+ are V_MUST_DEF operands for the same statement. */
static inline bool
-vdefs_disappeared_p (vdef_optype vdefs_before, vdef_optype vdefs_after)
+v_must_defs_disappeared_p (v_must_def_optype v_must_defs_before,
+ v_must_def_optype v_must_defs_after)
{
/* If there was nothing before, nothing could've disappeared. */
- if (vdefs_before == NULL)
+ if (v_must_defs_before == NULL)
return false;
/* All/some of them gone. */
- if (vdefs_after == NULL
- || NUM_VDEFS (vdefs_before) > NUM_VDEFS (vdefs_after))
+ if (v_must_defs_after == NULL
+ || NUM_V_MUST_DEFS (v_must_defs_before) >
+ NUM_V_MUST_DEFS (v_must_defs_after))
return true;
return false;
{
def_optype defs;
use_optype uses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
vuse_optype vuses;
+ v_must_def_optype v_must_defs;
size_t i;
bitmap vars_in_vops_to_rename;
bool found_exposed_symbol = false;
- vdef_optype vdefs_before, vdefs_after;
+ v_may_def_optype v_may_defs_before, v_may_defs_after;
+ v_must_def_optype v_must_defs_before, v_must_defs_after;
stmt_ann_t ann;
vars_in_vops_to_rename = BITMAP_XMALLOC ();
rename them if there are not any newly exposed symbols in the
statement operands. */
ann = stmt_ann (stmt);
- vdefs_before = vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs_before = v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- tree var = VDEF_RESULT (vdefs, i);
+ tree var = V_MAY_DEF_RESULT (v_may_defs, i);
if (!DECL_P (var))
var = SSA_NAME_VAR (var);
bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid);
bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid);
}
+ v_must_defs_before = v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree var = V_MUST_DEF_OP (v_must_defs, i);
+ if (!DECL_P (var))
+ var = SSA_NAME_VAR (var);
+ bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid);
+ }
+
/* Now force an operand re-scan on the statement and mark any newly
exposed variables. */
modify_stmt (stmt);
}
}
- vdefs_after = vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs_after = v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- tree var = VDEF_RESULT (vdefs, i);
+ tree var = V_MAY_DEF_RESULT (v_may_defs, i);
if (DECL_P (var))
{
found_exposed_symbol = true;
bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
}
}
+
+ v_must_defs_after = v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree var = V_MUST_DEF_OP (v_must_defs, i);
+ if (DECL_P (var))
+ {
+ found_exposed_symbol = true;
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+ }
/* If we found any newly exposed symbols, or if there are fewer VDEF
operands in the statement, add the variables we had set in
vanishing VDEFs because in those cases, the names that were formerly
generated by this statement are not going to be available anymore. */
if (found_exposed_symbol
- || vdefs_disappeared_p (vdefs_before, vdefs_after))
+ || v_may_defs_disappeared_p (v_may_defs_before, v_may_defs_after)
+ || v_must_defs_disappeared_p (v_must_defs_before, v_must_defs_after))
bitmap_a_or_b (vars_to_rename, vars_to_rename, vars_in_vops_to_rename);
BITMAP_XFREE (vars_in_vops_to_rename);
return ann ? ann->use_ops : NULL;
}
-static inline vdef_optype
-get_vdef_ops (stmt_ann_t ann)
+static inline v_may_def_optype
+get_v_may_def_ops (stmt_ann_t ann)
{
- return ann ? ann->vdef_ops : NULL;
+ return ann ? ann->v_may_def_ops : NULL;
}
static inline vuse_optype
return ann ? ann->vuse_ops : NULL;
}
+static inline v_must_def_optype
+get_v_must_def_ops (stmt_ann_t ann)
+{
+ return ann ? ann->v_must_def_ops : NULL;
+}
+
static inline tree *
get_use_op_ptr (use_optype uses, unsigned int index)
{
}
static inline tree *
-get_vdef_result_ptr(vdef_optype vdefs, unsigned int index)
+get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
{
#ifdef ENABLE_CHECKING
- if (index >= vdefs->num_vdefs)
+ if (index >= v_may_defs->num_v_may_defs)
abort();
#endif
- return &(vdefs->vdefs[index * 2]);
+ return &(v_may_defs->v_may_defs[index * 2]);
}
static inline tree *
-get_vdef_op_ptr(vdef_optype vdefs, unsigned int index)
+get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
{
#ifdef ENABLE_CHECKING
- if (index >= vdefs->num_vdefs)
+ if (index >= v_may_defs->num_v_may_defs)
abort();
#endif
- return &(vdefs->vdefs[index * 2 + 1]);
+ return &(v_may_defs->v_may_defs[index * 2 + 1]);
}
static inline tree *
return &(vuses->vuses[index]);
}
+static inline tree *
+get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+ if (index >= v_must_defs->num_v_must_defs)
+ abort();
+#endif
+ return &(v_must_defs->v_must_defs[index]);
+}
+
static inline void
start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
{
struct def_optype_d * GTY (()) def_ops;
struct use_optype_d * GTY (()) use_ops;
- /* Virtual operands (VDEF and VUSE). */
- struct vdef_optype_d * GTY (()) vdef_ops;
+ /* Virtual operands (V_MAY_DEF, VUSE, and V_MUST_DEF). */
+ struct v_may_def_optype_d * GTY (()) v_may_def_ops;
struct vuse_optype_d * GTY (()) vuse_ops;
+ struct v_must_def_optype_d * GTY (()) v_must_def_ops;
/* Dataflow information. */
dataflow_t df;
static inline const char *get_filename (tree);
static inline bool is_exec_stmt (tree);
static inline bool is_label_stmt (tree);
-static inline vdef_optype get_vdef_ops (stmt_ann_t);
+static inline v_may_def_optype get_v_may_def_ops (stmt_ann_t);
static inline vuse_optype get_vuse_ops (stmt_ann_t);
static inline use_optype get_use_ops (stmt_ann_t);
static inline def_optype get_def_ops (stmt_ann_t);
{
struct mark_def_sites_global_data *gd = walk_data->global_data;
sbitmap kills = gd->kills;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
vuse_optype vuses;
def_optype defs;
use_optype uses;
}
/* Note that virtual definitions are irrelevant for computing KILLS
- because a VDEF does not constitute a killing definition of the
+ because a V_MAY_DEF does not constitute a killing definition of the
variable. However, the operand of a virtual definitions is a use
of the variable, so it may cause the variable to be considered
live-on-entry. */
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- if (prepare_operand_for_rename (VDEF_OP_PTR (vdefs, i), &uid, true))
+ if (prepare_operand_for_rename (V_MAY_DEF_OP_PTR (v_may_defs, i),
+ &uid, true))
{
/* If we do not already have an SSA_NAME for our destination,
then set the destination to the source. */
- if (TREE_CODE (VDEF_RESULT (vdefs, i)) != SSA_NAME)
- VDEF_RESULT (vdefs, i) = VDEF_OP (vdefs, i);
+ if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
+ V_MAY_DEF_RESULT (v_may_defs, i) = V_MAY_DEF_OP (v_may_defs, i);
+
+ set_livein_block (V_MAY_DEF_OP (v_may_defs, i), bb);
+ set_def_block (V_MAY_DEF_RESULT (v_may_defs, i), bb);
+ }
+ }
+
+ /* Now process the virtual must-defs made by this statement. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree *def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
- set_livein_block (VDEF_OP (vdefs, i), bb);
- set_def_block (VDEF_RESULT (vdefs, i), bb);
+ if (prepare_operand_for_rename (def_p, &uid, false))
+ {
+ set_def_block (*def_p, bb);
+ SET_BIT (kills, uid);
}
}
stmt_ann_t ann;
tree stmt;
vuse_optype vuses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
def_optype defs;
use_optype uses;
struct rewrite_block_data *bd;
defs = DEF_OPS (ann);
uses = USE_OPS (ann);
vuses = VUSE_OPS (ann);
- vdefs = VDEF_OPS (ann);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ v_must_defs = V_MUST_DEF_OPS (ann);
/* Step 1. Rewrite USES and VUSES in the statement. */
for (i = 0; i < NUM_USES (uses); i++)
}
/* Register new virtual definitions made by the statement. */
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- rewrite_operand (VDEF_OP_PTR (vdefs, i));
+ rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i));
- if (TREE_CODE (VDEF_RESULT (vdefs, i)) != SSA_NAME)
- *VDEF_RESULT_PTR (vdefs, i)
- = make_ssa_name (VDEF_RESULT (vdefs, i), stmt);
+ if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
+ *V_MAY_DEF_RESULT_PTR (v_may_defs, i)
+ = make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i), stmt);
/* FIXME: We shouldn't be registering new defs if the variable
doesn't need to be renamed. */
- register_new_def (VDEF_RESULT (vdefs, i), &bd->block_defs);
+ register_new_def (V_MAY_DEF_RESULT (v_may_defs, i), &bd->block_defs);
+ }
+
+ /* Register new virtual mustdefs made by the statement. */
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree *v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
+
+ if (TREE_CODE (*v_must_def_p) != SSA_NAME)
+ *v_must_def_p = make_ssa_name (*v_must_def_p, stmt);
+
+ /* FIXME: We shouldn't be registering new mustdefs if the variable
+ doesn't need to be renamed. */
+ register_new_def (*v_must_def_p, &bd->block_defs);
}
+
}
dependent on any virtual variable (via a VUSE) has a dependence added
to the special partition defined by VIRTUAL_PARTITION.
- Whenever a VDEF is seen, all expressions dependent this VIRTUAL_PARTITION
- are removed from consideration.
+ Whenever a V_MAY_DEF is seen, all expressions dependent this
+ VIRTUAL_PARTITION are removed from consideration.
At the end of a basic block, all expression are removed from consideration
in preparation for the next block.
value_expr_p pending_dependence;
} *temp_expr_table_p;
-/* Used to indicate a dependancy on VDEFs. */
+/* Used to indicate a dependancy on V_MAY_DEFs. */
#define VIRTUAL_PARTITION(table) (table->virtual_partition)
static temp_expr_table_p new_temp_expr_table (var_map);
if (DECL_HARD_REGISTER (SSA_NAME_VAR (def)))
return false;
- /* There must be no VDEFS. */
- if (NUM_VDEFS (VDEF_OPS (ann)) != 0)
+ /* There must be no V_MAY_DEFS. */
+ if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) != 0)
+ return false;
+
+ /* There must be no V_MUST_DEFS. */
+ if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) != 0)
return false;
/* Float expressions must go through memory if float-store is on. */
free_value_expr (tab, p);
}
- /* A VDEF kills any expression using a virtual operand. */
- if (NUM_VDEFS (VDEF_OPS (ann)) > 0)
+ /* A V_MAY_DEF kills any expression using a virtual operand. */
+ if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0)
+ kill_virtual_exprs (tab, true);
+
+ /* A V_MUST_DEF kills any expression using a virtual operand. */
+ if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0)
kill_virtual_exprs (tab, true);
}
}
{
size_t i;
stmt_ann_t ann = stmt_ann (stmt);
- vdef_optype vdefs = VDEF_OPS (ann);
+ v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
+ v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
vuse_optype vuses = VUSE_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
pp_string (buffer, "# ");
- dump_generic_node (buffer, VDEF_RESULT (vdefs, i), spc + 2, flags, false);
- pp_string (buffer, " = VDEF <");
- dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, false);
+ dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
+ spc + 2, flags, false);
+ pp_string (buffer, " = V_MAY_DEF <");
+ dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
+ spc + 2, flags, false);
+ pp_string (buffer, ">;");
+ newline_and_indent (buffer, spc);
+ }
+
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
+ pp_string (buffer, "# V_MUST_DEF <");
+ dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
pp_string (buffer, ">;");
newline_and_indent (buffer, spc);
}
return true;
}
-/* Mark all the variables in VDEF operands for STMT for renaming.
+/* Mark all the variables in V_MAY_DEF operands for STMT for renaming.
This becomes necessary when we modify all of a non-scalar. */
static void
-mark_all_vdefs (tree stmt)
+mark_all_v_may_defs (tree stmt)
{
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
size_t i, n;
get_stmt_operands (stmt);
- vdefs = VDEF_OPS (stmt_ann (stmt));
- n = NUM_VDEFS (vdefs);
+ v_may_defs = V_MAY_DEF_OPS (stmt_ann (stmt));
+ n = NUM_V_MAY_DEFS (v_may_defs);
for (i = 0; i < n; i++)
{
- tree sym = VDEF_RESULT (vdefs, i);
+ tree sym = V_MAY_DEF_RESULT (v_may_defs, i);
+ bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
+ }
+}
+
+/* Mark all the variables in V_MUST_DEF operands for STMT for renaming.
+ This becomes necessary when we modify all of a non-scalar. */
+
+static void
+mark_all_v_must_defs (tree stmt)
+{
+ v_must_def_optype v_must_defs;
+ size_t i, n;
+
+ get_stmt_operands (stmt);
+ v_must_defs = V_MUST_DEF_OPS (stmt_ann (stmt));
+ n = NUM_V_MUST_DEFS (v_must_defs);
+
+ for (i = 0; i < n; i++)
+ {
+ tree sym = V_MUST_DEF_OP (v_must_defs, i);
bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
}
}
/* Mark all the variables in VDEF operands for renaming, because
the VA_ARG_EXPR will now be in a different statement. */
- mark_all_vdefs (stmt);
+ mark_all_v_may_defs (stmt);
+ mark_all_v_must_defs (stmt);
/* Set RHS to be the new temporary TMP. */
rhs = tmp;
/* Otherwise, mark all the symbols in the VDEFs for the last
scalarized statement just created. Since all the statements
introduce the same VDEFs, we only need to check the last one. */
- mark_all_vdefs (tsi_stmt (tsi));
+ mark_all_v_may_defs (tsi_stmt (tsi));
+ mark_all_v_must_defs (tsi_stmt (tsi));
}
else
abort ();
/* If the statement has no virtual operands, then it doesn't make
structure references that we care about. */
- if (NUM_VDEFS (VDEF_OPS (ann)) == 0
- && NUM_VUSES (VUSE_OPS (ann)) == 0)
+ if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0
+ && NUM_VUSES (VUSE_OPS (ann)) == 0
+ && NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
continue;
/* Structure references may only appear in certain statements. */
if (is_sra_candidate_ref (lhs, false))
{
tree sym;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
scalarize_component_ref (stmt, &TREE_OPERAND (stmt, 0));
/* Mark the LHS to be renamed, as we have just removed the previous
- VDEF for AGGREGATE. The statement should have exactly one VDEF
- for variable AGGREGATE. */
- vdefs = STMT_VDEF_OPS (stmt);
- if (NUM_VDEFS (vdefs) != 1)
+ V_MAY_DEF for AGGREGATE. The statement should have exactly one
+ V_MAY_DEF for variable AGGREGATE. */
+ v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
+ if (NUM_V_MAY_DEFS (v_may_defs) != 1)
abort ();
- sym = SSA_NAME_VAR (VDEF_RESULT (vdefs, 0));
+ sym = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, 0));
bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
}
this variable is used to represent the clobbering effects of function
calls. In these cases, all the call clobbered variables in the program
are forced to alias this variable. This reduces compile times by not
- having to keep track of too many VDEF expressions at call sites. */
+ having to keep track of too many V_MAY_DEF expressions at call sites. */
tree global_var;
p_6 = &b;
# p_1 = PHI <p_4(1), p_6(2)>;
- # a_7 = VDEF <a_3>;
- # b_8 = VDEF <b_5>;
+ # a_7 = V_MAY_DEF <a_3>;
+ # b_8 = V_MAY_DEF <b_5>;
*p_1 = 3;
- # a_9 = VDEF <a_7>
+ # a_9 = V_MAY_DEF <a_7>
# VUSE <b_8>
a_9 = b_8 + 2;
{
use_optype uses;
def_optype defs;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
stmt_ann_t ann;
bitmap addr_taken;
tree stmt = bsi_stmt (si);
(VARRAY_UINT (ai->num_references, ann->uid))++;
}
- /* Mark variables in VDEF operands as being written to. */
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ /* Mark variables in V_MAY_DEF operands as being written to. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- tree op = VDEF_OP (vdefs, i);
+ tree op = V_MAY_DEF_OP (v_may_defs, i);
+ tree var = SSA_NAME_VAR (op);
+ var_ann_t ann = var_ann (var);
+ bitmap_set_bit (ai->written_vars, ann->uid);
+ }
+
+ /* Mark variables in V_MUST_DEF operands as being written to. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree op = V_MUST_DEF_OP (v_must_defs, i);
tree var = SSA_NAME_VAR (op);
var_ann_t ann = var_ann (var);
bitmap_set_bit (ai->written_vars, ann->uid);
p_5 = &a;
...
- # a_9 = VDEF <a_8>
+ # a_9 = V_MAY_DEF <a_8>
p_5->field = 0
... Several modifications to TMT.20 ...
# VUSE <a_9>
}
-/* Determine whether to use .GLOBAL_VAR to model call clobbering semantics. At
- every call site, we need to emit VDEF expressions to represent the
+/* Determine whether to use .GLOBAL_VAR to model call clobbering semantics. At
+ every call site, we need to emit V_MAY_DEF expressions to represent the
clobbering effects of the call for variables whose address escapes the
current function.
(.GLOBAL_VAR). This works well, but it ties the optimizer hands because
references to any call clobbered variable is a reference to .GLOBAL_VAR.
- The second approach is to emit a clobbering VDEF for every call-clobbered
- variable at call sites. This is the preferred way in terms of optimization
- opportunities but it may create too many VDEF operands if there are many
- call clobbered variables and function calls in the function.
+ The second approach is to emit a clobbering V_MAY_DEF for every
+ call-clobbered variable at call sites. This is the preferred way in terms
+ of optimization opportunities but it may create too many V_MAY_DEF operands
+ if there are many call clobbered variables and function calls in the
+ function.
To decide whether or not to use .GLOBAL_VAR we multiply the number of
function calls found by the number of call-clobbered variables. If that
size_t i;
stmt_ann_t ann;
def_optype defs;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
/* If the statement has already been deemed to be VARYING, don't simulate
it again. */
add_outgoing_control_edges (bb_for_stmt (stmt));
}
- /* Mark all VDEF operands VARYING. */
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
- def_to_varying (VDEF_RESULT (vdefs, i));
+ /* Mark all V_MAY_DEF operands VARYING. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ def_to_varying (V_MAY_DEF_RESULT (v_may_defs, i));
+
+ /* Mark all V_MUST_DEF operands VARYING. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ def_to_varying (V_MUST_DEF_OP (v_must_defs, i));
}
tree stmt;
stmt_ann_t ann;
def_optype defs;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
size_t x;
int vary;
}
DONT_SIMULATE_AGAIN (stmt) = vary;
- /* Mark all VDEF operands VARYING. */
- vdefs = VDEF_OPS (ann);
- for (x = 0; x < NUM_VDEFS (vdefs); x++)
+ /* Mark all V_MAY_DEF operands VARYING. */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
{
- tree res = VDEF_RESULT (vdefs, x);
+ tree res = V_MAY_DEF_RESULT (v_may_defs, x);
get_value (res)->lattice_val = VARYING;
SET_BIT (virtual_var, SSA_NAME_VERSION (res));
}
+
+ /* Mark all V_MUST_DEF operands VARYING. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
+ {
+ tree v_must_def = V_MUST_DEF_OP (v_must_defs, x);
+ get_value (v_must_def)->lattice_val = VARYING;
+ SET_BIT (virtual_var, SSA_NAME_VERSION (v_must_def));
+ }
}
for (e = bb->succ; e; e = e->succ_next)
if (TREE_SIDE_EFFECTS (expr))
{
def_optype defs;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
size_t i;
/* Fix all the SSA_NAMEs created by *STMT_P to point to its new
SSA_NAME_DEF_STMT (var) = *stmt_p;
}
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ tree var = V_MAY_DEF_RESULT (v_may_defs, i);
+ if (TREE_CODE (var) == SSA_NAME)
+ SSA_NAME_DEF_STMT (var) = *stmt_p;
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
{
- tree var = VDEF_RESULT (vdefs, i);
+ tree var = V_MUST_DEF_OP (v_must_defs, i);
if (TREE_CODE (var) == SSA_NAME)
SSA_NAME_DEF_STMT (var) = *stmt_p;
}
known value for that SSA_NAME (or NULL if no value is known).
Propagate values from CONST_AND_COPIES into the uses, vuses and
- vdef_ops of STMT. */
+ v_may_def_ops of STMT. */
bool
cprop_into_stmt (tree stmt, varray_type const_and_copies)
{
bool may_have_exposed_new_symbols = false;
stmt_ann_t ann = stmt_ann (stmt);
- size_t i, num_uses, num_vuses, num_vdefs;
+ size_t i, num_uses, num_vuses, num_v_may_defs;
vuse_optype vuses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
use_optype uses;
uses = USE_OPS (ann);
|= cprop_operand (ann, op_p, const_and_copies);
}
- vdefs = VDEF_OPS (ann);
- num_vdefs = NUM_VDEFS (vdefs);
- for (i = 0; i < num_vdefs; i++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ num_v_may_defs = NUM_V_MAY_DEFS (v_may_defs);
+ for (i = 0; i < num_v_may_defs; i++)
{
- tree *op_p = VDEF_OP_PTR (vdefs, i);
+ tree *op_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
if (TREE_CODE (*op_p) == SSA_NAME)
may_have_exposed_new_symbols
|= cprop_operand (ann, op_p, const_and_copies);
mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
{
def_optype defs;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
stmt_ann_t ann;
size_t i;
}
}
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- tree vdef = VDEF_RESULT (vdefs, i);
- if (need_to_preserve_store (vdef))
+ tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i);
+ if (need_to_preserve_store (v_may_def))
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
+ if (need_to_preserve_store (v_must_def))
{
mark_stmt_necessary (stmt, true);
return;
else
{
/* Propagate through the operands. Examine all the USE, VUSE and
- VDEF operands in this statement. Mark all the statements which
- feed this statement's uses as necessary. */
+ V_MAY_DEF operands in this statement. Mark all the statements
+ which feed this statement's uses as necessary. */
vuse_optype vuses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
use_optype uses;
stmt_ann_t ann;
size_t k;
for (k = 0; k < NUM_VUSES (vuses); k++)
mark_operand_necessary (VUSE_OP (vuses, k));
- /* The operands of VDEF expressions are also needed as they
+ /* The operands of V_MAY_DEF expressions are also needed as they
represent potential definitions that may reach this
- statement (VDEF operands allow us to follow def-def links). */
- vdefs = VDEF_OPS (ann);
- for (k = 0; k < NUM_VDEFS (vdefs); k++)
- mark_operand_necessary (VDEF_OP (vdefs, k));
+ statement (V_MAY_DEF operands allow us to follow def-def
+ links). */
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (k = 0; k < NUM_V_MAY_DEFS (v_may_defs); k++)
+ mark_operand_necessary (V_MAY_DEF_OP (v_may_defs, k));
}
}
}
{
unsigned int j;
def_optype defs;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
tree stmt = bsi_stmt (bsi);
stmt_ann_t ann = stmt_ann (stmt);
bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
}
- vdefs = VDEF_OPS (ann);
- for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
{
- tree op = VDEF_RESULT (vdefs, j);
- bitmap_set_bit (virtuals_to_rename, var_ann (op)->uid);
+ tree op = V_MAY_DEF_RESULT (v_may_defs, j);
+ bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
+ }
+
+ v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+ for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+ {
+ tree op = V_MUST_DEF_OP (v_must_defs, j);
+ bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
}
}
eliminate_redundant_computations (struct dom_walk_data *walk_data,
tree stmt, stmt_ann_t ann)
{
- vdef_optype vdefs = VDEF_OPS (ann);
+ v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
tree *expr_p, def = NULL_TREE;
bool insert = true;
tree cached_lhs;
|| ! def
|| TREE_CODE (def) != SSA_NAME
|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
- || NUM_VDEFS (vdefs) != 0)
+ || NUM_V_MAY_DEFS (v_may_defs) != 0)
insert = false;
/* Check if the expression has been computed before. */
if (rhs)
{
- vdef_optype vdefs = VDEF_OPS (ann);
+ v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
+ v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
/* Build a new statement with the RHS and LHS exchanged. */
new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs);
/* Clear out the virtual operands on the new statement, we are
going to set them explicitly below. */
remove_vuses (new);
- remove_vdefs (new);
+ remove_v_may_defs (new);
+ remove_v_must_defs (new);
start_ssa_stmt_operands (new);
/* For each VDEF on the original statement, we want to create a
- VUSE of the VDEF result on the new statement. */
- for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new
+ statement. */
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
{
- tree op = VDEF_RESULT (vdefs, j);
+ tree op = V_MAY_DEF_RESULT (v_may_defs, j);
+ add_vuse (op, new);
+ }
+
+ for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+ {
+ tree op = V_MUST_DEF_OP (v_must_defs, j);
add_vuse (op, new);
}
{
stmt_ann_t ann;
tree stmt;
- vdef_optype vdefs;
bool may_optimize_p;
bool may_have_exposed_new_symbols = false;
struct dom_walk_block_data *bd
get_stmt_operands (stmt);
ann = stmt_ann (stmt);
- vdefs = VDEF_OPS (ann);
opt_stats.num_stmts++;
may_have_exposed_new_symbols = false;
print_generic_stmt (dump_file, stmt, TDF_SLIM);
}
- /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */
+ /* Const/copy propagate into USES, VUSES and the RHS of V_MAY_DEFs. */
may_have_exposed_new_symbols = cprop_into_stmt (stmt, const_and_copies);
/* If the statement has been modified with constant replacements,
register_definitions_for_stmt (stmt_ann_t ann, varray_type *block_defs_p)
{
def_optype defs;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
unsigned int i;
defs = DEF_OPS (ann);
}
/* Register new virtual definitions made by the statement. */
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+ {
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (V_MAY_DEF_RESULT (v_may_defs, i), block_defs_p);
+ }
+
+ /* Register new virtual mustdefs made by the statement. */
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
{
/* FIXME: We shouldn't be registering new defs if the variable
doesn't need to be renamed. */
- register_new_def (VDEF_RESULT (vdefs, i), block_defs_p);
+ register_new_def (V_MUST_DEF_OP (v_must_defs, i), block_defs_p);
}
}
static void dse_record_phis (struct dom_walk_data *, basic_block);
static void dse_finalize_block (struct dom_walk_data *, basic_block);
static void fix_phi_uses (tree, tree);
-static void fix_stmt_vdefs (tree, tree);
+static void fix_stmt_v_may_defs (tree, tree);
static void record_voperand_set (bitmap, bitmap *, unsigned int);
/* Function indicating whether we ought to include information for 'var'
}
-/* Replace uses in PHI which match VDEF_RESULTs in STMT with the
- corresponding VDEF_OP in STMT. */
+/* Replace uses in PHI which match V_MAY_DEF_RESULTs in STMT with the
+ corresponding V_MAY_DEF_OP in STMT. */
static void
fix_phi_uses (tree phi, tree stmt)
{
stmt_ann_t ann = stmt_ann (stmt);
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
unsigned int i;
int j;
get_stmt_operands (stmt);
- vdefs = VDEF_OPS (ann);
+ v_may_defs = V_MAY_DEF_OPS (ann);
- /* Walk each VDEF in STMT. */
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ /* Walk each V_MAY_DEF in STMT. */
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- tree vdef = VDEF_RESULT (vdefs, i);
+ tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i);
- /* Find any uses in the PHI which match VDEF and replace
- them with the appropriate VDEF_OP. */
+ /* Find any uses in the PHI which match V_MAY_DEF and replace
+ them with the appropriate V_MAY_DEF_OP. */
for (j = 0; j < PHI_NUM_ARGS (phi); j++)
- if (vdef == PHI_ARG_DEF (phi, j))
- PHI_ARG_DEF (phi, j) = VDEF_OP (vdefs, i);
+ if (v_may_def == PHI_ARG_DEF (phi, j))
+ PHI_ARG_DEF (phi, j) = V_MAY_DEF_OP (v_may_defs, i);
}
}
-/* Replace the VDEF_OPs in STMT1 which match VDEF_RESULTs in STMT2 with
- the appropriate VDEF_OPs from STMT2. */
+/* Replace the V_MAY_DEF_OPs in STMT1 which match V_MAY_DEF_RESULTs
+ in STMT2 with the appropriate V_MAY_DEF_OPs from STMT2. */
static void
-fix_stmt_vdefs (tree stmt1, tree stmt2)
+fix_stmt_v_may_defs (tree stmt1, tree stmt2)
{
stmt_ann_t ann1 = stmt_ann (stmt1);
stmt_ann_t ann2 = stmt_ann (stmt2);
- vdef_optype vdefs1;
- vdef_optype vdefs2;
+ v_may_def_optype v_may_defs1;
+ v_may_def_optype v_may_defs2;
unsigned int i, j;
get_stmt_operands (stmt1);
get_stmt_operands (stmt2);
- vdefs1 = VDEF_OPS (ann1);
- vdefs2 = VDEF_OPS (ann2);
+ v_may_defs1 = V_MAY_DEF_OPS (ann1);
+ v_may_defs2 = V_MAY_DEF_OPS (ann2);
- /* Walk each VDEF_OP in stmt1. */
- for (i = 0; i < NUM_VDEFS (vdefs1); i++)
+ /* Walk each V_MAY_DEF_OP in stmt1. */
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs1); i++)
{
- tree vdef1 = VDEF_OP (vdefs1, i);
+ tree v_may_def1 = V_MAY_DEF_OP (v_may_defs1, i);
- /* Find the appropriate VDEF_RESULT in STMT2. */
- for (j = 0; j < NUM_VDEFS (vdefs2); j++)
+ /* Find the appropriate V_MAY_DEF_RESULT in STMT2. */
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs2); j++)
{
- if (vdef1 == VDEF_RESULT (vdefs2, j))
+ if (v_may_def1 == V_MAY_DEF_RESULT (v_may_defs2, j))
{
/* Update. */
- *VDEF_OP_PTR (vdefs1, i) = VDEF_OP (vdefs2, j);
+ *V_MAY_DEF_OP_PTR (v_may_defs1, i) =
+ V_MAY_DEF_OP (v_may_defs2, j);
break;
}
}
#ifdef ENABLE_CHECKING
- /* If we did not find a corresponding VDEF_RESULT, then something
+ /* If we did not find a corresponding V_MAY_DEF_RESULT, then something
has gone terribly wrong. */
- if (j == NUM_VDEFS (vdefs2))
+ if (j == NUM_V_MAY_DEFS (v_may_defs2))
abort ();
#endif
struct dse_global_data *dse_gd = walk_data->global_data;
tree stmt = bsi_stmt (bsi);
stmt_ann_t ann = stmt_ann (stmt);
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
get_stmt_operands (stmt);
- vdefs = VDEF_OPS (ann);
+ v_may_defs = V_MAY_DEF_OPS (ann);
/* If this statement has no virtual uses, then there is nothing
to do. */
- if (NUM_VDEFS (vdefs) == 0)
+ if (NUM_V_MAY_DEFS (v_may_defs) == 0)
return;
/* We know we have virtual definitions. If this is a MODIFY_EXPR, then
represents the only use of this store.
Note this does not handle the case where the store has
- multiple VDEFs which all reach a set of PHI nodes in the
+ multiple V_MAY_DEFs which all reach a set of PHI nodes in the
same block. */
while (num_uses == 1
&& TREE_CODE (use) == PHI_NODE
if (skipped_phi)
fix_phi_uses (skipped_phi, stmt);
else
- fix_stmt_vdefs (use, stmt);
+ fix_stmt_v_may_defs (use, stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
tree stmt;
stmt_ann_t ann;
vuse_optype vuses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
use_optype uses;
def_optype defs;
unsigned x;
#endif
}
- vdefs = VDEF_OPS (ann);
- for (x = 0; x < NUM_VDEFS (vdefs); x++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
{
- tree var = VDEF_OP (vdefs, x);
+ tree var = V_MAY_DEF_OP (v_may_defs, x);
set_is_used (var);
#if defined ENABLE_CHECKING
SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
#endif
}
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
+ {
+ tree var = V_MUST_DEF_OP (v_must_defs, x);
+ set_is_used (var);
+#if defined ENABLE_CHECKING
+ SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
+#endif
+ }
}
}
block_stmt_iterator bsi;
stmt_ann_t ann;
def_optype defs;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
vuse_optype vuses;
+ v_must_def_optype v_must_defs;
unsigned i;
for (stmt = phi_nodes (bb); stmt; stmt = TREE_CHAIN (stmt))
bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
}
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- var = SSA_NAME_VAR (VDEF_RESULT (vdefs, i));
+ var = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i));
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+
+ v_must_defs = V_MUST_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ var = SSA_NAME_VAR (V_MUST_DEF_OP (v_must_defs, i));
bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
}
/* We also need to rewrite vuses, since we will copy the statements
and the ssa versions could not be recovered in the copy. We do
- not have to do this for operands of VDEFS explicitly, since
+ not have to do this for operands of V_MAY_DEFS explicitly, since
they have the same underlying variable as the results. */
vuses = VUSE_OPS (ann);
for (i = 0; i < NUM_VUSES (vuses); i++)
/* 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
/* 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);
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 *
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
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)
{
}
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;
}
}
}
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)
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;
}
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
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
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;
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)
{
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
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();
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;
/* 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)))
}
/* 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);
}
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
/* 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);
{
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:
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
/* 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)
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;
}
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)
/* 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
{
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;
}
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
{
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
typedef use_optype_t *use_optype;
-typedef struct vdef_optype_d GTY(())
+typedef struct v_may_def_optype_d GTY(())
{
- unsigned num_vdefs;
- tree GTY((length ("%h.num_vdefs * 2"))) vdefs[1];
-} vdef_optype_t;
+ unsigned num_v_may_defs;
+ tree GTY((length ("%h.num_v_may_defs * 2"))) v_may_defs[1];
+} v_may_def_optype_t;
-typedef vdef_optype_t *vdef_optype;
+typedef v_may_def_optype_t *v_may_def_optype;
typedef struct vuse_optype_d GTY(())
{
typedef vuse_optype_t *vuse_optype;
+typedef struct v_must_def_optype_d GTY(())
+{
+ unsigned num_v_must_defs;
+ tree GTY((length("%h.num_v_must_defs"))) v_must_defs[1];
+} v_must_def_optype_t;
+
+typedef v_must_def_optype_t *v_must_def_optype;
+
#define USE_OPS(ANN) get_use_ops (ANN)
#define STMT_USE_OPS(STMT) get_use_ops (stmt_ann (STMT))
#define NUM_USES(OPS) ((OPS) ? (OPS)->num_uses : 0)
#define DEF_OP(OPS, I) (*(DEF_OP_PTR ((OPS), (I))))
-#define VDEF_OPS(ANN) get_vdef_ops (ANN)
-#define STMT_VDEF_OPS(STMT) get_vdef_ops (stmt_ann(STMT))
-#define NUM_VDEFS(OPS) ((OPS) ? (OPS)->num_vdefs : 0)
-#define VDEF_RESULT_PTR(OPS, I) get_vdef_result_ptr ((OPS), (I))
-#define VDEF_RESULT(OPS, I) (*(VDEF_RESULT_PTR ((OPS), (I))))
-#define VDEF_OP_PTR(OPS, I) get_vdef_op_ptr ((OPS), (I))
-#define VDEF_OP(OPS, I) (*(VDEF_OP_PTR ((OPS), (I))))
+#define V_MAY_DEF_OPS(ANN) get_v_may_def_ops (ANN)
+#define STMT_V_MAY_DEF_OPS(STMT) get_v_may_def_ops (stmt_ann(STMT))
+#define NUM_V_MAY_DEFS(OPS) ((OPS) ? (OPS)->num_v_may_defs : 0)
+#define V_MAY_DEF_RESULT_PTR(OPS, I) get_v_may_def_result_ptr ((OPS), (I))
+#define V_MAY_DEF_RESULT(OPS, I) (*(V_MAY_DEF_RESULT_PTR ((OPS), (I))))
+#define V_MAY_DEF_OP_PTR(OPS, I) get_v_may_def_op_ptr ((OPS), (I))
+#define V_MAY_DEF_OP(OPS, I) (*(V_MAY_DEF_OP_PTR ((OPS), (I))))
#define VUSE_OPS(ANN) get_vuse_ops (ANN)
#define VUSE_OP(OPS, I) (*(VUSE_OP_PTR ((OPS), (I))))
+#define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN)
+#define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT))
+#define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0)
+#define V_MUST_DEF_OP_PTR(OPS, I) get_v_must_def_op_ptr ((OPS), (I))
+#define V_MUST_DEF_OP(OPS, I) (*(V_MUST_DEF_OP_PTR ((OPS), (I))))
+
extern void init_ssa_operands (void);
extern void fini_ssa_operands (void);
extern void verify_start_operands (tree);
void add_vuse (tree, tree);
extern void get_stmt_operands (tree);
extern void remove_vuses (tree);
-extern void remove_vdefs (tree);
+extern void remove_v_may_defs (tree);
+extern void remove_v_must_defs (tree);
#endif /* GCC_TREE_SSA_OPERANDS_H */
else
{
remove_vuses (stmt_copy);
- remove_vdefs (stmt_copy);
+ remove_v_may_defs (stmt_copy);
+ remove_v_must_defs (stmt_copy);
}
if (pred->index < n_phi_preds)
{
size_t i, j, k;
- stmt_ann_t ann = stmt_ann (expr);
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
vuse_optype vuses;
def_optype defs;
- defs = DEF_OPS (ann);
- vdefs = VDEF_OPS (ann);
- if (NUM_DEFS (defs) == 0 && NUM_VDEFS (vdefs) == 0)
+ defs = STMT_DEF_OPS (expr);
+ v_may_defs = STMT_V_MAY_DEF_OPS (expr);
+ v_must_defs = STMT_V_MUST_DEF_OPS (expr);
+ if (NUM_DEFS (defs) == 0
+ && NUM_V_MAY_DEFS (v_may_defs) == 0
+ && NUM_V_MUST_DEFS (v_must_defs) == 0)
return;
for (j = 0; j < VARRAY_ACTIVE_SIZE (bexprs); j++)
}
}
- /* If we VDEF the VUSE of the expression, it's also a left
+ /* If we virtually define the variable itself,
+ it's a left occurrence. */
+ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+ {
+ if (names_match_p (V_MUST_DEF_OP (v_must_defs, i), ei->expr))
+ {
+ if (TREE_CODE (expr) == ASM_EXPR)
+ {
+ ei->loadpre_cand = false;
+ continue;
+ }
+ VARRAY_PUSH_TREE (ei->lefts, expr);
+ VARRAY_PUSH_TREE (ei->occurs, NULL);
+ VARRAY_PUSH_TREE (ei->kills, NULL);
+ }
+ }
+
+ /* If we V_MAY_DEF the VUSE of the expression, it's also a left
occurrence. */
random_occur = VARRAY_TREE (ei->occurs, 0);
ann = stmt_ann (random_occur);
vuses = VUSE_OPS (ann);
- if (NUM_VDEFS (vdefs) != 0)
+ if (NUM_V_MAY_DEFS (v_may_defs) != 0)
{
for (k = 0; k < NUM_VUSES (vuses); k++)
{
vuse_name = VUSE_OP (vuses, k);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- if (names_match_p (VDEF_OP (vdefs, i), vuse_name))
+ if (names_match_p (V_MAY_DEF_OP (v_may_defs, i), vuse_name))
{
VARRAY_PUSH_TREE (ei->lefts, expr);
VARRAY_PUSH_TREE (ei->occurs, NULL);
tree stmt;
stmt_ann_t ann;
unsigned int j;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
+ v_must_def_optype v_must_defs;
def_optype defs;
stmt = bsi_stmt (bsi);
ann = stmt_ann (stmt);
get_stmt_operands (stmt);
- vdefs = VDEF_OPS (ann);
- if (ann->makes_aliased_stores && NUM_VDEFS (vdefs) == 0)
- error ("Makes aliased stores, but no VDEFS");
-
- for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ if (ann->makes_aliased_stores && NUM_V_MAY_DEFS (v_may_defs) == 0)
+ error ("Makes aliased stores, but no V_MAY_DEFS");
+
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
{
- tree op = VDEF_RESULT (vdefs, j);
+ tree op = V_MAY_DEF_RESULT (v_may_defs, j);
if (is_gimple_reg (op))
{
error ("Found a virtual definition for a GIMPLE register");
}
err |= verify_def (bb, definition_block, op, stmt);
}
+
+ v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+ for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+ {
+ tree op = V_MUST_DEF_OP (v_must_defs, j);
+ if (is_gimple_reg (op))
+ {
+ error ("Found a virtual must-def for a GIMPLE register");
+ debug_generic_stmt (op);
+ debug_generic_stmt (stmt);
+ err = true;
+ }
+ err |= verify_def (bb, definition_block, op, stmt);
+ }
defs = DEF_OPS (ann);
for (j = 0; j < NUM_DEFS (defs); j++)
/* Now verify all the uses and vuses in every statement of the block.
- Remember, the RHS of a VDEF is a use as well. */
+ Remember, the RHS of a V_MAY_DEF is a use as well. */
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{
tree stmt = bsi_stmt (bsi);
stmt_ann_t ann = stmt_ann (stmt);
unsigned int j;
vuse_optype vuses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
use_optype uses;
vuses = VUSE_OPS (ann);
op, stmt, false);
}
- vdefs = VDEF_OPS (ann);
- for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
{
- tree op = VDEF_OP (vdefs, j);
+ tree op = V_MAY_DEF_OP (v_may_defs, j);
if (is_gimple_reg (op))
{
{
use_optype uses;
vuse_optype vuses;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
int i, j, n;
dataflow_t df;
tree stmt;
if (VUSE_OP (vuses, j) == var)
propagate_value (VUSE_OP_PTR (vuses, j), repl);
- vdefs = VDEF_OPS (ann);
- for (j = 0; j < (int) NUM_VDEFS (vdefs); j++)
- if (VDEF_OP (vdefs, j) == var)
- propagate_value (VDEF_OP_PTR (vdefs, j), repl);
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (j = 0; j < (int) NUM_V_MAY_DEFS (v_may_defs); j++)
+ if (V_MAY_DEF_OP (v_may_defs, j) == var)
+ propagate_value (V_MAY_DEF_OP_PTR (v_may_defs, j), repl);
}
modify_stmt (stmt);
/* If the statement has virtual operands, fail. */
ann = stmt_ann (stmt);
- if (NUM_VDEFS (VDEF_OPS (ann))
+ if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann))
+ || NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann))
|| NUM_VUSES (VUSE_OPS (ann)))
return;
}
edge e;
tree phi;
stmt_ann_t ann;
- vdef_optype vdefs;
+ v_may_def_optype v_may_defs;
unsigned i;
stmt = bsi_stmt (t->call_bsi);
}
/* Add phi nodes for the call clobbered variables. */
- vdefs = VDEF_OPS (ann);
- for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ v_may_defs = V_MAY_DEF_OPS (ann);
+ for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{
- param = SSA_NAME_VAR (VDEF_RESULT (vdefs, i));
+ param = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i));
for (phi = phi_nodes (first); phi; phi = TREE_CHAIN (phi))
if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
break;
abort ();
}
- add_phi_arg (&phi, VDEF_OP (vdefs, i), e);
+ add_phi_arg (&phi, V_MAY_DEF_OP (v_may_defs, i), e);
}
/* Update the values of accumulators. */