/* 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
/* 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;
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;
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 *);
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;
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. */
}
}
-/* 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. */
/* 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)
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)
{
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);
}
}
PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
}
- mo->u.loc = oloc;
+ mo.u.loc = oloc;
}
else if (type == MO_VAL_USE)
{
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);
}
}
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);
}
}
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;
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;
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
{
if (src == NULL)
{
- mo->type = MO_SET;
- mo->u.loc = loc;
+ mo.type = MO_SET;
+ mo.u.loc = loc;
}
else
{
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)))
{
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
{
if (src == NULL)
{
- mo->type = MO_SET;
- mo->u.loc = loc;
+ mo.type = MO_SET;
+ mo.u.loc = loc;
}
else
{
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;
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);
}
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:
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;
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
basic_block bb = BLOCK_FOR_INSN (insn);
int n1, n2;
struct count_use_info cui;
+ micro_operation *mos;
cselib_hook_called = true;
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;
}
}
}
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;
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);
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);
case MO_VAL_LOC:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx val, vloc;
tree var;
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);
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;
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)
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;
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);
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);
break;
case MO_ADJUST:
- out->stack_adjust += VTI (bb)->mos[i].u.adjust;
+ out->stack_adjust += mo->u.adjust;
break;
}
}
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);
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);
case MO_VAL_LOC:
{
- rtx loc = VTI (bb)->mos[i].u.loc;
+ rtx loc = mo->u.loc;
rtx val, vloc;
tree var;
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);
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;
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)
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;
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);
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);
break;
case MO_ADJUST:
- set->stack_adjust += VTI (bb)->mos[i].u.adjust;
+ set->stack_adjust += mo->u.adjust;
break;
}
}
if (MAY_HAVE_DEBUG_INSNS)
{
- cselib_preserve_only_values (true);
+ cselib_preserve_only_values ();
cselib_reset_table (cselib_get_next_uid ());
}
{
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 ());
}
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))
{
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,
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,
}
}
}
- 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;
}
}
FOR_EACH_BB (bb)
{
- free (VTI (bb)->mos);
+ VEC_free (micro_operation, heap, VTI (bb)->mos);
}
FOR_ALL_BB (bb)