From c77c64d83a5b21e78670c99205aa9d450968554f Mon Sep 17 00:00:00 2001 From: jakub Date: Fri, 12 Mar 2010 13:27:43 +0000 Subject: [PATCH] * 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 --- gcc/ChangeLog | 22 +++ gcc/cselib.c | 43 +--- gcc/cselib.h | 2 +- gcc/var-tracking.c | 569 ++++++++++++++++++----------------------------------- 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 + * 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) -- 2.11.0