Commit 0de3e43f by Jakub Jelinek Committed by Jakub Jelinek

cselib.c (LONG_TERM_PRESERVED_VALUE_P): Remove.

	* 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.

From-SVN: r157403
parent 70235ab9
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.
......
/* 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]);
......
......@@ -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 *);
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment