summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2010-03-12 13:27:43 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2010-03-12 13:27:43 +0000
commitc77c64d83a5b21e78670c99205aa9d450968554f (patch)
treee12fe17c4daff632e72812078a4cb3dd45be7118
parentf24c0e3a57a4720d43000eacaa57c61fd49d79c4 (diff)
downloadgcc-c77c64d83a5b21e78670c99205aa9d450968554f.tar.gz
* cselib.c (LONG_TERM_PRESERVED_VALUE_P): Remove.
(cselib_preserve_definitely, cselib_clear_preserve): Remove. (cselib_preserve_only_values): Remove retain argument, don't traverse hash table with cselib_{preserve_definitely,clear_preserve}. * cselib.h (cselib_preserve_only_values): Remove retain argument. * var-tracking.c (micro_operation): Move insn field before union. Add DEF_VEC_O and DEF_VEC_ALLOC_O for this type. (struct variable_tracking_info_def): Remove n_mos field, change mos into a vector of micro_operations. (count_uses, count_uses_1, count_stores, count_with_sets): Remove. (bb_stack_adjust_offset, log_op_type, add_uses, add_stores, compute_bb_dataflow, emit_notes_in_bb): Adjust for VTI (bb)->mos changing into a vector. (add_with_sets): Likewise. Ensure MO_VAL_USE uops from add_stores come before all other uops generated by add_stores. (vt_add_function_parameters): Adjust for cselib_preserve_only_values argument removal. (vt_initialize): Likewise. Adjust for VTI (bb)->mos changing into a vector. Run just one pass over the bbs instead of separate counting and computation phase. (vt_finalize): Free VTI (bb)->mos vector instead of array. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157403 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/cselib.c43
-rw-r--r--gcc/cselib.h2
-rw-r--r--gcc/var-tracking.c569
4 files changed, 214 insertions, 422 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 481a2480eb8..ce51db69c8c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,27 @@
2010-03-12 Jakub Jelinek <jakub@redhat.com>
+ * cselib.c (LONG_TERM_PRESERVED_VALUE_P): Remove.
+ (cselib_preserve_definitely, cselib_clear_preserve): Remove.
+ (cselib_preserve_only_values): Remove retain argument, don't
+ traverse hash table with cselib_{preserve_definitely,clear_preserve}.
+ * cselib.h (cselib_preserve_only_values): Remove retain argument.
+ * var-tracking.c (micro_operation): Move insn field before union.
+ Add DEF_VEC_O and DEF_VEC_ALLOC_O for this type.
+ (struct variable_tracking_info_def): Remove n_mos field, change
+ mos into a vector of micro_operations.
+ (count_uses, count_uses_1, count_stores, count_with_sets): Remove.
+ (bb_stack_adjust_offset, log_op_type, add_uses, add_stores,
+ compute_bb_dataflow, emit_notes_in_bb): Adjust for VTI (bb)->mos
+ changing into a vector.
+ (add_with_sets): Likewise. Ensure MO_VAL_USE uops from add_stores
+ come before all other uops generated by add_stores.
+ (vt_add_function_parameters): Adjust for cselib_preserve_only_values
+ argument removal.
+ (vt_initialize): Likewise. Adjust for VTI (bb)->mos changing into
+ a vector. Run just one pass over the bbs instead of separate counting
+ and computation phase.
+ (vt_finalize): Free VTI (bb)->mos vector instead of array.
+
PR debug/43329
* tree-inline.c (remap_decls): Put old_var rather than origin_var
into *nonlocalized_list vector.
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 515fc328463..f63ea3f5f1c 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -1,6 +1,6 @@
/* Common subexpression elimination library for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
@@ -155,8 +155,6 @@ void (*cselib_record_sets_hook) (rtx insn, struct cselib_set *sets,
#define PRESERVED_VALUE_P(RTX) \
(RTL_FLAG_CHECK1("PRESERVED_VALUE_P", (RTX), VALUE)->unchanging)
-#define LONG_TERM_PRESERVED_VALUE_P(RTX) \
- (RTL_FLAG_CHECK1("LONG_TERM_PRESERVED_VALUE_P", (RTX), VALUE)->in_struct)
@@ -436,51 +434,14 @@ cselib_preserved_value_p (cselib_val *v)
return PRESERVED_VALUE_P (v->val_rtx);
}
-/* Mark preserved values as preserved for the long term. */
-
-static int
-cselib_preserve_definitely (void **slot, void *info ATTRIBUTE_UNUSED)
-{
- cselib_val *v = (cselib_val *)*slot;
-
- if (PRESERVED_VALUE_P (v->val_rtx)
- && !LONG_TERM_PRESERVED_VALUE_P (v->val_rtx))
- LONG_TERM_PRESERVED_VALUE_P (v->val_rtx) = true;
-
- return 1;
-}
-
-/* Clear the preserve marks for values not preserved for the long
- term. */
-
-static int
-cselib_clear_preserve (void **slot, void *info ATTRIBUTE_UNUSED)
-{
- cselib_val *v = (cselib_val *)*slot;
-
- if (PRESERVED_VALUE_P (v->val_rtx)
- && !LONG_TERM_PRESERVED_VALUE_P (v->val_rtx))
- {
- PRESERVED_VALUE_P (v->val_rtx) = false;
- if (!v->locs)
- n_useless_values++;
- }
-
- return 1;
-}
-
/* Clean all non-constant expressions in the hash table, but retain
their values. */
void
-cselib_preserve_only_values (bool retain)
+cselib_preserve_only_values (void)
{
int i;
- htab_traverse (cselib_hash_table,
- retain ? cselib_preserve_definitely : cselib_clear_preserve,
- NULL);
-
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
cselib_invalidate_regno (i, reg_raw_mode[i]);
diff --git a/gcc/cselib.h b/gcc/cselib.h
index 2cdf6ade10b..67e59920254 100644
--- a/gcc/cselib.h
+++ b/gcc/cselib.h
@@ -91,6 +91,6 @@ extern void cselib_reset_table (unsigned int);
extern unsigned int cselib_get_next_uid (void);
extern void cselib_preserve_value (cselib_val *);
extern bool cselib_preserved_value_p (cselib_val *);
-extern void cselib_preserve_only_values (bool);
+extern void cselib_preserve_only_values (void);
extern void dump_cselib_table (FILE *);
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index ece77902793..430e16830a8 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -169,6 +169,13 @@ typedef struct micro_operation_def
/* Type of micro operation. */
enum micro_operation_type type;
+ /* The instruction which the micro operation is in, for MO_USE,
+ MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
+ instruction or note in the original flow (before any var-tracking
+ notes are inserted, to simplify emission of notes), for MO_SET
+ and MO_CLOBBER. */
+ rtx insn;
+
union {
/* Location. For MO_SET and MO_COPY, this is the SET that
performs the assignment, if known, otherwise it is the target
@@ -181,15 +188,11 @@ typedef struct micro_operation_def
/* Stack adjustment. */
HOST_WIDE_INT adjust;
} u;
-
- /* The instruction which the micro operation is in, for MO_USE,
- MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
- instruction or note in the original flow (before any var-tracking
- notes are inserted, to simplify emission of notes), for MO_SET
- and MO_CLOBBER. */
- rtx insn;
} micro_operation;
+DEF_VEC_O(micro_operation);
+DEF_VEC_ALLOC_O(micro_operation,heap);
+
/* A declaration of a variable, or an RTL value being handled like a
declaration. */
typedef void *decl_or_value;
@@ -258,11 +261,8 @@ typedef struct dataflow_set_def
needed for variable tracking. */
typedef struct variable_tracking_info_def
{
- /* Number of micro operations stored in the MOS array. */
- int n_mos;
-
- /* The array of micro operations. */
- micro_operation *mos;
+ /* The vector of micro operations. */
+ VEC(micro_operation, heap) *mos;
/* The IN and OUT set for dataflow analysis. */
dataflow_set in;
@@ -453,9 +453,6 @@ static void dataflow_set_destroy (dataflow_set *);
static bool contains_symbol_ref (rtx);
static bool track_expr_p (tree, bool);
static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
-static int count_uses (rtx *, void *);
-static void count_uses_1 (rtx *, void *);
-static void count_stores (rtx, const_rtx, void *);
static int add_uses (rtx *, void *);
static void add_uses_1 (rtx *, void *);
static void add_stores (rtx, const_rtx, void *);
@@ -626,20 +623,18 @@ static void
bb_stack_adjust_offset (basic_block bb)
{
HOST_WIDE_INT offset;
- int i;
+ unsigned int i;
+ micro_operation *mo;
offset = VTI (bb)->in.stack_adjust;
- for (i = 0; i < VTI (bb)->n_mos; i++)
+ for (i = 0; VEC_iterate (micro_operation, VTI (bb)->mos, i, mo); i++)
{
- if (VTI (bb)->mos[i].type == MO_ADJUST)
- offset += VTI (bb)->mos[i].u.adjust;
- else if (VTI (bb)->mos[i].type != MO_CALL)
+ if (mo->type == MO_ADJUST)
+ offset += mo->u.adjust;
+ else if (mo->type != MO_CALL)
{
- if (MEM_P (VTI (bb)->mos[i].u.loc))
- {
- VTI (bb)->mos[i].u.loc
- = adjust_stack_reference (VTI (bb)->mos[i].u.loc, -offset);
- }
+ if (MEM_P (mo->u.loc))
+ mo->u.loc = adjust_stack_reference (mo->u.loc, -offset);
}
}
VTI (bb)->out.stack_adjust = offset;
@@ -4489,118 +4484,12 @@ log_op_type (rtx x, basic_block bb, rtx insn,
enum micro_operation_type mopt, FILE *out)
{
fprintf (out, "bb %i op %i insn %i %s ",
- bb->index, VTI (bb)->n_mos - 1,
+ bb->index, VEC_length (micro_operation, VTI (bb)->mos),
INSN_UID (insn), micro_operation_type_name[mopt]);
print_inline_rtx (out, x, 2);
fputc ('\n', out);
}
-/* Count uses (register and memory references) LOC which will be tracked.
- INSN is instruction which the LOC is part of. */
-
-static int
-count_uses (rtx *ploc, void *cuip)
-{
- rtx loc = *ploc;
- struct count_use_info *cui = (struct count_use_info *) cuip;
- enum micro_operation_type mopt = use_type (loc, cui, NULL);
-
- if (mopt != MO_CLOBBER)
- {
- cselib_val *val;
- enum machine_mode mode = GET_MODE (loc);
-
- switch (mopt)
- {
- case MO_VAL_LOC:
- loc = PAT_VAR_LOCATION_LOC (loc);
- if (VAR_LOC_UNKNOWN_P (loc))
- break;
- /* Fall through. */
-
- case MO_VAL_USE:
- case MO_VAL_SET:
- if (MEM_P (loc)
- && !REG_P (XEXP (loc, 0)) && !MEM_P (XEXP (loc, 0)))
- {
- enum machine_mode address_mode
- = targetm.addr_space.address_mode (MEM_ADDR_SPACE (loc));
- val = cselib_lookup (XEXP (loc, 0), address_mode, 0);
-
- if (val && !cselib_preserved_value_p (val))
- {
- VTI (cui->bb)->n_mos++;
- cselib_preserve_value (val);
- if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (XEXP (loc, 0), cui->bb, cui->insn,
- MO_VAL_USE, dump_file);
- }
- }
-
- val = find_use_val (loc, mode, cui);
- if (val)
- {
- if (mopt == MO_VAL_SET
- && GET_CODE (PATTERN (cui->insn)) == COND_EXEC
- && (REG_P (loc)
- || (MEM_P (loc)
- && (use_type (loc, NULL, NULL) == MO_USE
- || cui->sets))))
- {
- cselib_val *oval = cselib_lookup (loc, GET_MODE (loc), 0);
-
- gcc_assert (oval != val);
- gcc_assert (REG_P (loc) || MEM_P (loc));
-
- if (!cselib_preserved_value_p (oval))
- {
- VTI (cui->bb)->n_mos++;
- cselib_preserve_value (oval);
- if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (loc, cui->bb, cui->insn,
- MO_VAL_USE, dump_file);
- }
- }
-
- cselib_preserve_value (val);
- }
- else
- gcc_assert (mopt == MO_VAL_LOC
- || (mopt == MO_VAL_SET && cui->store_p));
-
- break;
-
- default:
- break;
- }
-
- VTI (cui->bb)->n_mos++;
- if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (loc, cui->bb, cui->insn, mopt, dump_file);
- }
-
- return 0;
-}
-
-/* Helper function for finding all uses of REG/MEM in X in CUI's
- insn. */
-
-static void
-count_uses_1 (rtx *x, void *cui)
-{
- for_each_rtx (x, count_uses, cui);
-}
-
-/* Count stores (register and memory references) LOC which will be
- tracked. CUI is a count_use_info object containing the instruction
- which the LOC is part of. */
-
-static void
-count_stores (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *cui)
-{
- count_uses (&loc, cui);
-}
-
/* Adjust sets if needed. Currently this optimizes read-only MEM loads
if REG_EQUAL/REG_EQUIV note is present. */
@@ -4625,35 +4514,6 @@ adjust_sets (rtx insn, struct cselib_set *sets, int n_sets)
}
}
-/* Callback for cselib_record_sets_hook, that counts how many micro
- operations it takes for uses and stores in an insn after
- cselib_record_sets has analyzed the sets in an insn, but before it
- modifies the stored values in the internal tables, unless
- cselib_record_sets doesn't call it directly (perhaps because we're
- not doing cselib in the first place, in which case sets and n_sets
- will be 0). */
-
-static void
-count_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
-{
- basic_block bb = BLOCK_FOR_INSN (insn);
- struct count_use_info cui;
-
- cselib_hook_called = true;
-
- adjust_sets (insn, sets, n_sets);
-
- cui.insn = insn;
- cui.bb = bb;
- cui.sets = sets;
- cui.n_sets = n_sets;
-
- cui.store_p = false;
- note_uses (&PATTERN (insn), count_uses_1, &cui);
- cui.store_p = true;
- note_stores (PATTERN (insn), count_stores, &cui);
-}
-
/* Tell whether the CONCAT used to holds a VALUE and its location
needs value resolution, i.e., an attempt of mapping the location
back to other incoming values. */
@@ -4679,9 +4539,7 @@ count_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
/* All preserved VALUEs. */
static VEC (rtx, heap) *preserved_values;
-/* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.
- This must be only called when cselib_preserve_only_values will be called
- with true, the counting phase must use cselib_preserve_value. */
+/* Ensure VAL is preserved and remember it in a vector for vt_emit_notes. */
static void
preserve_value (cselib_val *val)
@@ -4704,11 +4562,11 @@ add_uses (rtx *ploc, void *data)
if (type != MO_CLOBBER)
{
basic_block bb = cui->bb;
- micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+ micro_operation mo;
- mo->type = type;
- mo->u.loc = type == MO_USE ? var_lowpart (mode, loc) : loc;
- mo->insn = cui->insn;
+ mo.type = type;
+ mo.u.loc = type == MO_USE ? var_lowpart (mode, loc) : loc;
+ mo.insn = cui->insn;
if (type == MO_VAL_LOC)
{
@@ -4729,19 +4587,17 @@ add_uses (rtx *ploc, void *data)
if (val && !cselib_preserved_value_p (val))
{
- micro_operation *mon = VTI (bb)->mos + VTI (bb)->n_mos++;
- mon->type = mo->type;
- mon->u.loc = mo->u.loc;
- mon->insn = mo->insn;
+ micro_operation moa;
preserve_value (val);
- mo->type = MO_VAL_USE;
mloc = cselib_subst_to_values (XEXP (mloc, 0));
- mo->u.loc = gen_rtx_CONCAT (address_mode,
+ moa.type = MO_VAL_USE;
+ moa.insn = cui->insn;
+ moa.u.loc = gen_rtx_CONCAT (address_mode,
val->val_rtx, mloc);
if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (mo->u.loc, cui->bb, cui->insn,
- mo->type, dump_file);
- mo = mon;
+ log_op_type (moa.u.loc, cui->bb, cui->insn,
+ moa.type, dump_file);
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &moa);
}
}
@@ -4778,7 +4634,7 @@ add_uses (rtx *ploc, void *data)
PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
}
- mo->u.loc = oloc;
+ mo.u.loc = oloc;
}
else if (type == MO_VAL_USE)
{
@@ -4800,20 +4656,17 @@ add_uses (rtx *ploc, void *data)
if (val && !cselib_preserved_value_p (val))
{
- micro_operation *mon = VTI (bb)->mos + VTI (bb)->n_mos++;
- mon->type = mo->type;
- mon->u.loc = mo->u.loc;
- mon->insn = mo->insn;
+ micro_operation moa;
preserve_value (val);
- mo->type = MO_VAL_USE;
mloc = cselib_subst_to_values (XEXP (mloc, 0));
- mo->u.loc = gen_rtx_CONCAT (address_mode,
+ moa.type = MO_VAL_USE;
+ moa.insn = cui->insn;
+ moa.u.loc = gen_rtx_CONCAT (address_mode,
val->val_rtx, mloc);
- mo->insn = cui->insn;
if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (mo->u.loc, cui->bb, cui->insn,
- mo->type, dump_file);
- mo = mon;
+ log_op_type (moa.u.loc, cui->bb, cui->insn,
+ moa.type, dump_file);
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &moa);
}
}
@@ -4846,13 +4699,13 @@ add_uses (rtx *ploc, void *data)
else
oloc = val->val_rtx;
- mo->u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
+ mo.u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
if (type2 == MO_USE)
- VAL_HOLDS_TRACK_EXPR (mo->u.loc) = 1;
+ VAL_HOLDS_TRACK_EXPR (mo.u.loc) = 1;
if (!cselib_preserved_value_p (val))
{
- VAL_NEEDS_RESOLUTION (mo->u.loc) = 1;
+ VAL_NEEDS_RESOLUTION (mo.u.loc) = 1;
preserve_value (val);
}
}
@@ -4860,7 +4713,8 @@ add_uses (rtx *ploc, void *data)
gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);
if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (mo->u.loc, cui->bb, cui->insn, mo->type, dump_file);
+ log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
}
return 0;
@@ -4985,7 +4839,7 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
enum machine_mode mode = VOIDmode, mode2;
struct count_use_info *cui = (struct count_use_info *)cuip;
basic_block bb = cui->bb;
- micro_operation *mo;
+ micro_operation mo;
rtx oloc = loc, nloc, src = NULL;
enum micro_operation_type type = use_type (loc, cui, &mode);
bool track_p = false;
@@ -5000,14 +4854,12 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (REG_P (loc))
{
- mo = VTI (bb)->mos + VTI (bb)->n_mos++;
-
if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
|| !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
|| GET_CODE (expr) == CLOBBER)
{
- mo->type = MO_CLOBBER;
- mo->u.loc = loc;
+ mo.type = MO_CLOBBER;
+ mo.u.loc = loc;
}
else
{
@@ -5020,8 +4872,8 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (src == NULL)
{
- mo->type = MO_SET;
- mo->u.loc = loc;
+ mo.type = MO_SET;
+ mo.u.loc = loc;
}
else
{
@@ -5030,20 +4882,18 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (SET_SRC (expr) != src)
xexpr = gen_rtx_SET (VOIDmode, loc, src);
if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
- mo->type = MO_COPY;
+ mo.type = MO_COPY;
else
- mo->type = MO_SET;
- mo->u.loc = xexpr;
+ mo.type = MO_SET;
+ mo.u.loc = xexpr;
}
}
- mo->insn = cui->insn;
+ mo.insn = cui->insn;
}
else if (MEM_P (loc)
&& ((track_p = use_type (loc, NULL, &mode2) == MO_USE)
|| cui->sets))
{
- mo = VTI (bb)->mos + VTI (bb)->n_mos++;
-
if (MEM_P (loc) && type == MO_VAL_SET
&& !REG_P (XEXP (loc, 0)) && !MEM_P (XEXP (loc, 0)))
{
@@ -5055,21 +4905,21 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (val && !cselib_preserved_value_p (val))
{
preserve_value (val);
- mo->type = MO_VAL_USE;
+ mo.type = MO_VAL_USE;
mloc = cselib_subst_to_values (XEXP (mloc, 0));
- mo->u.loc = gen_rtx_CONCAT (address_mode, val->val_rtx, mloc);
- mo->insn = cui->insn;
+ mo.u.loc = gen_rtx_CONCAT (address_mode, val->val_rtx, mloc);
+ mo.insn = cui->insn;
if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (mo->u.loc, cui->bb, cui->insn,
- mo->type, dump_file);
- mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+ log_op_type (mo.u.loc, cui->bb, cui->insn,
+ mo.type, dump_file);
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
}
}
if (GET_CODE (expr) == CLOBBER || !track_p)
{
- mo->type = MO_CLOBBER;
- mo->u.loc = track_p ? var_lowpart (mode2, loc) : loc;
+ mo.type = MO_CLOBBER;
+ mo.u.loc = track_p ? var_lowpart (mode2, loc) : loc;
}
else
{
@@ -5082,8 +4932,8 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (src == NULL)
{
- mo->type = MO_SET;
- mo->u.loc = loc;
+ mo.type = MO_SET;
+ mo.u.loc = loc;
}
else
{
@@ -5094,13 +4944,13 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (same_variable_part_p (SET_SRC (xexpr),
MEM_EXPR (loc),
INT_MEM_OFFSET (loc)))
- mo->type = MO_COPY;
+ mo.type = MO_COPY;
else
- mo->type = MO_SET;
- mo->u.loc = xexpr;
+ mo.type = MO_SET;
+ mo.u.loc = xexpr;
}
}
- mo->insn = cui->insn;
+ mo.insn = cui->insn;
}
else
return;
@@ -5128,23 +4978,24 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
if (!cselib_preserved_value_p (oval))
{
- micro_operation *nmo = VTI (bb)->mos + VTI (bb)->n_mos++;
+ micro_operation moa;
preserve_value (oval);
- nmo->type = MO_VAL_USE;
- nmo->u.loc = gen_rtx_CONCAT (mode, oval->val_rtx, oloc);
- VAL_NEEDS_RESOLUTION (nmo->u.loc) = 1;
- nmo->insn = mo->insn;
+ moa.type = MO_VAL_USE;
+ moa.u.loc = gen_rtx_CONCAT (mode, oval->val_rtx, oloc);
+ VAL_NEEDS_RESOLUTION (moa.u.loc) = 1;
+ moa.insn = cui->insn;
if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (nmo->u.loc, cui->bb, cui->insn,
- nmo->type, dump_file);
+ log_op_type (moa.u.loc, cui->bb, cui->insn,
+ moa.type, dump_file);
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &moa);
}
resolve = false;
}
- else if (resolve && GET_CODE (mo->u.loc) == SET)
+ else if (resolve && GET_CODE (mo.u.loc) == SET)
{
src = get_adjusted_src (cui, SET_SRC (expr));
nloc = replace_expr_with_values (src);
@@ -5157,30 +5008,30 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
}
if (nloc)
- oloc = gen_rtx_SET (GET_MODE (mo->u.loc), oloc, nloc);
+ oloc = gen_rtx_SET (GET_MODE (mo.u.loc), oloc, nloc);
else
{
- if (oloc == SET_DEST (mo->u.loc))
+ if (oloc == SET_DEST (mo.u.loc))
/* No point in duplicating. */
- oloc = mo->u.loc;
- if (!REG_P (SET_SRC (mo->u.loc)))
+ oloc = mo.u.loc;
+ if (!REG_P (SET_SRC (mo.u.loc)))
resolve = false;
}
}
else if (!resolve)
{
- if (GET_CODE (mo->u.loc) == SET
- && oloc == SET_DEST (mo->u.loc))
+ if (GET_CODE (mo.u.loc) == SET
+ && oloc == SET_DEST (mo.u.loc))
/* No point in duplicating. */
- oloc = mo->u.loc;
+ oloc = mo.u.loc;
}
else
resolve = false;
loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);
- if (mo->u.loc != oloc)
- loc = gen_rtx_CONCAT (GET_MODE (mo->u.loc), loc, mo->u.loc);
+ if (mo.u.loc != oloc)
+ loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, mo.u.loc);
/* The loc of a MO_VAL_SET may have various forms:
@@ -5207,12 +5058,12 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
reverse = reverse_op (v->val_rtx, expr);
if (reverse)
{
- loc = gen_rtx_CONCAT (GET_MODE (mo->u.loc), loc, reverse);
+ loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, reverse);
VAL_EXPR_HAS_REVERSE (loc) = 1;
}
}
- mo->u.loc = loc;
+ mo.u.loc = loc;
if (track_p)
VAL_HOLDS_TRACK_EXPR (loc) = 1;
@@ -5221,16 +5072,17 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
VAL_NEEDS_RESOLUTION (loc) = resolve;
preserve_value (v);
}
- if (mo->type == MO_CLOBBER)
+ if (mo.type == MO_CLOBBER)
VAL_EXPR_IS_CLOBBERED (loc) = 1;
- if (mo->type == MO_COPY)
+ if (mo.type == MO_COPY)
VAL_EXPR_IS_COPIED (loc) = 1;
- mo->type = MO_VAL_SET;
+ mo.type = MO_VAL_SET;
log_and_return:
if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (mo->u.loc, cui->bb, cui->insn, mo->type, dump_file);
+ log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
}
/* Callback for cselib_record_sets_hook, that records as micro
@@ -5246,6 +5098,7 @@ add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
basic_block bb = BLOCK_FOR_INSN (insn);
int n1, n2;
struct count_use_info cui;
+ micro_operation *mos;
cselib_hook_called = true;
@@ -5256,80 +5109,102 @@ add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
cui.sets = sets;
cui.n_sets = n_sets;
- n1 = VTI (bb)->n_mos;
+ n1 = VEC_length (micro_operation, VTI (bb)->mos);
cui.store_p = false;
note_uses (&PATTERN (insn), add_uses_1, &cui);
- n2 = VTI (bb)->n_mos - 1;
+ n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
+ mos = VEC_address (micro_operation, VTI (bb)->mos);
/* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
MO_VAL_LOC last. */
while (n1 < n2)
{
- while (n1 < n2 && VTI (bb)->mos[n1].type == MO_USE)
+ while (n1 < n2 && mos[n1].type == MO_USE)
n1++;
- while (n1 < n2 && VTI (bb)->mos[n2].type != MO_USE)
+ while (n1 < n2 && mos[n2].type != MO_USE)
n2--;
if (n1 < n2)
{
micro_operation sw;
- sw = VTI (bb)->mos[n1];
- VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
- VTI (bb)->mos[n2] = sw;
+ sw = mos[n1];
+ mos[n1] = mos[n2];
+ mos[n2] = sw;
}
}
- n2 = VTI (bb)->n_mos - 1;
-
+ n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
while (n1 < n2)
{
- while (n1 < n2 && VTI (bb)->mos[n1].type != MO_VAL_LOC)
+ while (n1 < n2 && mos[n1].type != MO_VAL_LOC)
n1++;
- while (n1 < n2 && VTI (bb)->mos[n2].type == MO_VAL_LOC)
+ while (n1 < n2 && mos[n2].type == MO_VAL_LOC)
n2--;
if (n1 < n2)
{
micro_operation sw;
- sw = VTI (bb)->mos[n1];
- VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
- VTI (bb)->mos[n2] = sw;
+ sw = mos[n1];
+ mos[n1] = mos[n2];
+ mos[n2] = sw;
}
}
if (CALL_P (insn))
{
- micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
+ micro_operation mo;
- mo->type = MO_CALL;
- mo->insn = insn;
+ mo.type = MO_CALL;
+ mo.insn = insn;
+ mo.u.loc = NULL_RTX;
if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (PATTERN (insn), bb, insn, mo->type, dump_file);
+ log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
}
- n1 = VTI (bb)->n_mos;
+ n1 = VEC_length (micro_operation, VTI (bb)->mos);
/* This will record NEXT_INSN (insn), such that we can
insert notes before it without worrying about any
notes that MO_USEs might emit after the insn. */
cui.store_p = true;
note_stores (PATTERN (insn), add_stores, &cui);
- n2 = VTI (bb)->n_mos - 1;
+ n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
+ mos = VEC_address (micro_operation, VTI (bb)->mos);
- /* Order the MO_CLOBBERs to be before MO_SETs. */
+ /* Order the MO_VAL_USEs first (note_stores does nothing
+ on DEBUG_INSNs, so there are no MO_VAL_LOCs from this
+ insn), then MO_CLOBBERs, then MO_SET/MO_COPY/MO_VAL_SET. */
while (n1 < n2)
{
- while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
+ while (n1 < n2 && mos[n1].type == MO_VAL_USE)
n1++;
- while (n1 < n2 && VTI (bb)->mos[n2].type != MO_CLOBBER)
+ while (n1 < n2 && mos[n2].type != MO_VAL_USE)
n2--;
if (n1 < n2)
{
micro_operation sw;
- sw = VTI (bb)->mos[n1];
- VTI (bb)->mos[n1] = VTI (bb)->mos[n2];
- VTI (bb)->mos[n2] = sw;
+ sw = mos[n1];
+ mos[n1] = mos[n2];
+ mos[n2] = sw;
+ }
+ }
+
+ n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
+ while (n1 < n2)
+ {
+ while (n1 < n2 && mos[n1].type == MO_CLOBBER)
+ n1++;
+ while (n1 < n2 && mos[n2].type != MO_CLOBBER)
+ n2--;
+ if (n1 < n2)
+ {
+ micro_operation sw;
+
+ sw = mos[n1];
+ mos[n1] = mos[n2];
+ mos[n2] = sw;
}
}
}
@@ -5401,7 +5276,8 @@ find_src_set_src (dataflow_set *set, rtx src)
static bool
compute_bb_dataflow (basic_block bb)
{
- int i, n;
+ unsigned int i;
+ micro_operation *mo;
bool changed;
dataflow_set old_out;
dataflow_set *in = &VTI (bb)->in;
@@ -5411,12 +5287,11 @@ compute_bb_dataflow (basic_block bb)
dataflow_set_copy (&old_out, out);
dataflow_set_copy (out, in);
- n = VTI (bb)->n_mos;
- for (i = 0; i < n; i++)
+ for (i = 0; VEC_iterate (micro_operation, VTI (bb)->mos, i, mo); i++)
{
- rtx insn = VTI (bb)->mos[i].insn;
+ rtx insn = mo->insn;
- switch (VTI (bb)->mos[i].type)
+ switch (mo->type)
{
case MO_CALL:
dataflow_set_clear_at_call (out);
@@ -5424,7 +5299,7 @@ compute_bb_dataflow (basic_block bb)
case MO_USE:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
if (REG_P (loc))
var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
@@ -5435,7 +5310,7 @@ compute_bb_dataflow (basic_block bb)
case MO_VAL_LOC:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx val, vloc;
tree var;
@@ -5467,7 +5342,7 @@ compute_bb_dataflow (basic_block bb)
case MO_VAL_USE:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx val, vloc, uloc;
vloc = uloc = XEXP (loc, 1);
@@ -5498,7 +5373,7 @@ compute_bb_dataflow (basic_block bb)
case MO_VAL_SET:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx val, vloc, uloc, reverse = NULL_RTX;
vloc = loc;
@@ -5591,7 +5466,7 @@ compute_bb_dataflow (basic_block bb)
case MO_SET:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx set_src = NULL;
if (GET_CODE (loc) == SET)
@@ -5611,7 +5486,7 @@ compute_bb_dataflow (basic_block bb)
case MO_COPY:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
enum var_init_status src_status;
rtx set_src = NULL;
@@ -5642,7 +5517,7 @@ compute_bb_dataflow (basic_block bb)
case MO_USE_NO_VAR:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
if (REG_P (loc))
var_reg_delete (out, loc, false);
@@ -5653,7 +5528,7 @@ compute_bb_dataflow (basic_block bb)
case MO_CLOBBER:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
if (REG_P (loc))
var_reg_delete (out, loc, true);
@@ -5663,7 +5538,7 @@ compute_bb_dataflow (basic_block bb)
break;
case MO_ADJUST:
- out->stack_adjust += VTI (bb)->mos[i].u.adjust;
+ out->stack_adjust += mo->u.adjust;
break;
}
}
@@ -7318,16 +7193,17 @@ emit_notes_for_differences (rtx insn, dataflow_set *old_set,
static void
emit_notes_in_bb (basic_block bb, dataflow_set *set)
{
- int i;
+ unsigned int i;
+ micro_operation *mo;
dataflow_set_clear (set);
dataflow_set_copy (set, &VTI (bb)->in);
- for (i = 0; i < VTI (bb)->n_mos; i++)
+ for (i = 0; VEC_iterate (micro_operation, VTI (bb)->mos, i, mo); i++)
{
- rtx insn = VTI (bb)->mos[i].insn;
+ rtx insn = mo->insn;
- switch (VTI (bb)->mos[i].type)
+ switch (mo->type)
{
case MO_CALL:
dataflow_set_clear_at_call (set);
@@ -7336,7 +7212,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
case MO_USE:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
if (REG_P (loc))
var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
@@ -7349,7 +7225,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
case MO_VAL_LOC:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx val, vloc;
tree var;
@@ -7383,7 +7259,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
case MO_VAL_USE:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx val, vloc, uloc;
vloc = uloc = XEXP (loc, 1);
@@ -7416,7 +7292,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
case MO_VAL_SET:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx val, vloc, uloc, reverse = NULL_RTX;
vloc = loc;
@@ -7506,7 +7382,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
case MO_SET:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx set_src = NULL;
if (GET_CODE (loc) == SET)
@@ -7529,7 +7405,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
case MO_COPY:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
enum var_init_status src_status;
rtx set_src = NULL;
@@ -7554,7 +7430,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
case MO_USE_NO_VAR:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
if (REG_P (loc))
var_reg_delete (set, loc, false);
@@ -7567,7 +7443,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
case MO_CLOBBER:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
if (REG_P (loc))
var_reg_delete (set, loc, true);
@@ -7580,7 +7456,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
break;
case MO_ADJUST:
- set->stack_adjust += VTI (bb)->mos[i].u.adjust;
+ set->stack_adjust += mo->u.adjust;
break;
}
}
@@ -7806,7 +7682,7 @@ vt_add_function_parameters (void)
if (MAY_HAVE_DEBUG_INSNS)
{
- cselib_preserve_only_values (true);
+ cselib_preserve_only_values ();
cselib_reset_table (cselib_get_next_uid ());
}
@@ -7840,13 +7716,11 @@ vt_initialize (void)
{
rtx insn;
HOST_WIDE_INT pre, post = 0;
- unsigned int next_uid_before = cselib_get_next_uid ();
- unsigned int next_uid_after = next_uid_before;
basic_block first_bb, last_bb;
if (MAY_HAVE_DEBUG_INSNS)
{
- cselib_record_sets_hook = count_with_sets;
+ cselib_record_sets_hook = add_with_sets;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "first value: %i\n",
cselib_get_next_uid ());
@@ -7866,10 +7740,9 @@ vt_initialize (void)
}
last_bb = bb;
- /* Count the number of micro operations. */
+ /* Add the micro-operations to the vector. */
FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
{
- VTI (bb)->n_mos = 0;
for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
@@ -7880,75 +7753,12 @@ vt_initialize (void)
insn_stack_adjust_offset_pre_post (insn, &pre, &post);
if (pre)
{
- VTI (bb)->n_mos++;
- if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (GEN_INT (pre), bb, insn,
- MO_ADJUST, dump_file);
- }
- if (post)
- {
- VTI (bb)->n_mos++;
- if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (GEN_INT (post), bb, insn,
- MO_ADJUST, dump_file);
- }
- }
- cselib_hook_called = false;
- if (MAY_HAVE_DEBUG_INSNS)
- {
- cselib_process_insn (insn);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- print_rtl_single (dump_file, insn);
- dump_cselib_table (dump_file);
- }
- }
- if (!cselib_hook_called)
- count_with_sets (insn, 0, 0);
- if (CALL_P (insn))
- {
- VTI (bb)->n_mos++;
- if (dump_file && (dump_flags & TDF_DETAILS))
- log_op_type (PATTERN (insn), bb, insn,
- MO_CALL, dump_file);
- }
- }
- }
- }
-
- if (MAY_HAVE_DEBUG_INSNS)
- {
- cselib_preserve_only_values (false);
- next_uid_after = cselib_get_next_uid ();
- cselib_reset_table (next_uid_before);
- cselib_record_sets_hook = add_with_sets;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "first value: %i\n",
- cselib_get_next_uid ());
- }
-
- /* Add the micro-operations to the array. */
- FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
- {
- int count = VTI (bb)->n_mos;
- VTI (bb)->mos = XNEWVEC (micro_operation, count);
- VTI (bb)->n_mos = 0;
- for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
- insn = NEXT_INSN (insn))
- {
- if (INSN_P (insn))
- {
- if (!frame_pointer_needed)
- {
- insn_stack_adjust_offset_pre_post (insn, &pre, &post);
- if (pre)
- {
- micro_operation *mo
- = VTI (bb)->mos + VTI (bb)->n_mos++;
-
- mo->type = MO_ADJUST;
- mo->u.adjust = pre;
- mo->insn = insn;
+ micro_operation mo;
+ mo.type = MO_ADJUST;
+ mo.u.adjust = pre;
+ mo.insn = insn;
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
+ &mo);
if (dump_file && (dump_flags & TDF_DETAILS))
log_op_type (PATTERN (insn), bb, insn,
@@ -7971,11 +7781,12 @@ vt_initialize (void)
if (!frame_pointer_needed && post)
{
- micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
-
- mo->type = MO_ADJUST;
- mo->u.adjust = post;
- mo->insn = insn;
+ micro_operation mo;
+ mo.type = MO_ADJUST;
+ mo.u.adjust = post;
+ mo.insn = insn;
+ VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
+ &mo);
if (dump_file && (dump_flags & TDF_DETAILS))
log_op_type (PATTERN (insn), bb, insn,
@@ -7983,16 +7794,14 @@ vt_initialize (void)
}
}
}
- gcc_assert (count == VTI (bb)->n_mos);
}
bb = last_bb;
if (MAY_HAVE_DEBUG_INSNS)
{
- cselib_preserve_only_values (true);
- gcc_assert (next_uid_after == cselib_get_next_uid ());
- cselib_reset_table (next_uid_after);
+ cselib_preserve_only_values ();
+ cselib_reset_table (cselib_get_next_uid ());
cselib_record_sets_hook = NULL;
}
}
@@ -8079,7 +7888,7 @@ vt_finalize (void)
FOR_EACH_BB (bb)
{
- free (VTI (bb)->mos);
+ VEC_free (micro_operation, heap, VTI (bb)->mos);
}
FOR_ALL_BB (bb)