mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-29 22:15:03 +08:00
df-scan.c (df_collection_rec): Adjust.
* df-scan.c (df_collection_rec): Adjust. (copy_defs): New constant. (copy_uses): Likewise. (copy_eq_uses): Likewise. (copy_mw): Likewise. (copy_all): Likewise. (df_insn_rescan): Adjust. (df_notes_rescan): Likewise. (df_swap_refs): Likewise. (df_sort_and_compress_refs): Likewise. (df_sort_and_compress_mws): Likewise. (df_install_refs): Likewise. (df_install_mws): Likewise. (df_refs_add_to_chains): Add flags parameter controlling which vectors are coppied. (df_bb_refs_record): Adjust. (df_record_entry_block_defs): Likewise. (df_record_exit_block_defs): Likewise. (df_refs_verify): Likewise. (df_mws_verify): Likewise. (df_insn_refs_verify): Likewise. (df_bb_verify): Likewise. * ipa-pure-const.c (finish_state): Remove. (propagate): Adjust. * tree-data-ref.c tree-ssa-alias.c tree-ssa-loop-ivcanon.c tree-ssa-threadedge.c tree-vect-loop-manip.c tree-vect-slp.c var-tracking.c: Adjust. * vec.c (stack_vecs): Remove. (register_stack_vec): Likewise. (stack_vec_register_index): Likewise. (unregister_stack_vec): Likewise. * vec.h (struct va_stack): Remove. (struct vec<T, A, vl_ptr>): Specialize as struct vec<T, va_heap, vl_ptr> instead since va_heap is the only allocation strategy compatable with the vl_ptr layout. (struct vec<T, va_gc, vl_ptr>): Remove because it now gets an empty specialization anyway. (class stack_vec): New class. (vec_stack_alloc): Remove. (vec<T, va_heap, vl_ptr>::using_auto_storage): New method. * gcc-interface/decl.c (components_to_record): Adjust. From-SVN: r204137
This commit is contained in:
parent
b868b7cae4
commit
ff4c81cccb
@ -1,3 +1,46 @@
|
|||||||
|
2013-10-28 Trevor Saunders <tsaunders@mozilla.com>
|
||||||
|
|
||||||
|
* df-scan.c (df_collection_rec): Adjust.
|
||||||
|
(copy_defs): New constant.
|
||||||
|
(copy_uses): Likewise.
|
||||||
|
(copy_eq_uses): Likewise.
|
||||||
|
(copy_mw): Likewise.
|
||||||
|
(copy_all): Likewise.
|
||||||
|
(df_insn_rescan): Adjust.
|
||||||
|
(df_notes_rescan): Likewise.
|
||||||
|
(df_swap_refs): Likewise.
|
||||||
|
(df_sort_and_compress_refs): Likewise.
|
||||||
|
(df_sort_and_compress_mws): Likewise.
|
||||||
|
(df_install_refs): Likewise.
|
||||||
|
(df_install_mws): Likewise.
|
||||||
|
(df_refs_add_to_chains): Add flags parameter controlling which vectors
|
||||||
|
are coppied.
|
||||||
|
(df_bb_refs_record): Adjust.
|
||||||
|
(df_record_entry_block_defs): Likewise.
|
||||||
|
(df_record_exit_block_defs): Likewise.
|
||||||
|
(df_refs_verify): Likewise.
|
||||||
|
(df_mws_verify): Likewise.
|
||||||
|
(df_insn_refs_verify): Likewise.
|
||||||
|
(df_bb_verify): Likewise.
|
||||||
|
* ipa-pure-const.c (finish_state): Remove.
|
||||||
|
(propagate): Adjust.
|
||||||
|
* tree-data-ref.c tree-ssa-alias.c tree-ssa-loop-ivcanon.c
|
||||||
|
tree-ssa-threadedge.c tree-vect-loop-manip.c tree-vect-slp.c
|
||||||
|
var-tracking.c: Adjust.
|
||||||
|
* vec.c (stack_vecs): Remove.
|
||||||
|
(register_stack_vec): Likewise.
|
||||||
|
(stack_vec_register_index): Likewise.
|
||||||
|
(unregister_stack_vec): Likewise.
|
||||||
|
* vec.h (struct va_stack): Remove.
|
||||||
|
(struct vec<T, A, vl_ptr>): Specialize as
|
||||||
|
struct vec<T, va_heap, vl_ptr> instead since va_heap is the only
|
||||||
|
allocation strategy compatable with the vl_ptr layout.
|
||||||
|
(struct vec<T, va_gc, vl_ptr>): Remove because it now gets an empty
|
||||||
|
specialization anyway.
|
||||||
|
(class stack_vec): New class.
|
||||||
|
(vec_stack_alloc): Remove.
|
||||||
|
(vec<T, va_heap, vl_ptr>::using_auto_storage): New method.
|
||||||
|
|
||||||
2013-10-28 Alexander Ivchenko <alexander.ivchenko@intel.com>
|
2013-10-28 Alexander Ivchenko <alexander.ivchenko@intel.com>
|
||||||
Maxim Kuznetsov <maxim.kuznetsov@intel.com>
|
Maxim Kuznetsov <maxim.kuznetsov@intel.com>
|
||||||
Sergey Lega <sergey.s.lega@intel.com>
|
Sergey Lega <sergey.s.lega@intel.com>
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2013-10-28 Trevor Saunders <tsaunders@mozilla.com>
|
||||||
|
|
||||||
|
* gcc-interface/decl.c (components_to_record): Adjust.
|
||||||
|
|
||||||
2013-10-24 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
2013-10-24 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||||
|
|
||||||
* gcc-interface/Make-lang.in (ADA_DEPS): Fix quoting.
|
* gcc-interface/Make-lang.in (ADA_DEPS): Fix quoting.
|
||||||
|
@ -7003,13 +7003,11 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
|
|||||||
tree gnu_union_type, gnu_union_name;
|
tree gnu_union_type, gnu_union_name;
|
||||||
tree this_first_free_pos, gnu_variant_list = NULL_TREE;
|
tree this_first_free_pos, gnu_variant_list = NULL_TREE;
|
||||||
bool union_field_needs_strict_alignment = false;
|
bool union_field_needs_strict_alignment = false;
|
||||||
vec <vinfo_t, va_stack> variant_types;
|
stack_vec <vinfo_t, 16> variant_types;
|
||||||
vinfo_t *gnu_variant;
|
vinfo_t *gnu_variant;
|
||||||
unsigned int variants_align = 0;
|
unsigned int variants_align = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
vec_stack_alloc (vinfo_t, variant_types, 16);
|
|
||||||
|
|
||||||
if (TREE_CODE (gnu_name) == TYPE_DECL)
|
if (TREE_CODE (gnu_name) == TYPE_DECL)
|
||||||
gnu_name = DECL_NAME (gnu_name);
|
gnu_name = DECL_NAME (gnu_name);
|
||||||
|
|
||||||
@ -7205,9 +7203,6 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
|
|||||||
gnu_variant_list = gnu_field;
|
gnu_variant_list = gnu_field;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We are done with the variants. */
|
|
||||||
variant_types.release ();
|
|
||||||
|
|
||||||
/* Only make the QUAL_UNION_TYPE if there are non-empty variants. */
|
/* Only make the QUAL_UNION_TYPE if there are non-empty variants. */
|
||||||
if (gnu_variant_list)
|
if (gnu_variant_list)
|
||||||
{
|
{
|
||||||
|
138
gcc/df-scan.c
138
gcc/df-scan.c
@ -86,10 +86,10 @@ static HARD_REG_SET elim_reg_set;
|
|||||||
|
|
||||||
struct df_collection_rec
|
struct df_collection_rec
|
||||||
{
|
{
|
||||||
vec<df_ref, va_stack> def_vec;
|
stack_vec<df_ref, 128> def_vec;
|
||||||
vec<df_ref, va_stack> use_vec;
|
stack_vec<df_ref, 32> use_vec;
|
||||||
vec<df_ref, va_stack> eq_use_vec;
|
stack_vec<df_ref, 32> eq_use_vec;
|
||||||
vec<df_mw_hardreg_ptr, va_stack> mw_vec;
|
stack_vec<df_mw_hardreg_ptr, 32> mw_vec;
|
||||||
};
|
};
|
||||||
|
|
||||||
static df_ref df_null_ref_rec[1];
|
static df_ref df_null_ref_rec[1];
|
||||||
@ -131,7 +131,7 @@ static void df_ref_chain_delete_du_chain (df_ref *);
|
|||||||
static void df_ref_chain_delete (df_ref *);
|
static void df_ref_chain_delete (df_ref *);
|
||||||
|
|
||||||
static void df_refs_add_to_chains (struct df_collection_rec *,
|
static void df_refs_add_to_chains (struct df_collection_rec *,
|
||||||
basic_block, rtx);
|
basic_block, rtx, unsigned int);
|
||||||
|
|
||||||
static bool df_insn_refs_verify (struct df_collection_rec *, basic_block, rtx, bool);
|
static bool df_insn_refs_verify (struct df_collection_rec *, basic_block, rtx, bool);
|
||||||
static void df_entry_block_defs_collect (struct df_collection_rec *, bitmap);
|
static void df_entry_block_defs_collect (struct df_collection_rec *, bitmap);
|
||||||
@ -153,6 +153,14 @@ static void df_insn_info_delete (unsigned int);
|
|||||||
and epilogue to save and restore registers as needed. */
|
and epilogue to save and restore registers as needed. */
|
||||||
|
|
||||||
static bool regs_ever_live[FIRST_PSEUDO_REGISTER];
|
static bool regs_ever_live[FIRST_PSEUDO_REGISTER];
|
||||||
|
|
||||||
|
/* Flags used to tell df_refs_add_to_chains() which vectors it should copy. */
|
||||||
|
static const unsigned int copy_defs = 0x1;
|
||||||
|
static const unsigned int copy_uses = 0x2;
|
||||||
|
static const unsigned int copy_eq_uses = 0x4;
|
||||||
|
static const unsigned int copy_mw = 0x8;
|
||||||
|
static const unsigned int copy_all = copy_defs | copy_uses | copy_eq_uses
|
||||||
|
| copy_mw;
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
SCANNING DATAFLOW PROBLEM
|
SCANNING DATAFLOW PROBLEM
|
||||||
@ -1268,11 +1276,6 @@ df_insn_rescan (rtx insn)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.def_vec, 128);
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.use_vec, 32);
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.eq_use_vec, 32);
|
|
||||||
vec_stack_alloc (df_mw_hardreg_ptr, collection_rec.mw_vec, 32);
|
|
||||||
|
|
||||||
bitmap_clear_bit (&df->insns_to_delete, uid);
|
bitmap_clear_bit (&df->insns_to_delete, uid);
|
||||||
bitmap_clear_bit (&df->insns_to_rescan, uid);
|
bitmap_clear_bit (&df->insns_to_rescan, uid);
|
||||||
bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
|
bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
|
||||||
@ -1306,15 +1309,10 @@ df_insn_rescan (rtx insn)
|
|||||||
fprintf (dump_file, "scanning new insn with uid = %d.\n", uid);
|
fprintf (dump_file, "scanning new insn with uid = %d.\n", uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
df_refs_add_to_chains (&collection_rec, bb, insn);
|
df_refs_add_to_chains (&collection_rec, bb, insn, copy_all);
|
||||||
if (!DEBUG_INSN_P (insn))
|
if (!DEBUG_INSN_P (insn))
|
||||||
df_set_bb_dirty (bb);
|
df_set_bb_dirty (bb);
|
||||||
|
|
||||||
collection_rec.def_vec.release ();
|
|
||||||
collection_rec.use_vec.release ();
|
|
||||||
collection_rec.eq_use_vec.release ();
|
|
||||||
collection_rec.mw_vec.release ();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2221,10 +2219,6 @@ df_notes_rescan (rtx insn)
|
|||||||
unsigned int num_deleted;
|
unsigned int num_deleted;
|
||||||
unsigned int mw_len;
|
unsigned int mw_len;
|
||||||
|
|
||||||
memset (&collection_rec, 0, sizeof (struct df_collection_rec));
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.eq_use_vec, 32);
|
|
||||||
vec_stack_alloc (df_mw_hardreg_ptr, collection_rec.mw_vec, 32);
|
|
||||||
|
|
||||||
num_deleted = df_mw_hardreg_chain_delete_eq_uses (insn_info);
|
num_deleted = df_mw_hardreg_chain_delete_eq_uses (insn_info);
|
||||||
df_ref_chain_delete (insn_info->eq_uses);
|
df_ref_chain_delete (insn_info->eq_uses);
|
||||||
insn_info->eq_uses = NULL;
|
insn_info->eq_uses = NULL;
|
||||||
@ -2287,11 +2281,7 @@ df_notes_rescan (rtx insn)
|
|||||||
insn_info->mw_hardregs[mw_len] = NULL;
|
insn_info->mw_hardregs[mw_len] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Get rid of the mw_rec so that df_refs_add_to_chains will
|
df_refs_add_to_chains (&collection_rec, bb, insn, copy_eq_uses);
|
||||||
ignore it. */
|
|
||||||
collection_rec.mw_vec.release ();
|
|
||||||
df_refs_add_to_chains (&collection_rec, bb, insn);
|
|
||||||
collection_rec.eq_use_vec.release ();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
df_insn_rescan (insn);
|
df_insn_rescan (insn);
|
||||||
@ -2391,7 +2381,7 @@ df_ref_compare (const void *r1, const void *r2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
df_swap_refs (vec<df_ref, va_stack> *ref_vec, int i, int j)
|
df_swap_refs (vec<df_ref, va_heap> *ref_vec, int i, int j)
|
||||||
{
|
{
|
||||||
df_ref tmp = (*ref_vec)[i];
|
df_ref tmp = (*ref_vec)[i];
|
||||||
(*ref_vec)[i] = (*ref_vec)[j];
|
(*ref_vec)[i] = (*ref_vec)[j];
|
||||||
@ -2401,7 +2391,7 @@ df_swap_refs (vec<df_ref, va_stack> *ref_vec, int i, int j)
|
|||||||
/* Sort and compress a set of refs. */
|
/* Sort and compress a set of refs. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
df_sort_and_compress_refs (vec<df_ref, va_stack> *ref_vec)
|
df_sort_and_compress_refs (vec<df_ref, va_heap> *ref_vec)
|
||||||
{
|
{
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -2510,7 +2500,7 @@ df_mw_compare (const void *m1, const void *m2)
|
|||||||
/* Sort and compress a set of refs. */
|
/* Sort and compress a set of refs. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
df_sort_and_compress_mws (vec<df_mw_hardreg_ptr, va_stack> *mw_vec)
|
df_sort_and_compress_mws (vec<df_mw_hardreg_ptr, va_heap> *mw_vec)
|
||||||
{
|
{
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
struct df_scan_problem_data *problem_data
|
struct df_scan_problem_data *problem_data
|
||||||
@ -2621,14 +2611,12 @@ df_install_ref (df_ref this_ref,
|
|||||||
|
|
||||||
static df_ref *
|
static df_ref *
|
||||||
df_install_refs (basic_block bb,
|
df_install_refs (basic_block bb,
|
||||||
vec<df_ref, va_stack> old_vec,
|
const vec<df_ref, va_heap> *old_vec,
|
||||||
struct df_reg_info **reg_info,
|
struct df_reg_info **reg_info,
|
||||||
struct df_ref_info *ref_info,
|
struct df_ref_info *ref_info,
|
||||||
bool is_notes)
|
bool is_notes)
|
||||||
{
|
{
|
||||||
unsigned int count;
|
unsigned int count = old_vec->length ();
|
||||||
|
|
||||||
count = old_vec.length ();
|
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
df_ref *new_vec = XNEWVEC (df_ref, count + 1);
|
df_ref *new_vec = XNEWVEC (df_ref, count + 1);
|
||||||
@ -2659,7 +2647,7 @@ df_install_refs (basic_block bb,
|
|||||||
if (add_to_table && df->analyze_subset)
|
if (add_to_table && df->analyze_subset)
|
||||||
add_to_table = bitmap_bit_p (df->blocks_to_analyze, bb->index);
|
add_to_table = bitmap_bit_p (df->blocks_to_analyze, bb->index);
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (old_vec, ix, this_ref)
|
FOR_EACH_VEC_ELT (*old_vec, ix, this_ref)
|
||||||
{
|
{
|
||||||
new_vec[ix] = this_ref;
|
new_vec[ix] = this_ref;
|
||||||
df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)],
|
df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)],
|
||||||
@ -2678,16 +2666,14 @@ df_install_refs (basic_block bb,
|
|||||||
insn. */
|
insn. */
|
||||||
|
|
||||||
static struct df_mw_hardreg **
|
static struct df_mw_hardreg **
|
||||||
df_install_mws (vec<df_mw_hardreg_ptr, va_stack> old_vec)
|
df_install_mws (const vec<df_mw_hardreg_ptr, va_heap> *old_vec)
|
||||||
{
|
{
|
||||||
unsigned int count;
|
unsigned int count = old_vec->length ();
|
||||||
|
|
||||||
count = old_vec.length ();
|
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
struct df_mw_hardreg **new_vec
|
struct df_mw_hardreg **new_vec
|
||||||
= XNEWVEC (struct df_mw_hardreg*, count + 1);
|
= XNEWVEC (struct df_mw_hardreg*, count + 1);
|
||||||
memcpy (new_vec, old_vec.address (),
|
memcpy (new_vec, old_vec->address (),
|
||||||
sizeof (struct df_mw_hardreg*) * count);
|
sizeof (struct df_mw_hardreg*) * count);
|
||||||
new_vec[count] = NULL;
|
new_vec[count] = NULL;
|
||||||
return new_vec;
|
return new_vec;
|
||||||
@ -2702,7 +2688,7 @@ df_install_mws (vec<df_mw_hardreg_ptr, va_stack> old_vec)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
df_refs_add_to_chains (struct df_collection_rec *collection_rec,
|
df_refs_add_to_chains (struct df_collection_rec *collection_rec,
|
||||||
basic_block bb, rtx insn)
|
basic_block bb, rtx insn, unsigned int flags)
|
||||||
{
|
{
|
||||||
if (insn)
|
if (insn)
|
||||||
{
|
{
|
||||||
@ -2710,35 +2696,35 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec,
|
|||||||
/* If there is a vector in the collection rec, add it to the
|
/* If there is a vector in the collection rec, add it to the
|
||||||
insn. A null rec is a signal that the caller will handle the
|
insn. A null rec is a signal that the caller will handle the
|
||||||
chain specially. */
|
chain specially. */
|
||||||
if (collection_rec->def_vec.exists ())
|
if (flags & copy_defs)
|
||||||
{
|
{
|
||||||
df_scan_free_ref_vec (insn_rec->defs);
|
df_scan_free_ref_vec (insn_rec->defs);
|
||||||
insn_rec->defs
|
insn_rec->defs
|
||||||
= df_install_refs (bb, collection_rec->def_vec,
|
= df_install_refs (bb, &collection_rec->def_vec,
|
||||||
df->def_regs,
|
df->def_regs,
|
||||||
&df->def_info, false);
|
&df->def_info, false);
|
||||||
}
|
}
|
||||||
if (collection_rec->use_vec.exists ())
|
if (flags & copy_uses)
|
||||||
{
|
{
|
||||||
df_scan_free_ref_vec (insn_rec->uses);
|
df_scan_free_ref_vec (insn_rec->uses);
|
||||||
insn_rec->uses
|
insn_rec->uses
|
||||||
= df_install_refs (bb, collection_rec->use_vec,
|
= df_install_refs (bb, &collection_rec->use_vec,
|
||||||
df->use_regs,
|
df->use_regs,
|
||||||
&df->use_info, false);
|
&df->use_info, false);
|
||||||
}
|
}
|
||||||
if (collection_rec->eq_use_vec.exists ())
|
if (flags & copy_eq_uses)
|
||||||
{
|
{
|
||||||
df_scan_free_ref_vec (insn_rec->eq_uses);
|
df_scan_free_ref_vec (insn_rec->eq_uses);
|
||||||
insn_rec->eq_uses
|
insn_rec->eq_uses
|
||||||
= df_install_refs (bb, collection_rec->eq_use_vec,
|
= df_install_refs (bb, &collection_rec->eq_use_vec,
|
||||||
df->eq_use_regs,
|
df->eq_use_regs,
|
||||||
&df->use_info, true);
|
&df->use_info, true);
|
||||||
}
|
}
|
||||||
if (collection_rec->mw_vec.exists ())
|
if (flags & copy_mw)
|
||||||
{
|
{
|
||||||
df_scan_free_mws_vec (insn_rec->mw_hardregs);
|
df_scan_free_mws_vec (insn_rec->mw_hardregs);
|
||||||
insn_rec->mw_hardregs
|
insn_rec->mw_hardregs
|
||||||
= df_install_mws (collection_rec->mw_vec);
|
= df_install_mws (&collection_rec->mw_vec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2747,12 +2733,12 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec,
|
|||||||
|
|
||||||
df_scan_free_ref_vec (bb_info->artificial_defs);
|
df_scan_free_ref_vec (bb_info->artificial_defs);
|
||||||
bb_info->artificial_defs
|
bb_info->artificial_defs
|
||||||
= df_install_refs (bb, collection_rec->def_vec,
|
= df_install_refs (bb, &collection_rec->def_vec,
|
||||||
df->def_regs,
|
df->def_regs,
|
||||||
&df->def_info, false);
|
&df->def_info, false);
|
||||||
df_scan_free_ref_vec (bb_info->artificial_uses);
|
df_scan_free_ref_vec (bb_info->artificial_uses);
|
||||||
bb_info->artificial_uses
|
bb_info->artificial_uses
|
||||||
= df_install_refs (bb, collection_rec->use_vec,
|
= df_install_refs (bb, &collection_rec->use_vec,
|
||||||
df->use_regs,
|
df->use_regs,
|
||||||
&df->use_info, false);
|
&df->use_info, false);
|
||||||
}
|
}
|
||||||
@ -3633,17 +3619,12 @@ df_bb_refs_record (int bb_index, bool scan_insns)
|
|||||||
basic_block bb = BASIC_BLOCK (bb_index);
|
basic_block bb = BASIC_BLOCK (bb_index);
|
||||||
rtx insn;
|
rtx insn;
|
||||||
int luid = 0;
|
int luid = 0;
|
||||||
struct df_collection_rec collection_rec;
|
|
||||||
|
|
||||||
if (!df)
|
if (!df)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
df_collection_rec collection_rec;
|
||||||
df_grow_bb_info (df_scan);
|
df_grow_bb_info (df_scan);
|
||||||
vec_stack_alloc (df_ref, collection_rec.def_vec, 128);
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.use_vec, 32);
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.eq_use_vec, 32);
|
|
||||||
vec_stack_alloc (df_mw_hardreg_ptr, collection_rec.mw_vec, 32);
|
|
||||||
|
|
||||||
if (scan_insns)
|
if (scan_insns)
|
||||||
/* Scan the block an insn at a time from beginning to end. */
|
/* Scan the block an insn at a time from beginning to end. */
|
||||||
FOR_BB_INSNS (bb, insn)
|
FOR_BB_INSNS (bb, insn)
|
||||||
@ -3657,19 +3638,14 @@ df_bb_refs_record (int bb_index, bool scan_insns)
|
|||||||
/* Record refs within INSN. */
|
/* Record refs within INSN. */
|
||||||
DF_INSN_INFO_LUID (insn_info) = luid++;
|
DF_INSN_INFO_LUID (insn_info) = luid++;
|
||||||
df_insn_refs_collect (&collection_rec, bb, DF_INSN_INFO_GET (insn));
|
df_insn_refs_collect (&collection_rec, bb, DF_INSN_INFO_GET (insn));
|
||||||
df_refs_add_to_chains (&collection_rec, bb, insn);
|
df_refs_add_to_chains (&collection_rec, bb, insn, copy_all);
|
||||||
}
|
}
|
||||||
DF_INSN_INFO_LUID (insn_info) = luid;
|
DF_INSN_INFO_LUID (insn_info) = luid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Other block level artificial refs */
|
/* Other block level artificial refs */
|
||||||
df_bb_refs_collect (&collection_rec, bb);
|
df_bb_refs_collect (&collection_rec, bb);
|
||||||
df_refs_add_to_chains (&collection_rec, bb, NULL);
|
df_refs_add_to_chains (&collection_rec, bb, NULL, copy_all);
|
||||||
|
|
||||||
collection_rec.def_vec.release ();
|
|
||||||
collection_rec.use_vec.release ();
|
|
||||||
collection_rec.eq_use_vec.release ();
|
|
||||||
collection_rec.mw_vec.release ();
|
|
||||||
|
|
||||||
/* Now that the block has been processed, set the block as dirty so
|
/* Now that the block has been processed, set the block as dirty so
|
||||||
LR and LIVE will get it processed. */
|
LR and LIVE will get it processed. */
|
||||||
@ -3911,13 +3887,11 @@ static void
|
|||||||
df_record_entry_block_defs (bitmap entry_block_defs)
|
df_record_entry_block_defs (bitmap entry_block_defs)
|
||||||
{
|
{
|
||||||
struct df_collection_rec collection_rec;
|
struct df_collection_rec collection_rec;
|
||||||
memset (&collection_rec, 0, sizeof (struct df_collection_rec));
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.def_vec, FIRST_PSEUDO_REGISTER);
|
|
||||||
df_entry_block_defs_collect (&collection_rec, entry_block_defs);
|
df_entry_block_defs_collect (&collection_rec, entry_block_defs);
|
||||||
|
|
||||||
/* Process bb_refs chain */
|
/* Process bb_refs chain */
|
||||||
df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (ENTRY_BLOCK), NULL);
|
df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (ENTRY_BLOCK), NULL,
|
||||||
collection_rec.def_vec.release ();
|
copy_defs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4084,13 +4058,11 @@ static void
|
|||||||
df_record_exit_block_uses (bitmap exit_block_uses)
|
df_record_exit_block_uses (bitmap exit_block_uses)
|
||||||
{
|
{
|
||||||
struct df_collection_rec collection_rec;
|
struct df_collection_rec collection_rec;
|
||||||
memset (&collection_rec, 0, sizeof (struct df_collection_rec));
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.use_vec, FIRST_PSEUDO_REGISTER);
|
|
||||||
df_exit_block_uses_collect (&collection_rec, exit_block_uses);
|
df_exit_block_uses_collect (&collection_rec, exit_block_uses);
|
||||||
|
|
||||||
/* Process bb_refs chain */
|
/* Process bb_refs chain */
|
||||||
df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (EXIT_BLOCK), NULL);
|
df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (EXIT_BLOCK), NULL,
|
||||||
collection_rec.use_vec.release ();
|
copy_uses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4331,13 +4303,13 @@ df_reg_chain_verify_unmarked (df_ref refs)
|
|||||||
/* Verify that NEW_REC and OLD_REC have exactly the same members. */
|
/* Verify that NEW_REC and OLD_REC have exactly the same members. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
df_refs_verify (vec<df_ref, va_stack> new_rec, df_ref *old_rec,
|
df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec,
|
||||||
bool abort_if_fail)
|
bool abort_if_fail)
|
||||||
{
|
{
|
||||||
unsigned int ix;
|
unsigned int ix;
|
||||||
df_ref new_ref;
|
df_ref new_ref;
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (new_rec, ix, new_ref)
|
FOR_EACH_VEC_ELT (*new_rec, ix, new_ref)
|
||||||
{
|
{
|
||||||
if (*old_rec == NULL || !df_ref_equal_p (new_ref, *old_rec))
|
if (*old_rec == NULL || !df_ref_equal_p (new_ref, *old_rec))
|
||||||
{
|
{
|
||||||
@ -4369,14 +4341,14 @@ df_refs_verify (vec<df_ref, va_stack> new_rec, df_ref *old_rec,
|
|||||||
/* Verify that NEW_REC and OLD_REC have exactly the same members. */
|
/* Verify that NEW_REC and OLD_REC have exactly the same members. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
df_mws_verify (vec<df_mw_hardreg_ptr, va_stack> new_rec,
|
df_mws_verify (const vec<df_mw_hardreg_ptr, va_heap> *new_rec,
|
||||||
struct df_mw_hardreg **old_rec,
|
struct df_mw_hardreg **old_rec,
|
||||||
bool abort_if_fail)
|
bool abort_if_fail)
|
||||||
{
|
{
|
||||||
unsigned int ix;
|
unsigned int ix;
|
||||||
struct df_mw_hardreg *new_reg;
|
struct df_mw_hardreg *new_reg;
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (new_rec, ix, new_reg)
|
FOR_EACH_VEC_ELT (*new_rec, ix, new_reg)
|
||||||
{
|
{
|
||||||
if (*old_rec == NULL || !df_mw_equal_p (new_reg, *old_rec))
|
if (*old_rec == NULL || !df_mw_equal_p (new_reg, *old_rec))
|
||||||
{
|
{
|
||||||
@ -4430,13 +4402,13 @@ df_insn_refs_verify (struct df_collection_rec *collection_rec,
|
|||||||
|
|
||||||
/* Unfortunately we cannot opt out early if one of these is not
|
/* Unfortunately we cannot opt out early if one of these is not
|
||||||
right because the marks will not get cleared. */
|
right because the marks will not get cleared. */
|
||||||
ret1 = df_refs_verify (collection_rec->def_vec, DF_INSN_UID_DEFS (uid),
|
ret1 = df_refs_verify (&collection_rec->def_vec, DF_INSN_UID_DEFS (uid),
|
||||||
abort_if_fail);
|
abort_if_fail);
|
||||||
ret2 = df_refs_verify (collection_rec->use_vec, DF_INSN_UID_USES (uid),
|
ret2 = df_refs_verify (&collection_rec->use_vec, DF_INSN_UID_USES (uid),
|
||||||
abort_if_fail);
|
abort_if_fail);
|
||||||
ret3 = df_refs_verify (collection_rec->eq_use_vec, DF_INSN_UID_EQ_USES (uid),
|
ret3 = df_refs_verify (&collection_rec->eq_use_vec, DF_INSN_UID_EQ_USES (uid),
|
||||||
abort_if_fail);
|
abort_if_fail);
|
||||||
ret4 = df_mws_verify (collection_rec->mw_vec, DF_INSN_UID_MWS (uid),
|
ret4 = df_mws_verify (&collection_rec->mw_vec, DF_INSN_UID_MWS (uid),
|
||||||
abort_if_fail);
|
abort_if_fail);
|
||||||
return (ret1 && ret2 && ret3 && ret4);
|
return (ret1 && ret2 && ret3 && ret4);
|
||||||
}
|
}
|
||||||
@ -4453,12 +4425,6 @@ df_bb_verify (basic_block bb)
|
|||||||
struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
|
struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
|
||||||
struct df_collection_rec collection_rec;
|
struct df_collection_rec collection_rec;
|
||||||
|
|
||||||
memset (&collection_rec, 0, sizeof (struct df_collection_rec));
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.def_vec, 128);
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.use_vec, 32);
|
|
||||||
vec_stack_alloc (df_ref, collection_rec.eq_use_vec, 32);
|
|
||||||
vec_stack_alloc (df_mw_hardreg_ptr, collection_rec.mw_vec, 32);
|
|
||||||
|
|
||||||
gcc_assert (bb_info);
|
gcc_assert (bb_info);
|
||||||
|
|
||||||
/* Scan the block, one insn at a time, from beginning to end. */
|
/* Scan the block, one insn at a time, from beginning to end. */
|
||||||
@ -4472,8 +4438,8 @@ df_bb_verify (basic_block bb)
|
|||||||
|
|
||||||
/* Do the artificial defs and uses. */
|
/* Do the artificial defs and uses. */
|
||||||
df_bb_refs_collect (&collection_rec, bb);
|
df_bb_refs_collect (&collection_rec, bb);
|
||||||
df_refs_verify (collection_rec.def_vec, df_get_artificial_defs (bb->index), true);
|
df_refs_verify (&collection_rec.def_vec, df_get_artificial_defs (bb->index), true);
|
||||||
df_refs_verify (collection_rec.use_vec, df_get_artificial_uses (bb->index), true);
|
df_refs_verify (&collection_rec.use_vec, df_get_artificial_uses (bb->index), true);
|
||||||
df_free_collection_rec (&collection_rec);
|
df_free_collection_rec (&collection_rec);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -190,15 +190,6 @@ warn_function_noreturn (tree decl)
|
|||||||
true, warned_about, "noreturn");
|
true, warned_about, "noreturn");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init the function state. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
finish_state (void)
|
|
||||||
{
|
|
||||||
funct_state_vec.release ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return true if we have a function state for NODE. */
|
/* Return true if we have a function state for NODE. */
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
@ -1488,7 +1479,6 @@ propagate (void)
|
|||||||
if (has_function_state (node))
|
if (has_function_state (node))
|
||||||
free (get_function_state (node));
|
free (get_function_state (node));
|
||||||
funct_state_vec.release ();
|
funct_state_vec.release ();
|
||||||
finish_state ();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4325,7 +4325,7 @@ typedef struct data_ref_loc_d
|
|||||||
true if STMT clobbers memory, false otherwise. */
|
true if STMT clobbers memory, false otherwise. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
get_references_in_stmt (gimple stmt, vec<data_ref_loc, va_stack> *references)
|
get_references_in_stmt (gimple stmt, vec<data_ref_loc, va_heap> *references)
|
||||||
{
|
{
|
||||||
bool clobbers_memory = false;
|
bool clobbers_memory = false;
|
||||||
data_ref_loc ref;
|
data_ref_loc ref;
|
||||||
@ -4417,17 +4417,13 @@ find_data_references_in_stmt (struct loop *nest, gimple stmt,
|
|||||||
vec<data_reference_p> *datarefs)
|
vec<data_reference_p> *datarefs)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
vec<data_ref_loc, va_stack> references;
|
stack_vec<data_ref_loc, 2> references;
|
||||||
data_ref_loc *ref;
|
data_ref_loc *ref;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
data_reference_p dr;
|
data_reference_p dr;
|
||||||
|
|
||||||
vec_stack_alloc (data_ref_loc, references, 2);
|
|
||||||
if (get_references_in_stmt (stmt, &references))
|
if (get_references_in_stmt (stmt, &references))
|
||||||
{
|
return false;
|
||||||
references.release ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (references, i, ref)
|
FOR_EACH_VEC_ELT (references, i, ref)
|
||||||
{
|
{
|
||||||
@ -4451,17 +4447,13 @@ graphite_find_data_references_in_stmt (loop_p nest, loop_p loop, gimple stmt,
|
|||||||
vec<data_reference_p> *datarefs)
|
vec<data_reference_p> *datarefs)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
vec<data_ref_loc, va_stack> references;
|
stack_vec<data_ref_loc, 2> references;
|
||||||
data_ref_loc *ref;
|
data_ref_loc *ref;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
data_reference_p dr;
|
data_reference_p dr;
|
||||||
|
|
||||||
vec_stack_alloc (data_ref_loc, references, 2);
|
|
||||||
if (get_references_in_stmt (stmt, &references))
|
if (get_references_in_stmt (stmt, &references))
|
||||||
{
|
return false;
|
||||||
references.release ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (references, i, ref)
|
FOR_EACH_VEC_ELT (references, i, ref)
|
||||||
{
|
{
|
||||||
|
@ -736,11 +736,8 @@ aliasing_component_refs_p (tree ref1,
|
|||||||
static bool
|
static bool
|
||||||
nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
|
nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
|
||||||
{
|
{
|
||||||
vec<tree, va_stack> component_refs1;
|
stack_vec<tree, 16> component_refs1;
|
||||||
vec<tree, va_stack> component_refs2;
|
stack_vec<tree, 16> component_refs2;
|
||||||
|
|
||||||
vec_stack_alloc (tree, component_refs1, 16);
|
|
||||||
vec_stack_alloc (tree, component_refs2, 16);
|
|
||||||
|
|
||||||
/* Create the stack of handled components for REF1. */
|
/* Create the stack of handled components for REF1. */
|
||||||
while (handled_component_p (ref1))
|
while (handled_component_p (ref1))
|
||||||
|
@ -1100,7 +1100,7 @@ propagate_constants_for_unrolling (basic_block bb)
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer,
|
tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer,
|
||||||
vec<loop_p, va_stack>& father_stack,
|
vec<loop_p, va_heap>& father_stack,
|
||||||
struct loop *loop)
|
struct loop *loop)
|
||||||
{
|
{
|
||||||
struct loop *loop_father;
|
struct loop *loop_father;
|
||||||
@ -1164,12 +1164,11 @@ tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer,
|
|||||||
unsigned int
|
unsigned int
|
||||||
tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
|
tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
|
||||||
{
|
{
|
||||||
vec<loop_p, va_stack> father_stack;
|
stack_vec<loop_p, 16> father_stack;
|
||||||
bool changed;
|
bool changed;
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
bool irred_invalidated = false;
|
bool irred_invalidated = false;
|
||||||
|
|
||||||
vec_stack_alloc (loop_p, father_stack, 16);
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
changed = false;
|
changed = false;
|
||||||
|
@ -644,7 +644,7 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec<tree, va_stack> fewvars = vNULL;
|
stack_vec<tree, alloc_count> fewvars;
|
||||||
pointer_set_t *vars = NULL;
|
pointer_set_t *vars = NULL;
|
||||||
|
|
||||||
/* If we're already starting with 3/4 of alloc_count, go for a
|
/* If we're already starting with 3/4 of alloc_count, go for a
|
||||||
@ -652,8 +652,6 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
|
|||||||
VEC. */
|
VEC. */
|
||||||
if (i * 4 > alloc_count * 3)
|
if (i * 4 > alloc_count * 3)
|
||||||
vars = pointer_set_create ();
|
vars = pointer_set_create ();
|
||||||
else if (alloc_count)
|
|
||||||
vec_stack_alloc (tree, fewvars, alloc_count);
|
|
||||||
|
|
||||||
/* Now go through the initial debug stmts in DEST again, this time
|
/* Now go through the initial debug stmts in DEST again, this time
|
||||||
actually inserting in VARS or FEWVARS. Don't bother checking for
|
actually inserting in VARS or FEWVARS. Don't bother checking for
|
||||||
|
@ -115,7 +115,7 @@ typedef struct
|
|||||||
with a PHI DEF that would soon become non-dominant, and when we got
|
with a PHI DEF that would soon become non-dominant, and when we got
|
||||||
to the suitable one, it wouldn't have anything to substitute any
|
to the suitable one, it wouldn't have anything to substitute any
|
||||||
more. */
|
more. */
|
||||||
static vec<adjust_info, va_stack> adjust_vec;
|
static vec<adjust_info, va_heap> adjust_vec;
|
||||||
|
|
||||||
/* Adjust any debug stmts that referenced AI->from values to use the
|
/* Adjust any debug stmts that referenced AI->from values to use the
|
||||||
loop-closed AI->to, if the references are dominated by AI->bb and
|
loop-closed AI->to, if the references are dominated by AI->bb and
|
||||||
@ -1133,7 +1133,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
|
|||||||
if (MAY_HAVE_DEBUG_STMTS)
|
if (MAY_HAVE_DEBUG_STMTS)
|
||||||
{
|
{
|
||||||
gcc_assert (!adjust_vec.exists ());
|
gcc_assert (!adjust_vec.exists ());
|
||||||
vec_stack_alloc (adjust_info, adjust_vec, 32);
|
adjust_vec.create (32);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e == exit_e)
|
if (e == exit_e)
|
||||||
|
@ -1934,7 +1934,7 @@ vect_slp_analyze_operations (bb_vec_info bb_vinfo)
|
|||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
vect_bb_slp_scalar_cost (basic_block bb,
|
vect_bb_slp_scalar_cost (basic_block bb,
|
||||||
slp_tree node, vec<bool, va_stack> life)
|
slp_tree node, vec<bool, va_heap> *life)
|
||||||
{
|
{
|
||||||
unsigned scalar_cost = 0;
|
unsigned scalar_cost = 0;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -1948,7 +1948,7 @@ vect_bb_slp_scalar_cost (basic_block bb,
|
|||||||
def_operand_p def_p;
|
def_operand_p def_p;
|
||||||
stmt_vec_info stmt_info;
|
stmt_vec_info stmt_info;
|
||||||
|
|
||||||
if (life[i])
|
if ((*life)[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If there is a non-vectorized use of the defs then the scalar
|
/* If there is a non-vectorized use of the defs then the scalar
|
||||||
@ -1965,11 +1965,11 @@ vect_bb_slp_scalar_cost (basic_block bb,
|
|||||||
|| gimple_bb (use_stmt) != bb
|
|| gimple_bb (use_stmt) != bb
|
||||||
|| !STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (use_stmt)))
|
|| !STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (use_stmt)))
|
||||||
{
|
{
|
||||||
life[i] = true;
|
(*life)[i] = true;
|
||||||
BREAK_FROM_IMM_USE_STMT (use_iter);
|
BREAK_FROM_IMM_USE_STMT (use_iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (life[i])
|
if ((*life)[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
stmt_info = vinfo_for_stmt (stmt);
|
stmt_info = vinfo_for_stmt (stmt);
|
||||||
@ -2023,13 +2023,11 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo)
|
|||||||
/* Calculate scalar cost. */
|
/* Calculate scalar cost. */
|
||||||
FOR_EACH_VEC_ELT (slp_instances, i, instance)
|
FOR_EACH_VEC_ELT (slp_instances, i, instance)
|
||||||
{
|
{
|
||||||
vec<bool, va_stack> life;
|
stack_vec<bool, 20> life;
|
||||||
vec_stack_alloc (bool, life, SLP_INSTANCE_GROUP_SIZE (instance));
|
life.safe_grow_cleared (SLP_INSTANCE_GROUP_SIZE (instance));
|
||||||
life.quick_grow_cleared (SLP_INSTANCE_GROUP_SIZE (instance));
|
|
||||||
scalar_cost += vect_bb_slp_scalar_cost (BB_VINFO_BB (bb_vinfo),
|
scalar_cost += vect_bb_slp_scalar_cost (BB_VINFO_BB (bb_vinfo),
|
||||||
SLP_INSTANCE_TREE (instance),
|
SLP_INSTANCE_TREE (instance),
|
||||||
life);
|
&life);
|
||||||
life.release ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete the target-specific cost calculation. */
|
/* Complete the target-specific cost calculation. */
|
||||||
|
@ -7907,7 +7907,7 @@ struct expand_loc_callback_data
|
|||||||
|
|
||||||
/* Stack of values and debug_exprs under expansion, and their
|
/* Stack of values and debug_exprs under expansion, and their
|
||||||
children. */
|
children. */
|
||||||
vec<rtx, va_stack> expanding;
|
stack_vec<rtx, 4> expanding;
|
||||||
|
|
||||||
/* Stack of values and debug_exprs whose expansion hit recursion
|
/* Stack of values and debug_exprs whose expansion hit recursion
|
||||||
cycles. They will have VALUE_RECURSED_INTO marked when added to
|
cycles. They will have VALUE_RECURSED_INTO marked when added to
|
||||||
@ -7915,7 +7915,7 @@ struct expand_loc_callback_data
|
|||||||
resolves to a valid location. So, if the flag remains set at the
|
resolves to a valid location. So, if the flag remains set at the
|
||||||
end of the search, we know no valid location for this one can
|
end of the search, we know no valid location for this one can
|
||||||
possibly exist. */
|
possibly exist. */
|
||||||
vec<rtx, va_stack> pending;
|
stack_vec<rtx, 4> pending;
|
||||||
|
|
||||||
/* The maximum depth among the sub-expressions under expansion.
|
/* The maximum depth among the sub-expressions under expansion.
|
||||||
Zero indicates no expansion so far. */
|
Zero indicates no expansion so far. */
|
||||||
@ -8417,11 +8417,11 @@ vt_expand_loc_callback (rtx x, bitmap regs,
|
|||||||
This function performs this finalization of NULL locations. */
|
This function performs this finalization of NULL locations. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resolve_expansions_pending_recursion (vec<rtx, va_stack> pending)
|
resolve_expansions_pending_recursion (vec<rtx, va_heap> *pending)
|
||||||
{
|
{
|
||||||
while (!pending.is_empty ())
|
while (!pending->is_empty ())
|
||||||
{
|
{
|
||||||
rtx x = pending.pop ();
|
rtx x = pending->pop ();
|
||||||
decl_or_value dv;
|
decl_or_value dv;
|
||||||
|
|
||||||
if (!VALUE_RECURSED_INTO (x))
|
if (!VALUE_RECURSED_INTO (x))
|
||||||
@ -8441,8 +8441,6 @@ resolve_expansions_pending_recursion (vec<rtx, va_stack> pending)
|
|||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
(d).vars = (v); \
|
(d).vars = (v); \
|
||||||
vec_stack_alloc (rtx, (d).expanding, 4); \
|
|
||||||
vec_stack_alloc (rtx, (d).pending, 4); \
|
|
||||||
(d).depth.complexity = (d).depth.entryvals = 0; \
|
(d).depth.complexity = (d).depth.entryvals = 0; \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
@ -8450,7 +8448,7 @@ resolve_expansions_pending_recursion (vec<rtx, va_stack> pending)
|
|||||||
#define FINI_ELCD(d, l) \
|
#define FINI_ELCD(d, l) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
resolve_expansions_pending_recursion ((d).pending); \
|
resolve_expansions_pending_recursion (&(d).pending); \
|
||||||
(d).pending.release (); \
|
(d).pending.release (); \
|
||||||
(d).expanding.release (); \
|
(d).expanding.release (); \
|
||||||
\
|
\
|
||||||
@ -8744,7 +8742,7 @@ emit_note_insn_var_location (variable_def **varp, emit_note_data *data)
|
|||||||
|
|
||||||
int
|
int
|
||||||
var_track_values_to_stack (variable_def **slot,
|
var_track_values_to_stack (variable_def **slot,
|
||||||
vec<rtx, va_stack> *changed_values_stack)
|
vec<rtx, va_heap> *changed_values_stack)
|
||||||
{
|
{
|
||||||
variable var = *slot;
|
variable var = *slot;
|
||||||
|
|
||||||
@ -8779,7 +8777,7 @@ remove_value_from_changed_variables (rtx val)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
notify_dependents_of_changed_value (rtx val, variable_table_type htab,
|
notify_dependents_of_changed_value (rtx val, variable_table_type htab,
|
||||||
vec<rtx, va_stack> *changed_values_stack)
|
vec<rtx, va_heap> *changed_values_stack)
|
||||||
{
|
{
|
||||||
variable_def **slot;
|
variable_def **slot;
|
||||||
variable var;
|
variable var;
|
||||||
@ -8864,13 +8862,11 @@ process_changed_values (variable_table_type htab)
|
|||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
rtx val;
|
rtx val;
|
||||||
vec<rtx, va_stack> changed_values_stack;
|
stack_vec<rtx, 20> changed_values_stack;
|
||||||
|
|
||||||
vec_stack_alloc (rtx, changed_values_stack, 20);
|
|
||||||
|
|
||||||
/* Move values from changed_variables to changed_values_stack. */
|
/* Move values from changed_variables to changed_values_stack. */
|
||||||
changed_variables
|
changed_variables
|
||||||
.traverse <vec<rtx, va_stack>*, var_track_values_to_stack>
|
.traverse <vec<rtx, va_heap>*, var_track_values_to_stack>
|
||||||
(&changed_values_stack);
|
(&changed_values_stack);
|
||||||
|
|
||||||
/* Back-propagate change notifications in values while popping
|
/* Back-propagate change notifications in values while popping
|
||||||
@ -8891,8 +8887,6 @@ process_changed_values (variable_table_type htab)
|
|||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changed_values_stack.release ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
|
/* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
|
||||||
|
43
gcc/vec.c
43
gcc/vec.c
@ -217,49 +217,6 @@ vec_prefix::calculate_allocation (vec_prefix *pfx, unsigned reserve,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Stack vectors are a little different. VEC_alloc turns into a call
|
|
||||||
to vec<T, A>::stack_reserve and passes in space allocated via a
|
|
||||||
call to alloca. We record that pointer so that we know that we
|
|
||||||
shouldn't free it. If the vector is resized, we resize it on the
|
|
||||||
heap. We record the pointers in a vector and search it in LIFO
|
|
||||||
order--i.e., we look for the newest stack vectors first. We don't
|
|
||||||
expect too many stack vectors at any one level, and searching from
|
|
||||||
the end should normally be efficient even if they are used in a
|
|
||||||
recursive function. */
|
|
||||||
|
|
||||||
static vec<void *> stack_vecs;
|
|
||||||
|
|
||||||
/* Add a stack vector to STACK_VECS. */
|
|
||||||
|
|
||||||
void
|
|
||||||
register_stack_vec (void *vec)
|
|
||||||
{
|
|
||||||
stack_vecs.safe_push (vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If VEC is registered in STACK_VECS, return its index.
|
|
||||||
Otherwise, return -1. */
|
|
||||||
|
|
||||||
int
|
|
||||||
stack_vec_register_index (void *vec)
|
|
||||||
{
|
|
||||||
for (unsigned ix = stack_vecs.length (); ix > 0; --ix)
|
|
||||||
if (stack_vecs[ix - 1] == vec)
|
|
||||||
return static_cast<int> (ix - 1);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Remove vector at slot IX from the list of registered stack vectors. */
|
|
||||||
|
|
||||||
void
|
|
||||||
unregister_stack_vec (unsigned ix)
|
|
||||||
{
|
|
||||||
stack_vecs.unordered_remove (ix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper for qsort; sort descriptors by amount of memory consumed. */
|
/* Helper for qsort; sort descriptors by amount of memory consumed. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
346
gcc/vec.h
346
gcc/vec.h
@ -101,8 +101,6 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
- Heap: allocation is done using malloc/free. This is the
|
- Heap: allocation is done using malloc/free. This is the
|
||||||
default allocation strategy.
|
default allocation strategy.
|
||||||
|
|
||||||
- Stack: allocation is done using alloca.
|
|
||||||
|
|
||||||
- GC: allocation is done using ggc_alloc/ggc_free.
|
- GC: allocation is done using ggc_alloc/ggc_free.
|
||||||
|
|
||||||
- GC atomic: same as GC with the exception that the elements
|
- GC atomic: same as GC with the exception that the elements
|
||||||
@ -233,9 +231,9 @@ struct vec_prefix
|
|||||||
friend struct va_gc;
|
friend struct va_gc;
|
||||||
friend struct va_gc_atomic;
|
friend struct va_gc_atomic;
|
||||||
friend struct va_heap;
|
friend struct va_heap;
|
||||||
friend struct va_stack;
|
|
||||||
|
|
||||||
unsigned m_alloc;
|
unsigned m_alloc : 31;
|
||||||
|
unsigned m_has_auto_buf : 1;
|
||||||
unsigned m_num;
|
unsigned m_num;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -255,8 +253,7 @@ struct vl_ptr { };
|
|||||||
va_heap - Allocation uses malloc/free.
|
va_heap - Allocation uses malloc/free.
|
||||||
va_gc - Allocation uses ggc_alloc.
|
va_gc - Allocation uses ggc_alloc.
|
||||||
va_gc_atomic - Same as GC, but individual elements of the array
|
va_gc_atomic - Same as GC, but individual elements of the array
|
||||||
do not need to be marked during collection.
|
do not need to be marked during collection. */
|
||||||
va_stack - Allocation uses alloca. */
|
|
||||||
|
|
||||||
/* Allocator type for heap vectors. */
|
/* Allocator type for heap vectors. */
|
||||||
struct va_heap
|
struct va_heap
|
||||||
@ -401,107 +398,6 @@ struct va_gc_atomic : va_gc
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Allocator type for stack vectors. */
|
|
||||||
struct va_stack
|
|
||||||
{
|
|
||||||
/* Use vl_ptr as the default layout for stack vectors. */
|
|
||||||
typedef vl_ptr default_layout;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static void alloc (vec<T, va_stack, vl_ptr>&, unsigned,
|
|
||||||
vec<T, va_stack, vl_embed> *);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static void reserve (vec<T, va_stack, vl_embed> *&, unsigned, bool
|
|
||||||
CXX_MEM_STAT_INFO);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static void release (vec<T, va_stack, vl_embed> *&);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Helper functions to keep track of vectors allocated on the stack. */
|
|
||||||
void register_stack_vec (void *);
|
|
||||||
int stack_vec_register_index (void *);
|
|
||||||
void unregister_stack_vec (unsigned);
|
|
||||||
|
|
||||||
/* Allocate a vector V which uses alloca for the initial allocation.
|
|
||||||
SPACE is space allocated using alloca. NELEMS is the number of
|
|
||||||
entries allocated. */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void
|
|
||||||
va_stack::alloc (vec<T, va_stack, vl_ptr> &v, unsigned nelems,
|
|
||||||
vec<T, va_stack, vl_embed> *space)
|
|
||||||
{
|
|
||||||
v.m_vec = space;
|
|
||||||
register_stack_vec (static_cast<void *> (v.m_vec));
|
|
||||||
v.m_vec->embedded_init (nelems, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Reserve NELEMS slots for a vector initially allocated on the stack.
|
|
||||||
When this happens, we switch back to heap allocation. We remove
|
|
||||||
the vector from stack_vecs, if it is there, since we no longer need
|
|
||||||
to avoid freeing it. If EXACT is true, grow exactly, otherwise
|
|
||||||
grow exponentially. */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void
|
|
||||||
va_stack::reserve (vec<T, va_stack, vl_embed> *&v, unsigned nelems, bool exact
|
|
||||||
MEM_STAT_DECL)
|
|
||||||
{
|
|
||||||
int ix = stack_vec_register_index (static_cast<void *> (v));
|
|
||||||
if (ix >= 0)
|
|
||||||
unregister_stack_vec (ix);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* V is already on the heap. */
|
|
||||||
va_heap::reserve (reinterpret_cast<vec<T, va_heap, vl_embed> *&> (v),
|
|
||||||
nelems, exact PASS_MEM_STAT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move VEC_ to the heap. */
|
|
||||||
nelems += v->m_vecpfx.m_num;
|
|
||||||
vec<T, va_stack, vl_embed> *oldvec = v;
|
|
||||||
v = NULL;
|
|
||||||
va_heap::reserve (reinterpret_cast<vec<T, va_heap, vl_embed> *&>(v), nelems,
|
|
||||||
exact PASS_MEM_STAT);
|
|
||||||
if (v && oldvec)
|
|
||||||
{
|
|
||||||
v->m_vecpfx.m_num = oldvec->length ();
|
|
||||||
memcpy (v->m_vecdata,
|
|
||||||
oldvec->m_vecdata,
|
|
||||||
oldvec->length () * sizeof (T));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Free a vector allocated on the stack. Don't actually free it if we
|
|
||||||
find it in the hash table. */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void
|
|
||||||
va_stack::release (vec<T, va_stack, vl_embed> *&v)
|
|
||||||
{
|
|
||||||
if (v == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int ix = stack_vec_register_index (static_cast<void *> (v));
|
|
||||||
if (ix >= 0)
|
|
||||||
{
|
|
||||||
unregister_stack_vec (ix);
|
|
||||||
v = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The vector was not on the list of vectors allocated on the stack, so it
|
|
||||||
must be allocated on the heap. */
|
|
||||||
va_heap::release (reinterpret_cast<vec<T, va_heap, vl_embed> *&> (v));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Generic vector template. Default values for A and L indicate the
|
/* Generic vector template. Default values for A and L indicate the
|
||||||
most commonly used strategies.
|
most commonly used strategies.
|
||||||
|
|
||||||
@ -597,7 +493,6 @@ public:
|
|||||||
friend struct va_gc;
|
friend struct va_gc;
|
||||||
friend struct va_gc_atomic;
|
friend struct va_gc_atomic;
|
||||||
friend struct va_heap;
|
friend struct va_heap;
|
||||||
friend struct va_stack;
|
|
||||||
|
|
||||||
/* FIXME - These fields should be private, but we need to cater to
|
/* FIXME - These fields should be private, but we need to cater to
|
||||||
compilers that have stricter notions of PODness for types. */
|
compilers that have stricter notions of PODness for types. */
|
||||||
@ -1112,6 +1007,7 @@ inline void
|
|||||||
vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num)
|
vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num)
|
||||||
{
|
{
|
||||||
m_vecpfx.m_alloc = alloc;
|
m_vecpfx.m_alloc = alloc;
|
||||||
|
m_vecpfx.m_has_auto_buf = 0;
|
||||||
m_vecpfx.m_num = num;
|
m_vecpfx.m_num = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1218,8 +1114,8 @@ gt_pch_nx (vec<T, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
|
|||||||
As long as we use C++03, we cannot have constructors nor
|
As long as we use C++03, we cannot have constructors nor
|
||||||
destructors in classes that are stored in unions. */
|
destructors in classes that are stored in unions. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
struct vec<T, A, vl_ptr>
|
struct vec<T, va_heap, vl_ptr>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* Memory allocation and deallocation for the embedded vector.
|
/* Memory allocation and deallocation for the embedded vector.
|
||||||
@ -1284,23 +1180,39 @@ public:
|
|||||||
void qsort (int (*) (const void *, const void *));
|
void qsort (int (*) (const void *, const void *));
|
||||||
unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
|
unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
|
||||||
|
|
||||||
template<typename T1>
|
bool using_auto_storage () const;
|
||||||
friend void va_stack::alloc (vec<T1, va_stack, vl_ptr>&, unsigned,
|
|
||||||
vec<T1, va_stack, vl_embed> *);
|
|
||||||
|
|
||||||
/* FIXME - This field should be private, but we need to cater to
|
/* FIXME - This field should be private, but we need to cater to
|
||||||
compilers that have stricter notions of PODness for types. */
|
compilers that have stricter notions of PODness for types. */
|
||||||
vec<T, A, vl_embed> *m_vec;
|
vec<T, va_heap, vl_embed> *m_vec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Empty specialization for GC allocation. This will prevent GC
|
/* stack_vec is a subclass of vec containing N elements of internal storage.
|
||||||
vectors from using the vl_ptr layout. FIXME: This is needed to
|
You probably only want to allocate this on the stack because if the array
|
||||||
circumvent limitations in the GTY machinery. */
|
ends up being larger or much smaller than N it will be wasting space. */
|
||||||
|
template<typename T, size_t N>
|
||||||
template<typename T>
|
class stack_vec : public vec<T, va_heap>
|
||||||
struct vec<T, va_gc, vl_ptr>
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
stack_vec ()
|
||||||
|
{
|
||||||
|
m_header.m_alloc = N;
|
||||||
|
m_header.m_has_auto_buf = 1;
|
||||||
|
m_header.m_num = 0;
|
||||||
|
this->m_vec = reinterpret_cast<vec<T, va_heap, vl_embed> *> (&m_header);
|
||||||
|
}
|
||||||
|
|
||||||
|
~stack_vec ()
|
||||||
|
{
|
||||||
|
this->release ();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class vec<T, va_heap, vl_ptr>;
|
||||||
|
|
||||||
|
vec_prefix m_header;
|
||||||
|
T m_data[N];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1343,45 +1255,6 @@ vec_free (vec<T> *&v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Allocate a new stack vector with space for exactly NELEMS objects.
|
|
||||||
If NELEMS is zero, NO vector is created.
|
|
||||||
|
|
||||||
For the stack allocator, no memory is really allocated. The vector
|
|
||||||
is initialized to be at address SPACE and contain NELEMS slots.
|
|
||||||
Memory allocation actually occurs in the expansion of VEC_alloc.
|
|
||||||
|
|
||||||
Usage notes:
|
|
||||||
|
|
||||||
* This does not allocate an instance of vec<T, A>. It allocates the
|
|
||||||
actual vector of elements (i.e., vec<T, A, vl_embed>) inside a
|
|
||||||
vec<T, A> instance.
|
|
||||||
|
|
||||||
* This allocator must always be a macro:
|
|
||||||
|
|
||||||
We support a vector which starts out with space on the stack and
|
|
||||||
switches to heap space when forced to reallocate. This works a
|
|
||||||
little differently. In the case of stack vectors, vec_alloc will
|
|
||||||
expand to a call to vec_alloc_1 that calls XALLOCAVAR to request
|
|
||||||
the initial allocation. This uses alloca to get the initial
|
|
||||||
space. Since alloca can not be usefully called in an inline
|
|
||||||
function, vec_alloc must always be a macro.
|
|
||||||
|
|
||||||
Important limitations of stack vectors:
|
|
||||||
|
|
||||||
- Only the initial allocation will be made using alloca, so pass
|
|
||||||
a reasonable estimate that doesn't use too much stack space;
|
|
||||||
don't pass zero.
|
|
||||||
|
|
||||||
- Don't return a stack-allocated vector from the function which
|
|
||||||
allocated it. */
|
|
||||||
|
|
||||||
#define vec_stack_alloc(T,V,N) \
|
|
||||||
do { \
|
|
||||||
typedef vec<T, va_stack, vl_embed> stackv; \
|
|
||||||
va_stack::alloc (V, N, XALLOCAVAR (stackv, stackv::embedded_size (N)));\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
/* Return iteration condition and update PTR to point to the IX'th
|
/* Return iteration condition and update PTR to point to the IX'th
|
||||||
element of this vector. Use this to iterate over the elements of a
|
element of this vector. Use this to iterate over the elements of a
|
||||||
vector as follows,
|
vector as follows,
|
||||||
@ -1389,9 +1262,9 @@ vec_free (vec<T> *&v)
|
|||||||
for (ix = 0; v.iterate (ix, &ptr); ix++)
|
for (ix = 0; v.iterate (ix, &ptr); ix++)
|
||||||
continue; */
|
continue; */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline bool
|
inline bool
|
||||||
vec<T, A, vl_ptr>::iterate (unsigned ix, T *ptr) const
|
vec<T, va_heap, vl_ptr>::iterate (unsigned ix, T *ptr) const
|
||||||
{
|
{
|
||||||
if (m_vec)
|
if (m_vec)
|
||||||
return m_vec->iterate (ix, ptr);
|
return m_vec->iterate (ix, ptr);
|
||||||
@ -1412,9 +1285,9 @@ vec<T, A, vl_ptr>::iterate (unsigned ix, T *ptr) const
|
|||||||
|
|
||||||
This variant is for vectors of objects. */
|
This variant is for vectors of objects. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline bool
|
inline bool
|
||||||
vec<T, A, vl_ptr>::iterate (unsigned ix, T **ptr) const
|
vec<T, va_heap, vl_ptr>::iterate (unsigned ix, T **ptr) const
|
||||||
{
|
{
|
||||||
if (m_vec)
|
if (m_vec)
|
||||||
return m_vec->iterate (ix, ptr);
|
return m_vec->iterate (ix, ptr);
|
||||||
@ -1451,11 +1324,11 @@ vec<T, A, vl_ptr>::iterate (unsigned ix, T **ptr) const
|
|||||||
|
|
||||||
/* Return a copy of this vector. */
|
/* Return a copy of this vector. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline vec<T, A, vl_ptr>
|
inline vec<T, va_heap, vl_ptr>
|
||||||
vec<T, A, vl_ptr>::copy (ALONE_MEM_STAT_DECL) const
|
vec<T, va_heap, vl_ptr>::copy (ALONE_MEM_STAT_DECL) const
|
||||||
{
|
{
|
||||||
vec<T, A, vl_ptr> new_vec = vNULL;
|
vec<T, va_heap, vl_ptr> new_vec = vNULL;
|
||||||
if (length ())
|
if (length ())
|
||||||
new_vec.m_vec = m_vec->copy ();
|
new_vec.m_vec = m_vec->copy ();
|
||||||
return new_vec;
|
return new_vec;
|
||||||
@ -1471,14 +1344,34 @@ vec<T, A, vl_ptr>::copy (ALONE_MEM_STAT_DECL) const
|
|||||||
Note that this can cause the embedded vector to be reallocated.
|
Note that this can cause the embedded vector to be reallocated.
|
||||||
Returns true iff reallocation actually occurred. */
|
Returns true iff reallocation actually occurred. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline bool
|
inline bool
|
||||||
vec<T, A, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL)
|
vec<T, va_heap, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL)
|
||||||
{
|
{
|
||||||
bool extend = nelems ? !space (nelems) : false;
|
if (!nelems || space (nelems))
|
||||||
if (extend)
|
return false;
|
||||||
A::reserve (m_vec, nelems, exact PASS_MEM_STAT);
|
|
||||||
return extend;
|
/* For now play a game with va_heap::reserve to hide our auto storage if any,
|
||||||
|
this is necessary because it doesn't have enough information to know the
|
||||||
|
embedded vector is in auto storage, and so should not be freed. */
|
||||||
|
vec<T, va_heap, vl_embed> *oldvec = m_vec;
|
||||||
|
unsigned int oldsize = 0;
|
||||||
|
bool handle_auto_vec = m_vec && using_auto_storage ();
|
||||||
|
if (handle_auto_vec)
|
||||||
|
{
|
||||||
|
m_vec = NULL;
|
||||||
|
oldsize = oldvec->length ();
|
||||||
|
nelems += oldsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_heap::reserve (m_vec, nelems, exact PASS_MEM_STAT);
|
||||||
|
if (handle_auto_vec)
|
||||||
|
{
|
||||||
|
memcpy (m_vec->address (), oldvec->address (), sizeof (T) * oldsize);
|
||||||
|
m_vec->m_vecpfx.m_num = oldsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1487,9 +1380,9 @@ vec<T, A, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL)
|
|||||||
embedded vector to be reallocated. Returns true iff reallocation
|
embedded vector to be reallocated. Returns true iff reallocation
|
||||||
actually occurred. */
|
actually occurred. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline bool
|
inline bool
|
||||||
vec<T, A, vl_ptr>::reserve_exact (unsigned nelems MEM_STAT_DECL)
|
vec<T, va_heap, vl_ptr>::reserve_exact (unsigned nelems MEM_STAT_DECL)
|
||||||
{
|
{
|
||||||
return reserve (nelems, true PASS_MEM_STAT);
|
return reserve (nelems, true PASS_MEM_STAT);
|
||||||
}
|
}
|
||||||
@ -1500,9 +1393,9 @@ vec<T, A, vl_ptr>::reserve_exact (unsigned nelems MEM_STAT_DECL)
|
|||||||
unconditionally allocated from scratch. The old one, if it
|
unconditionally allocated from scratch. The old one, if it
|
||||||
existed, is lost. */
|
existed, is lost. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::create (unsigned nelems MEM_STAT_DECL)
|
vec<T, va_heap, vl_ptr>::create (unsigned nelems MEM_STAT_DECL)
|
||||||
{
|
{
|
||||||
m_vec = NULL;
|
m_vec = NULL;
|
||||||
if (nelems > 0)
|
if (nelems > 0)
|
||||||
@ -1512,23 +1405,30 @@ vec<T, A, vl_ptr>::create (unsigned nelems MEM_STAT_DECL)
|
|||||||
|
|
||||||
/* Free the memory occupied by the embedded vector. */
|
/* Free the memory occupied by the embedded vector. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::release (void)
|
vec<T, va_heap, vl_ptr>::release (void)
|
||||||
{
|
{
|
||||||
if (m_vec)
|
if (!m_vec)
|
||||||
A::release (m_vec);
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
|
if (using_auto_storage ())
|
||||||
|
{
|
||||||
|
static_cast<stack_vec<T, 1> *> (this)->m_header.m_num = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_heap::release (m_vec);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the elements from SRC to the end of this vector as if by memcpy.
|
/* Copy the elements from SRC to the end of this vector as if by memcpy.
|
||||||
SRC and this vector must be allocated with the same memory
|
SRC and this vector must be allocated with the same memory
|
||||||
allocation mechanism. This vector is assumed to have sufficient
|
allocation mechanism. This vector is assumed to have sufficient
|
||||||
headroom available. */
|
headroom available. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::splice (vec<T, A, vl_ptr> &src)
|
vec<T, va_heap, vl_ptr>::splice (vec<T, va_heap, vl_ptr> &src)
|
||||||
{
|
{
|
||||||
if (src.m_vec)
|
if (src.m_vec)
|
||||||
m_vec->splice (*(src.m_vec));
|
m_vec->splice (*(src.m_vec));
|
||||||
@ -1540,9 +1440,10 @@ vec<T, A, vl_ptr>::splice (vec<T, A, vl_ptr> &src)
|
|||||||
If there is not enough headroom in this vector, it will be reallocated
|
If there is not enough headroom in this vector, it will be reallocated
|
||||||
as needed. */
|
as needed. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::safe_splice (vec<T, A, vl_ptr> &src MEM_STAT_DECL)
|
vec<T, va_heap, vl_ptr>::safe_splice (vec<T, va_heap, vl_ptr> &src
|
||||||
|
MEM_STAT_DECL)
|
||||||
{
|
{
|
||||||
if (src.length ())
|
if (src.length ())
|
||||||
{
|
{
|
||||||
@ -1556,9 +1457,9 @@ vec<T, A, vl_ptr>::safe_splice (vec<T, A, vl_ptr> &src MEM_STAT_DECL)
|
|||||||
sufficient space in the vector. Return a pointer to the slot
|
sufficient space in the vector. Return a pointer to the slot
|
||||||
where OBJ was inserted. */
|
where OBJ was inserted. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline T *
|
inline T *
|
||||||
vec<T, A, vl_ptr>::quick_push (const T &obj)
|
vec<T, va_heap, vl_ptr>::quick_push (const T &obj)
|
||||||
{
|
{
|
||||||
return m_vec->quick_push (obj);
|
return m_vec->quick_push (obj);
|
||||||
}
|
}
|
||||||
@ -1568,9 +1469,9 @@ vec<T, A, vl_ptr>::quick_push (const T &obj)
|
|||||||
the embedded vector, if needed. Return a pointer to the slot where
|
the embedded vector, if needed. Return a pointer to the slot where
|
||||||
OBJ was inserted. */
|
OBJ was inserted. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline T *
|
inline T *
|
||||||
vec<T, A, vl_ptr>::safe_push (const T &obj MEM_STAT_DECL)
|
vec<T, va_heap, vl_ptr>::safe_push (const T &obj MEM_STAT_DECL)
|
||||||
{
|
{
|
||||||
reserve (1, false PASS_MEM_STAT);
|
reserve (1, false PASS_MEM_STAT);
|
||||||
return quick_push (obj);
|
return quick_push (obj);
|
||||||
@ -1579,9 +1480,9 @@ vec<T, A, vl_ptr>::safe_push (const T &obj MEM_STAT_DECL)
|
|||||||
|
|
||||||
/* Pop and return the last element off the end of the vector. */
|
/* Pop and return the last element off the end of the vector. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline T &
|
inline T &
|
||||||
vec<T, A, vl_ptr>::pop (void)
|
vec<T, va_heap, vl_ptr>::pop (void)
|
||||||
{
|
{
|
||||||
return m_vec->pop ();
|
return m_vec->pop ();
|
||||||
}
|
}
|
||||||
@ -1590,9 +1491,9 @@ vec<T, A, vl_ptr>::pop (void)
|
|||||||
/* Set the length of the vector to LEN. The new length must be less
|
/* Set the length of the vector to LEN. The new length must be less
|
||||||
than or equal to the current length. This is an O(1) operation. */
|
than or equal to the current length. This is an O(1) operation. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::truncate (unsigned size)
|
vec<T, va_heap, vl_ptr>::truncate (unsigned size)
|
||||||
{
|
{
|
||||||
if (m_vec)
|
if (m_vec)
|
||||||
m_vec->truncate (size);
|
m_vec->truncate (size);
|
||||||
@ -1605,9 +1506,9 @@ vec<T, A, vl_ptr>::truncate (unsigned size)
|
|||||||
longer than the current length. The new elements are
|
longer than the current length. The new elements are
|
||||||
uninitialized. Reallocate the internal vector, if needed. */
|
uninitialized. Reallocate the internal vector, if needed. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
|
vec<T, va_heap, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
|
||||||
{
|
{
|
||||||
unsigned oldlen = length ();
|
unsigned oldlen = length ();
|
||||||
gcc_checking_assert (oldlen <= len);
|
gcc_checking_assert (oldlen <= len);
|
||||||
@ -1620,9 +1521,9 @@ vec<T, A, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
|
|||||||
long or longer than the current length. The new elements are
|
long or longer than the current length. The new elements are
|
||||||
initialized to zero. Reallocate the internal vector, if needed. */
|
initialized to zero. Reallocate the internal vector, if needed. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL)
|
vec<T, va_heap, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL)
|
||||||
{
|
{
|
||||||
unsigned oldlen = length ();
|
unsigned oldlen = length ();
|
||||||
safe_grow (len PASS_MEM_STAT);
|
safe_grow (len PASS_MEM_STAT);
|
||||||
@ -1633,9 +1534,9 @@ vec<T, A, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL)
|
|||||||
/* Same as vec::safe_grow but without reallocation of the internal vector.
|
/* Same as vec::safe_grow but without reallocation of the internal vector.
|
||||||
If the vector cannot be extended, a runtime assertion will be triggered. */
|
If the vector cannot be extended, a runtime assertion will be triggered. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::quick_grow (unsigned len)
|
vec<T, va_heap, vl_ptr>::quick_grow (unsigned len)
|
||||||
{
|
{
|
||||||
gcc_checking_assert (m_vec);
|
gcc_checking_assert (m_vec);
|
||||||
m_vec->quick_grow (len);
|
m_vec->quick_grow (len);
|
||||||
@ -1646,9 +1547,9 @@ vec<T, A, vl_ptr>::quick_grow (unsigned len)
|
|||||||
internal vector. If the vector cannot be extended, a runtime
|
internal vector. If the vector cannot be extended, a runtime
|
||||||
assertion will be triggered. */
|
assertion will be triggered. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::quick_grow_cleared (unsigned len)
|
vec<T, va_heap, vl_ptr>::quick_grow_cleared (unsigned len)
|
||||||
{
|
{
|
||||||
gcc_checking_assert (m_vec);
|
gcc_checking_assert (m_vec);
|
||||||
m_vec->quick_grow_cleared (len);
|
m_vec->quick_grow_cleared (len);
|
||||||
@ -1658,9 +1559,9 @@ vec<T, A, vl_ptr>::quick_grow_cleared (unsigned len)
|
|||||||
/* Insert an element, OBJ, at the IXth position of this vector. There
|
/* Insert an element, OBJ, at the IXth position of this vector. There
|
||||||
must be sufficient space. */
|
must be sufficient space. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::quick_insert (unsigned ix, const T &obj)
|
vec<T, va_heap, vl_ptr>::quick_insert (unsigned ix, const T &obj)
|
||||||
{
|
{
|
||||||
m_vec->quick_insert (ix, obj);
|
m_vec->quick_insert (ix, obj);
|
||||||
}
|
}
|
||||||
@ -1669,9 +1570,9 @@ vec<T, A, vl_ptr>::quick_insert (unsigned ix, const T &obj)
|
|||||||
/* Insert an element, OBJ, at the IXth position of the vector.
|
/* Insert an element, OBJ, at the IXth position of the vector.
|
||||||
Reallocate the embedded vector, if necessary. */
|
Reallocate the embedded vector, if necessary. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::safe_insert (unsigned ix, const T &obj MEM_STAT_DECL)
|
vec<T, va_heap, vl_ptr>::safe_insert (unsigned ix, const T &obj MEM_STAT_DECL)
|
||||||
{
|
{
|
||||||
reserve (1, false PASS_MEM_STAT);
|
reserve (1, false PASS_MEM_STAT);
|
||||||
quick_insert (ix, obj);
|
quick_insert (ix, obj);
|
||||||
@ -1682,9 +1583,9 @@ vec<T, A, vl_ptr>::safe_insert (unsigned ix, const T &obj MEM_STAT_DECL)
|
|||||||
remaining elements is preserved. This is an O(N) operation due to
|
remaining elements is preserved. This is an O(N) operation due to
|
||||||
a memmove. */
|
a memmove. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::ordered_remove (unsigned ix)
|
vec<T, va_heap, vl_ptr>::ordered_remove (unsigned ix)
|
||||||
{
|
{
|
||||||
m_vec->ordered_remove (ix);
|
m_vec->ordered_remove (ix);
|
||||||
}
|
}
|
||||||
@ -1693,9 +1594,9 @@ vec<T, A, vl_ptr>::ordered_remove (unsigned ix)
|
|||||||
/* Remove an element from the IXth position of this vector. Ordering
|
/* Remove an element from the IXth position of this vector. Ordering
|
||||||
of remaining elements is destroyed. This is an O(1) operation. */
|
of remaining elements is destroyed. This is an O(1) operation. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::unordered_remove (unsigned ix)
|
vec<T, va_heap, vl_ptr>::unordered_remove (unsigned ix)
|
||||||
{
|
{
|
||||||
m_vec->unordered_remove (ix);
|
m_vec->unordered_remove (ix);
|
||||||
}
|
}
|
||||||
@ -1704,9 +1605,9 @@ vec<T, A, vl_ptr>::unordered_remove (unsigned ix)
|
|||||||
/* Remove LEN elements starting at the IXth. Ordering is retained.
|
/* Remove LEN elements starting at the IXth. Ordering is retained.
|
||||||
This is an O(N) operation due to memmove. */
|
This is an O(N) operation due to memmove. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::block_remove (unsigned ix, unsigned len)
|
vec<T, va_heap, vl_ptr>::block_remove (unsigned ix, unsigned len)
|
||||||
{
|
{
|
||||||
m_vec->block_remove (ix, len);
|
m_vec->block_remove (ix, len);
|
||||||
}
|
}
|
||||||
@ -1715,9 +1616,9 @@ vec<T, A, vl_ptr>::block_remove (unsigned ix, unsigned len)
|
|||||||
/* Sort the contents of this vector with qsort. CMP is the comparison
|
/* Sort the contents of this vector with qsort. CMP is the comparison
|
||||||
function to pass to qsort. */
|
function to pass to qsort. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
vec<T, A, vl_ptr>::qsort (int (*cmp) (const void *, const void *))
|
vec<T, va_heap, vl_ptr>::qsort (int (*cmp) (const void *, const void *))
|
||||||
{
|
{
|
||||||
if (m_vec)
|
if (m_vec)
|
||||||
m_vec->qsort (cmp);
|
m_vec->qsort (cmp);
|
||||||
@ -1729,14 +1630,27 @@ vec<T, A, vl_ptr>::qsort (int (*cmp) (const void *, const void *))
|
|||||||
function that returns true if the first argument is strictly less
|
function that returns true if the first argument is strictly less
|
||||||
than the second. */
|
than the second. */
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T>
|
||||||
inline unsigned
|
inline unsigned
|
||||||
vec<T, A, vl_ptr>::lower_bound (T obj, bool (*lessthan)(const T &, const T &))
|
vec<T, va_heap, vl_ptr>::lower_bound (T obj,
|
||||||
|
bool (*lessthan)(const T &, const T &))
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
return m_vec ? m_vec->lower_bound (obj, lessthan) : 0;
|
return m_vec ? m_vec->lower_bound (obj, lessthan) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool
|
||||||
|
vec<T, va_heap, vl_ptr>::using_auto_storage () const
|
||||||
|
{
|
||||||
|
if (!m_vec->m_vecpfx.m_has_auto_buf)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const vec_prefix *auto_header
|
||||||
|
= &static_cast<const stack_vec<T, 1> *> (this)->m_header;
|
||||||
|
return reinterpret_cast<vec_prefix *> (m_vec) == auto_header;
|
||||||
|
}
|
||||||
|
|
||||||
#if (GCC_VERSION >= 3000)
|
#if (GCC_VERSION >= 3000)
|
||||||
# pragma GCC poison m_vec m_vecpfx m_vecdata
|
# pragma GCC poison m_vec m_vecpfx m_vecdata
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user