From b512946c8932f373507943fe4d30156a1afd18eb Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sun, 15 Jun 2014 07:39:30 +0000 Subject: [PATCH] df.h (df_mw_hardreg, [...]): Add a link pointer. gcc/ * df.h (df_mw_hardreg, df_base_ref): Add a link pointer. (df_insn_info): Turn defs, uses, eq_uses and mw_hardregs into linked lists. (df_scan_bb_info): Likewise artificial_defs and artificial_uses. (DF_REF_NEXT_LOC, DF_MWS_NEXT): New macros. (FOR_EACH_INSN_INFO_DEF, FOR_EACH_INSN_INFO_USE) (FOR_EACH_INSN_INFO_EQ_USE, FOR_EACH_INSN_INFO_MW) (FOR_EACH_ARTIFICIAL_USE, FOR_EACH_ARTIFICIAL_DEF) (df_get_artificial_defs, df_get_artificial_uses) (df_single_def, df_single_use): Update accordingly. (df_refs_chain_dump): Take the first element in a linked list as parameter, rather than a pointer to an array of pointers. * df-core.c (df_refs_chain_dump, df_mws_dump): Likewise. * df-problems.c (df_rd_bb_local_compute_process_def): Likewise. (df_chain_create_bb_process_use): Likewise. (df_md_bb_local_compute_process_def): Likewise. * fwprop.c (process_defs, process_uses): Likewise. (register_active_defs, update_uses): Likewise. (forward_propagate_asm): Update for new df_ref linking. * df-scan.c (df_scan_free_ref_vec, df_scan_free_mws_vec): Delete. (df_null_ref_rec, df_null_mw_rec): Likewise. (df_scan_free_internal): Don't free df_ref and df_mw_hardreg lists explicitly. (df_scan_free_bb_info): Remove check for null artificial_defs. (df_install_ref_incremental): Adjust for new df_ref linking. Use a single-element insertion rather than a full sort. (df_ref_chain_delete_du_chain): Take the first element in a linked list as parameter, rather than a pointer to an array of pointers. (df_ref_chain_delete, df_mw_hardreg_chain_delete): Likewise. (df_add_refs_to_table, df_refs_verify, df_mws_verify): Likewise. (df_insn_info_delete): Remove check for null defs and call to df_scan_free_mws_vec. (df_insn_rescan): Initialize df_ref and df_mw_hardreg lists to null rather than df_null_*_rec. (df_insn_rescan_debug_internal): Likewise, and update null checks in the same way. Remove check for null defs. (df_ref_change_reg_with_loc_1): Fix choice of list for defs. Move a single element rather doing a full sort. (df_mw_hardreg_chain_delete_eq_uses): Adjust for new df_mw_hardreg linking. (df_notes_rescan): Likewise. Use a merge rather than a full sort. Initialize df_ref and df_mw_hardreg lists to null rather than df_null_*_rec. (df_ref_compare): Take df_refs as parameter, transferring the old interface to... (df_ref_ptr_compare): ...this new function. (df_sort_and_compress_refs): Update accordingly. (df_mw_compare): Take df_mw_hardregs as parameter, transferring the old interface to... (df_mw_ptr_compare): ...this new function. (df_sort_and_compress_mws): Update accordingly. (df_install_refs, df_install_mws): Return a linked list rather than an array of pointers. (df_refs_add_to_chains): Assert that old lists are empty rather than freeing them. (df_insn_refs_verify): Don't handle null defs speciailly. * web.c (union_match_dups): Update for new df_ref linking. From-SVN: r211683 --- gcc/ChangeLog | 61 +++++++ gcc/df-core.c | 19 +- gcc/df-problems.c | 18 +- gcc/df-scan.c | 509 +++++++++++++++++++----------------------------------- gcc/df.h | 50 +++--- gcc/fwprop.c | 26 ++- gcc/web.c | 42 ++--- 7 files changed, 313 insertions(+), 412 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3477ff9..eeda7d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,66 @@ 2014-06-15 Richard Sandiford + * df.h (df_mw_hardreg, df_base_ref): Add a link pointer. + (df_insn_info): Turn defs, uses, eq_uses and mw_hardregs into linked + lists. + (df_scan_bb_info): Likewise artificial_defs and artificial_uses. + (DF_REF_NEXT_LOC, DF_MWS_NEXT): New macros. + (FOR_EACH_INSN_INFO_DEF, FOR_EACH_INSN_INFO_USE) + (FOR_EACH_INSN_INFO_EQ_USE, FOR_EACH_INSN_INFO_MW) + (FOR_EACH_ARTIFICIAL_USE, FOR_EACH_ARTIFICIAL_DEF) + (df_get_artificial_defs, df_get_artificial_uses) + (df_single_def, df_single_use): Update accordingly. + (df_refs_chain_dump): Take the first element in a linked list as + parameter, rather than a pointer to an array of pointers. + * df-core.c (df_refs_chain_dump, df_mws_dump): Likewise. + * df-problems.c (df_rd_bb_local_compute_process_def): Likewise. + (df_chain_create_bb_process_use): Likewise. + (df_md_bb_local_compute_process_def): Likewise. + * fwprop.c (process_defs, process_uses): Likewise. + (register_active_defs, update_uses): Likewise. + (forward_propagate_asm): Update for new df_ref linking. + * df-scan.c (df_scan_free_ref_vec, df_scan_free_mws_vec): Delete. + (df_null_ref_rec, df_null_mw_rec): Likewise. + (df_scan_free_internal): Don't free df_ref and df_mw_hardreg lists + explicitly. + (df_scan_free_bb_info): Remove check for null artificial_defs. + (df_install_ref_incremental): Adjust for new df_ref linking. + Use a single-element insertion rather than a full sort. + (df_ref_chain_delete_du_chain): Take the first element + in a linked list as parameter, rather than a pointer to an array of + pointers. + (df_ref_chain_delete, df_mw_hardreg_chain_delete): Likewise. + (df_add_refs_to_table, df_refs_verify, df_mws_verify): Likewise. + (df_insn_info_delete): Remove check for null defs and call to + df_scan_free_mws_vec. + (df_insn_rescan): Initialize df_ref and df_mw_hardreg lists to + null rather than df_null_*_rec. + (df_insn_rescan_debug_internal): Likewise, and update null + checks in the same way. Remove check for null defs. + (df_ref_change_reg_with_loc_1): Fix choice of list for defs. + Move a single element rather doing a full sort. + (df_mw_hardreg_chain_delete_eq_uses): Adjust for new df_mw_hardreg + linking. + (df_notes_rescan): Likewise. Use a merge rather than a full sort. + Initialize df_ref and df_mw_hardreg lists to null rather than + df_null_*_rec. + (df_ref_compare): Take df_refs as parameter, transferring the + old interface to... + (df_ref_ptr_compare): ...this new function. + (df_sort_and_compress_refs): Update accordingly. + (df_mw_compare): Take df_mw_hardregs as parameter, transferring the + old interface to... + (df_mw_ptr_compare): ...this new function. + (df_sort_and_compress_mws): Update accordingly. + (df_install_refs, df_install_mws): Return a linked list rather than + an array of pointers. + (df_refs_add_to_chains): Assert that old lists are empty rather + than freeing them. + (df_insn_refs_verify): Don't handle null defs speciailly. + * web.c (union_match_dups): Update for new df_ref linking. + +2014-06-15 Richard Sandiford + * df.h (df_ref_create, df_ref_remove): Delete. * df-scan.c (df_ref_create, df_ref_compress_rec): Likewise. (df_ref_remove): Likewise. diff --git a/gcc/df-core.c b/gcc/df-core.c index 01d3bee..074b320 100644 --- a/gcc/df-core.c +++ b/gcc/df-core.c @@ -2319,16 +2319,14 @@ df_ref_dump (df_ref ref, FILE *file) } void -df_refs_chain_dump (df_ref *ref_rec, bool follow_chain, FILE *file) +df_refs_chain_dump (df_ref ref, bool follow_chain, FILE *file) { fprintf (file, "{ "); - while (*ref_rec) + for (; ref; ref = DF_REF_NEXT_LOC (ref)) { - df_ref ref = *ref_rec; df_ref_dump (ref, file); if (follow_chain) df_chain_dump (DF_REF_CHAIN (ref), file); - ref_rec++; } fprintf (file, "}"); } @@ -2350,15 +2348,12 @@ df_regs_chain_dump (df_ref ref, FILE *file) static void -df_mws_dump (struct df_mw_hardreg **mws, FILE *file) +df_mws_dump (struct df_mw_hardreg *mws, FILE *file) { - while (*mws) - { - fprintf (file, "mw %c r[%d..%d]\n", - (DF_MWS_REG_DEF_P (*mws)) ? 'd' : 'u', - (*mws)->start_regno, (*mws)->end_regno); - mws++; - } + for (; mws; mws = DF_MWS_NEXT (mws)) + fprintf (file, "mw %c r[%d..%d]\n", + DF_MWS_REG_DEF_P (mws) ? 'd' : 'u', + mws->start_regno, mws->end_regno); } diff --git a/gcc/df-problems.c b/gcc/df-problems.c index d97e287..e824865 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -291,12 +291,11 @@ df_rd_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn, static void df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info, - df_ref *def_rec, + df_ref def, int top_flag) { - while (*def_rec) + for (; def; def = DF_REF_NEXT_LOC (def)) { - df_ref def = *def_rec; if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP)) { unsigned int regno = DF_REF_REGNO (def); @@ -339,7 +338,6 @@ df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info, } } } - def_rec++; } } @@ -2022,15 +2020,14 @@ df_chain_reset (bitmap blocks_to_clear ATTRIBUTE_UNUSED) static void df_chain_create_bb_process_use (bitmap local_rd, - df_ref *use_rec, + df_ref use, int top_flag) { bitmap_iterator bi; unsigned int def_index; - while (*use_rec) + for (; use; use = DF_REF_NEXT_LOC (use)) { - df_ref use = *use_rec; unsigned int uregno = DF_REF_REGNO (use); if ((!(df->changeable_flags & DF_NO_HARD_REGS)) || (uregno >= FIRST_PSEUDO_REGISTER)) @@ -2059,8 +2056,6 @@ df_chain_create_bb_process_use (bitmap local_rd, } } } - - use_rec++; } } @@ -4077,13 +4072,12 @@ df_md_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn, static void df_md_bb_local_compute_process_def (struct df_md_bb_info *bb_info, - df_ref *def_rec, + df_ref def, int top_flag) { - df_ref def; bitmap_clear (&seen_in_insn); - while ((def = *def_rec++) != NULL) + for (; def; def = DF_REF_NEXT_LOC (def)) { unsigned int dregno = DF_REF_REGNO (def); if (((!(df->changeable_flags & DF_NO_HARD_REGS)) diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 0033d6d..f1ba808 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -62,21 +62,6 @@ typedef struct df_mw_hardreg *df_mw_hardreg_ptr; #define EPILOGUE_USES(REGNO) 0 #endif -/* The following two macros free the vecs that hold either the refs or - the mw refs. They are a little tricky because the vec has 0 - elements is special and is not to be freed. */ -#define df_scan_free_ref_vec(V) \ - do { \ - if (V && *V) \ - free (V); \ - } while (0) - -#define df_scan_free_mws_vec(V) \ - do { \ - if (V && *V) \ - free (V); \ - } while (0) - /* The set of hard registers in eliminables[i].from. */ static HARD_REG_SET elim_reg_set; @@ -92,9 +77,6 @@ struct df_collection_rec auto_vec mw_vec; }; -static df_ref df_null_ref_rec[1]; -static struct df_mw_hardreg * df_null_mw_rec[1]; - static void df_ref_record (enum df_ref_class, struct df_collection_rec *, rtx, rtx *, basic_block, struct df_insn_info *, @@ -123,8 +105,8 @@ static void df_record_exit_block_uses (bitmap); static void df_get_exit_block_use_set (bitmap); static void df_get_entry_block_def_set (bitmap); static void df_grow_ref_info (struct df_ref_info *, unsigned int); -static void df_ref_chain_delete_du_chain (df_ref *); -static void df_ref_chain_delete (df_ref *); +static void df_ref_chain_delete_du_chain (df_ref); +static void df_ref_chain_delete (df_ref); static void df_refs_add_to_chains (struct df_collection_rec *, basic_block, rtx, unsigned int); @@ -135,8 +117,10 @@ static void df_exit_block_uses_collect (struct df_collection_rec *, bitmap); static void df_install_ref (df_ref, struct df_reg_info *, struct df_ref_info *, bool); -static int df_ref_compare (const void *, const void *); -static int df_mw_compare (const void *, const void *); +static int df_ref_compare (df_ref, df_ref); +static int df_ref_ptr_compare (const void *, const void *); +static int df_mw_compare (const df_mw_hardreg *, const df_mw_hardreg *); +static int df_mw_ptr_compare (const void *, const void *); static void df_insn_info_delete (unsigned int); @@ -189,36 +173,6 @@ df_scan_free_internal (void) { struct df_scan_problem_data *problem_data = (struct df_scan_problem_data *) df_scan->problem_data; - unsigned int i; - basic_block bb; - - /* The vectors that hold the refs are not pool allocated because - they come in many sizes. This makes them impossible to delete - all at once. */ - for (i = 0; i < DF_INSN_SIZE (); i++) - { - struct df_insn_info *insn_info = DF_INSN_UID_GET (i); - /* Skip the insns that have no insn_info or have been - deleted. */ - if (insn_info) - { - df_scan_free_ref_vec (insn_info->defs); - df_scan_free_ref_vec (insn_info->uses); - df_scan_free_ref_vec (insn_info->eq_uses); - df_scan_free_mws_vec (insn_info->mw_hardregs); - } - } - - FOR_ALL_BB_FN (bb, cfun) - { - unsigned int bb_index = bb->index; - struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index); - if (bb_info) - { - df_scan_free_ref_vec (bb_info->artificial_defs); - df_scan_free_ref_vec (bb_info->artificial_uses); - } - } free (df->def_info.refs); free (df->def_info.begin); @@ -275,31 +229,22 @@ df_scan_free_bb_info (basic_block bb, void *vbb_info) { struct df_scan_bb_info *bb_info = (struct df_scan_bb_info *) vbb_info; unsigned int bb_index = bb->index; + rtx insn; - /* See if bb_info is initialized. */ - if (bb_info->artificial_defs) - { - rtx insn; - FOR_BB_INSNS (bb, insn) - { - if (INSN_P (insn)) - df_insn_info_delete (INSN_UID (insn)); - } - - if (bb_index < df_scan->block_info_size) - bb_info = df_scan_get_bb_info (bb_index); - - /* Get rid of any artificial uses or defs. */ - if (bb_info->artificial_defs) - { - df_ref_chain_delete_du_chain (bb_info->artificial_defs); - df_ref_chain_delete_du_chain (bb_info->artificial_uses); - df_ref_chain_delete (bb_info->artificial_defs); - df_ref_chain_delete (bb_info->artificial_uses); - bb_info->artificial_defs = NULL; - bb_info->artificial_uses = NULL; - } - } + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + df_insn_info_delete (INSN_UID (insn)); + + if (bb_index < df_scan->block_info_size) + bb_info = df_scan_get_bb_info (bb_index); + + /* Get rid of any artificial uses or defs. */ + df_ref_chain_delete_du_chain (bb_info->artificial_defs); + df_ref_chain_delete_du_chain (bb_info->artificial_uses); + df_ref_chain_delete (bb_info->artificial_defs); + df_ref_chain_delete (bb_info->artificial_uses); + bb_info->artificial_defs = NULL; + bb_info->artificial_uses = NULL; } @@ -695,9 +640,7 @@ df_install_ref_incremental (df_ref ref) { struct df_reg_info **reg_info; struct df_ref_info *ref_info; - df_ref *ref_rec; - df_ref **ref_rec_ptr; - unsigned int count = 0; + df_ref *ref_ptr; bool add_to_table; rtx insn = DF_REF_INSN (ref); @@ -707,14 +650,14 @@ df_install_ref_incremental (df_ref ref) { reg_info = df->def_regs; ref_info = &df->def_info; - ref_rec_ptr = &DF_INSN_DEFS (insn); + ref_ptr = &DF_INSN_DEFS (insn); add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE; } else if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) { reg_info = df->eq_use_regs; ref_info = &df->use_info; - ref_rec_ptr = &DF_INSN_EQ_USES (insn); + ref_ptr = &DF_INSN_EQ_USES (insn); switch (ref_info->ref_order) { case DF_REF_ORDER_UNORDERED_WITH_NOTES: @@ -731,7 +674,7 @@ df_install_ref_incremental (df_ref ref) { reg_info = df->use_regs; ref_info = &df->use_info; - ref_rec_ptr = &DF_INSN_USES (insn); + ref_ptr = &DF_INSN_USES (insn); add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE; } @@ -754,29 +697,11 @@ df_install_ref_incremental (df_ref ref) break; } - ref_rec = *ref_rec_ptr; - while (*ref_rec) - { - count++; - ref_rec++; - } + while (*ref_ptr && df_ref_compare (*ref_ptr, ref) < 0) + ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr); - ref_rec = *ref_rec_ptr; - if (count) - { - ref_rec = XRESIZEVEC (df_ref, ref_rec, count+2); - *ref_rec_ptr = ref_rec; - ref_rec[count] = ref; - ref_rec[count+1] = NULL; - qsort (ref_rec, count + 1, sizeof (df_ref), df_ref_compare); - } - else - { - df_ref *ref_rec = XNEWVEC (df_ref, 2); - ref_rec[0] = ref; - ref_rec[1] = NULL; - *ref_rec_ptr = ref_rec; - } + DF_REF_NEXT_LOC (ref) = *ref_ptr; + *ref_ptr = ref; #if 0 if (dump_file) @@ -930,55 +855,43 @@ df_insn_create_insn_record (rtx insn) /* Delete all du chain (DF_REF_CHAIN()) of all refs in the ref chain. */ static void -df_ref_chain_delete_du_chain (df_ref *ref_rec) +df_ref_chain_delete_du_chain (df_ref ref) { - while (*ref_rec) - { - df_ref ref = *ref_rec; - /* CHAIN is allocated by DF_CHAIN. So make sure to - pass df_scan instance for the problem. */ - if (DF_REF_CHAIN (ref)) - df_chain_unlink (ref); - ref_rec++; - } + for (; ref; ref = DF_REF_NEXT_LOC (ref)) + /* CHAIN is allocated by DF_CHAIN. So make sure to + pass df_scan instance for the problem. */ + if (DF_REF_CHAIN (ref)) + df_chain_unlink (ref); } /* Delete all refs in the ref chain. */ static void -df_ref_chain_delete (df_ref *ref_rec) +df_ref_chain_delete (df_ref ref) { - df_ref *start = ref_rec; - while (*ref_rec) + df_ref next; + for (; ref; ref = next) { - df_reg_chain_unlink (*ref_rec); - ref_rec++; + next = DF_REF_NEXT_LOC (ref); + df_reg_chain_unlink (ref); } - - /* If the list is empty, it has a special shared element that is not - to be deleted. */ - if (*start) - free (start); } /* Delete the hardreg chain. */ static void -df_mw_hardreg_chain_delete (struct df_mw_hardreg **hardregs) +df_mw_hardreg_chain_delete (struct df_mw_hardreg *hardregs) { - struct df_scan_problem_data *problem_data; - - if (!hardregs) - return; - - problem_data = (struct df_scan_problem_data *) df_scan->problem_data; + struct df_scan_problem_data *problem_data + = (struct df_scan_problem_data *) df_scan->problem_data; + df_mw_hardreg *next; - while (*hardregs) + for (; hardregs; hardregs = next) { - pool_free (problem_data->mw_reg_pool, *hardregs); - hardregs++; + next = DF_MWS_NEXT (hardregs); + pool_free (problem_data->mw_reg_pool, hardregs); } } @@ -1006,22 +919,19 @@ df_insn_info_delete (unsigned int uid) to notes. How clever. So we cannot just check if it is a valid insn before short circuiting this code, we need to see if we actually initialized it. */ - if (insn_info->defs) + df_mw_hardreg_chain_delete (insn_info->mw_hardregs); + + if (df_chain) { - df_mw_hardreg_chain_delete (insn_info->mw_hardregs); + df_ref_chain_delete_du_chain (insn_info->defs); + df_ref_chain_delete_du_chain (insn_info->uses); + df_ref_chain_delete_du_chain (insn_info->eq_uses); + } - if (df_chain) - { - df_ref_chain_delete_du_chain (insn_info->defs); - df_ref_chain_delete_du_chain (insn_info->uses); - df_ref_chain_delete_du_chain (insn_info->eq_uses); - } + df_ref_chain_delete (insn_info->defs); + df_ref_chain_delete (insn_info->uses); + df_ref_chain_delete (insn_info->eq_uses); - df_ref_chain_delete (insn_info->defs); - df_ref_chain_delete (insn_info->uses); - df_ref_chain_delete (insn_info->eq_uses); - df_scan_free_mws_vec (insn_info->mw_hardregs); - } pool_free (problem_data->insn_pool, insn_info); DF_INSN_UID_SET (uid, NULL); } @@ -1149,10 +1059,10 @@ df_insn_rescan (rtx insn) if (!insn_info) { insn_info = df_insn_create_insn_record (insn); - insn_info->defs = df_null_ref_rec; - insn_info->uses = df_null_ref_rec; - insn_info->eq_uses = df_null_ref_rec; - insn_info->mw_hardregs = df_null_mw_rec; + insn_info->defs = 0; + insn_info->uses = 0; + insn_info->eq_uses = 0; + insn_info->mw_hardregs = 0; } if (dump_file) fprintf (dump_file, "deferring rescan insn with uid = %d.\n", uid); @@ -1229,13 +1139,10 @@ df_insn_rescan_debug_internal (rtx insn) bitmap_clear_bit (&df->insns_to_rescan, uid); bitmap_clear_bit (&df->insns_to_notes_rescan, uid); - if (!insn_info->defs) - return false; - - if (insn_info->defs == df_null_ref_rec - && insn_info->uses == df_null_ref_rec - && insn_info->eq_uses == df_null_ref_rec - && insn_info->mw_hardregs == df_null_mw_rec) + if (insn_info->defs == 0 + && insn_info->uses == 0 + && insn_info->eq_uses == 0 + && insn_info->mw_hardregs == 0) return false; df_mw_hardreg_chain_delete (insn_info->mw_hardregs); @@ -1250,12 +1157,11 @@ df_insn_rescan_debug_internal (rtx insn) df_ref_chain_delete (insn_info->defs); df_ref_chain_delete (insn_info->uses); df_ref_chain_delete (insn_info->eq_uses); - df_scan_free_mws_vec (insn_info->mw_hardregs); - insn_info->defs = df_null_ref_rec; - insn_info->uses = df_null_ref_rec; - insn_info->eq_uses = df_null_ref_rec; - insn_info->mw_hardregs = df_null_mw_rec; + insn_info->defs = 0; + insn_info->uses = 0; + insn_info->eq_uses = 0; + insn_info->mw_hardregs = 0; return true; } @@ -1682,19 +1588,15 @@ df_reorganize_refs_by_reg (struct df_ref_info *ref_info, static unsigned int df_add_refs_to_table (unsigned int offset, struct df_ref_info *ref_info, - df_ref *ref_vec) + df_ref ref) { - while (*ref_vec) - { - df_ref ref = *ref_vec; - if ((!(df->changeable_flags & DF_NO_HARD_REGS)) - || (DF_REF_REGNO (ref) >= FIRST_PSEUDO_REGISTER)) - { - ref_info->refs[offset] = ref; - DF_REF_ID (*ref_vec) = offset++; - } - ref_vec++; - } + for (; ref; ref = DF_REF_NEXT_LOC (ref)) + if (!(df->changeable_flags & DF_NO_HARD_REGS) + || (DF_REF_REGNO (ref) >= FIRST_PSEUDO_REGISTER)) + { + ref_info->refs[offset] = ref; + DF_REF_ID (ref) = offset++; + } return offset; } @@ -1921,9 +1823,8 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df, { df_ref next_ref = DF_REF_NEXT_REG (the_ref); df_ref prev_ref = DF_REF_PREV_REG (the_ref); - df_ref *ref_vec, *ref_vec_t; + df_ref *ref_ptr; struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref); - unsigned int count = 0; DF_REF_REGNO (the_ref) = new_regno; DF_REF_REG (the_ref) = regno_reg_rtx[new_regno]; @@ -1950,23 +1851,42 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df, /* Need to sort the record again that the ref was in because the regno is a sorting key. First, find the right record. */ - if (DF_REF_FLAGS (the_ref) & DF_REF_IN_NOTE) - ref_vec = insn_info->eq_uses; + if (DF_REF_REG_DEF_P (the_ref)) + ref_ptr = &insn_info->defs; + else if (DF_REF_FLAGS (the_ref) & DF_REF_IN_NOTE) + ref_ptr = &insn_info->eq_uses; else - ref_vec = insn_info->uses; + ref_ptr = &insn_info->uses; if (dump_file) fprintf (dump_file, "changing reg in insn %d\n", DF_REF_INSN_UID (the_ref)); - ref_vec_t = ref_vec; - - /* Find the length. */ - while (*ref_vec_t) + /* Stop if we find the current reference or where the reference + needs to be. */ + while (*ref_ptr != the_ref && df_ref_compare (*ref_ptr, the_ref) < 0) + ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr); + if (*ref_ptr != the_ref) { - count++; - ref_vec_t++; + /* The reference needs to be promoted up the list. */ + df_ref next = DF_REF_NEXT_LOC (the_ref); + DF_REF_NEXT_LOC (the_ref) = *ref_ptr; + *ref_ptr = the_ref; + do + ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr); + while (*ref_ptr != the_ref); + *ref_ptr = next; + } + else if (DF_REF_NEXT_LOC (the_ref) + && df_ref_compare (the_ref, DF_REF_NEXT_LOC (the_ref)) > 0) + { + /* The reference needs to be demoted down the list. */ + *ref_ptr = DF_REF_NEXT_LOC (the_ref); + do + ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr); + while (*ref_ptr && df_ref_compare (the_ref, *ref_ptr) > 0); + DF_REF_NEXT_LOC (the_ref) = *ref_ptr; + *ref_ptr = the_ref; } - qsort (ref_vec, count, sizeof (df_ref ), df_ref_compare); the_ref = next_ref; } @@ -2000,51 +1920,24 @@ df_ref_change_reg_with_loc (int old_regno, int new_regno, rtx loc) /* Delete the mw_hardregs that point into the eq_notes. */ -static unsigned int +static void df_mw_hardreg_chain_delete_eq_uses (struct df_insn_info *insn_info) { - struct df_mw_hardreg **mw_vec = insn_info->mw_hardregs; - unsigned int deleted = 0; - unsigned int count = 0; + struct df_mw_hardreg **mw_ptr = &insn_info->mw_hardregs; struct df_scan_problem_data *problem_data = (struct df_scan_problem_data *) df_scan->problem_data; - if (!*mw_vec) - return 0; - - while (*mw_vec) + while (*mw_ptr) { - if ((*mw_vec)->flags & DF_REF_IN_NOTE) + df_mw_hardreg *mw = *mw_ptr; + if (mw->flags & DF_REF_IN_NOTE) { - struct df_mw_hardreg **temp_vec = mw_vec; - - pool_free (problem_data->mw_reg_pool, *mw_vec); - temp_vec = mw_vec; - /* Shove the remaining ones down one to fill the gap. While - this looks n**2, it is highly unusual to have any mw regs - in eq_notes and the chances of more than one are almost - non existent. */ - while (*temp_vec) - { - *temp_vec = *(temp_vec + 1); - temp_vec++; - } - deleted++; + *mw_ptr = DF_MWS_NEXT (mw); + pool_free (problem_data->mw_reg_pool, mw); } else - { - mw_vec++; - count++; - } + mw_ptr = &DF_MWS_NEXT (mw); } - - if (count == 0) - { - df_scan_free_mws_vec (insn_info->mw_hardregs); - insn_info->mw_hardregs = df_null_mw_rec; - return 0; - } - return deleted; } @@ -2078,10 +1971,10 @@ df_notes_rescan (rtx insn) if (!insn_info) { insn_info = df_insn_create_insn_record (insn); - insn_info->defs = df_null_ref_rec; - insn_info->uses = df_null_ref_rec; - insn_info->eq_uses = df_null_ref_rec; - insn_info->mw_hardregs = df_null_mw_rec; + insn_info->defs = 0; + insn_info->uses = 0; + insn_info->eq_uses = 0; + insn_info->mw_hardregs = 0; } bitmap_clear_bit (&df->insns_to_delete, uid); @@ -2100,10 +1993,9 @@ df_notes_rescan (rtx insn) basic_block bb = BLOCK_FOR_INSN (insn); rtx note; struct df_collection_rec collection_rec; - unsigned int num_deleted; - unsigned int mw_len; + unsigned int i; - num_deleted = df_mw_hardreg_chain_delete_eq_uses (insn_info); + df_mw_hardreg_chain_delete_eq_uses (insn_info); df_ref_chain_delete (insn_info->eq_uses); insn_info->eq_uses = NULL; @@ -2125,45 +2017,14 @@ df_notes_rescan (rtx insn) /* Find some place to put any new mw_hardregs. */ df_canonize_collection_rec (&collection_rec); - mw_len = collection_rec.mw_vec.length (); - if (mw_len) + struct df_mw_hardreg **mw_ptr = &insn_info->mw_hardregs, *mw; + FOR_EACH_VEC_ELT (collection_rec.mw_vec, i, mw) { - unsigned int count = 0; - struct df_mw_hardreg **mw_rec = insn_info->mw_hardregs; - while (*mw_rec) - { - count++; - mw_rec++; - } - - if (count) - { - /* Append to the end of the existing record after - expanding it if necessary. */ - if (mw_len > num_deleted) - { - insn_info->mw_hardregs = - XRESIZEVEC (struct df_mw_hardreg *, - insn_info->mw_hardregs, - count + 1 + mw_len); - } - memcpy (&insn_info->mw_hardregs[count], - collection_rec.mw_vec.address (), - mw_len * sizeof (struct df_mw_hardreg *)); - insn_info->mw_hardregs[count + mw_len] = NULL; - qsort (insn_info->mw_hardregs, count + mw_len, - sizeof (struct df_mw_hardreg *), df_mw_compare); - } - else - { - /* No vector there. */ - insn_info->mw_hardregs - = XNEWVEC (struct df_mw_hardreg*, 1 + mw_len); - memcpy (insn_info->mw_hardregs, - collection_rec.mw_vec.address (), - mw_len * sizeof (struct df_mw_hardreg *)); - insn_info->mw_hardregs[mw_len] = NULL; - } + while (*mw_ptr && df_mw_compare (*mw_ptr, mw) < 0) + mw_ptr = &DF_MWS_NEXT (*mw_ptr); + DF_MWS_NEXT (mw) = *mw_ptr; + *mw_ptr = mw; + mw_ptr = &DF_MWS_NEXT (mw); } df_refs_add_to_chains (&collection_rec, bb, insn, copy_eq_uses); } @@ -2222,14 +2083,8 @@ df_ref_equal_p (df_ref ref1, df_ref ref2) have the same bb. So these fields are not checked. */ static int -df_ref_compare (const void *r1, const void *r2) +df_ref_compare (df_ref ref1, df_ref ref2) { - const df_ref ref1 = *(const df_ref *)r1; - const df_ref ref2 = *(const df_ref *)r2; - - if (ref1 == ref2) - return 0; - if (DF_REF_CLASS (ref1) != DF_REF_CLASS (ref2)) return (int)DF_REF_CLASS (ref1) - (int)DF_REF_CLASS (ref2); @@ -2264,6 +2119,14 @@ df_ref_compare (const void *r1, const void *r2) return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2); } +/* Like df_ref_compare, but compare two df_ref* pointers R1 and R2. */ + +static int +df_ref_ptr_compare (const void *r1, const void *r2) +{ + return df_ref_compare (*(const df_ref *) r1, *(const df_ref *) r2); +} + static void df_swap_refs (vec *ref_vec, int i, int j) { @@ -2290,7 +2153,7 @@ df_sort_and_compress_refs (vec *ref_vec) { df_ref r0 = (*ref_vec)[0]; df_ref r1 = (*ref_vec)[1]; - if (df_ref_compare (&r0, &r1) > 0) + if (df_ref_compare (r0, r1) > 0) df_swap_refs (ref_vec, 0, 1); } else @@ -2299,7 +2162,7 @@ df_sort_and_compress_refs (vec *ref_vec) { df_ref r0 = (*ref_vec)[i]; df_ref r1 = (*ref_vec)[i + 1]; - if (df_ref_compare (&r0, &r1) >= 0) + if (df_ref_compare (r0, r1) >= 0) break; } /* If the array is already strictly ordered, @@ -2311,7 +2174,7 @@ df_sort_and_compress_refs (vec *ref_vec) of DF_REF_COMPARE. */ if (i == count - 1) return; - ref_vec->qsort (df_ref_compare); + ref_vec->qsort (df_ref_ptr_compare); } for (i=0; itype != mw2->type) return mw1->type - mw2->type; @@ -2380,6 +2237,14 @@ df_mw_compare (const void *m1, const void *m2) return 0; } +/* Like df_mw_compare, but compare two df_mw_hardreg** pointers R1 and R2. */ + +static int +df_mw_ptr_compare (const void *m1, const void *m2) +{ + return df_mw_compare (*(const df_mw_hardreg *const *) m1, + *(const df_mw_hardreg *const *) m2); +} /* Sort and compress a set of refs. */ @@ -2399,7 +2264,7 @@ df_sort_and_compress_mws (vec *mw_vec) { struct df_mw_hardreg *m0 = (*mw_vec)[0]; struct df_mw_hardreg *m1 = (*mw_vec)[1]; - if (df_mw_compare (&m0, &m1) > 0) + if (df_mw_compare (m0, m1) > 0) { struct df_mw_hardreg *tmp = (*mw_vec)[0]; (*mw_vec)[0] = (*mw_vec)[1]; @@ -2407,7 +2272,7 @@ df_sort_and_compress_mws (vec *mw_vec) } } else - mw_vec->qsort (df_mw_compare); + mw_vec->qsort (df_mw_ptr_compare); for (i=0; i *old_vec, struct df_reg_info **reg_info, @@ -2503,7 +2368,6 @@ df_install_refs (basic_block bb, unsigned int count = old_vec->length (); if (count) { - df_ref *new_vec = XNEWVEC (df_ref, count + 1); bool add_to_table; df_ref this_ref; unsigned int ix; @@ -2533,37 +2397,35 @@ df_install_refs (basic_block bb, FOR_EACH_VEC_ELT (*old_vec, ix, this_ref) { - new_vec[ix] = this_ref; + DF_REF_NEXT_LOC (this_ref) = (ix + 1 < old_vec->length () + ? (*old_vec)[ix + 1] + : NULL); df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)], ref_info, add_to_table); } - - new_vec[count] = NULL; - return new_vec; + return (*old_vec)[0]; } else - return df_null_ref_rec; + return 0; } /* This function takes the mws installs the entire group into the insn. */ -static struct df_mw_hardreg ** +static struct df_mw_hardreg * df_install_mws (const vec *old_vec) { unsigned int count = old_vec->length (); if (count) { - struct df_mw_hardreg **new_vec - = XNEWVEC (struct df_mw_hardreg*, count + 1); - memcpy (new_vec, old_vec->address (), - sizeof (struct df_mw_hardreg*) * count); - new_vec[count] = NULL; - return new_vec; + for (unsigned int i = 0; i < count - 1; i++) + DF_MWS_NEXT ((*old_vec)[i]) = (*old_vec)[i + 1]; + DF_MWS_NEXT ((*old_vec)[count - 1]) = 0; + return (*old_vec)[0]; } else - return df_null_mw_rec; + return 0; } @@ -2582,7 +2444,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, chain specially. */ if (flags & copy_defs) { - df_scan_free_ref_vec (insn_rec->defs); + gcc_checking_assert (!insn_rec->defs); insn_rec->defs = df_install_refs (bb, &collection_rec->def_vec, df->def_regs, @@ -2590,7 +2452,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, } if (flags & copy_uses) { - df_scan_free_ref_vec (insn_rec->uses); + gcc_checking_assert (!insn_rec->uses); insn_rec->uses = df_install_refs (bb, &collection_rec->use_vec, df->use_regs, @@ -2598,7 +2460,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, } if (flags & copy_eq_uses) { - df_scan_free_ref_vec (insn_rec->eq_uses); + gcc_checking_assert (!insn_rec->eq_uses); insn_rec->eq_uses = df_install_refs (bb, &collection_rec->eq_use_vec, df->eq_use_regs, @@ -2606,7 +2468,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, } if (flags & copy_mw) { - df_scan_free_mws_vec (insn_rec->mw_hardregs); + gcc_checking_assert (!insn_rec->mw_hardregs); insn_rec->mw_hardregs = df_install_mws (&collection_rec->mw_vec); } @@ -2615,12 +2477,12 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, { struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index); - df_scan_free_ref_vec (bb_info->artificial_defs); + gcc_checking_assert (!bb_info->artificial_defs); bb_info->artificial_defs = df_install_refs (bb, &collection_rec->def_vec, df->def_regs, &df->def_info, false); - df_scan_free_ref_vec (bb_info->artificial_uses); + gcc_checking_assert (!bb_info->artificial_uses); bb_info->artificial_uses = df_install_refs (bb, &collection_rec->use_vec, df->use_regs, @@ -4194,7 +4056,7 @@ df_reg_chain_verify_unmarked (df_ref refs) /* Verify that NEW_REC and OLD_REC have exactly the same members. */ static bool -df_refs_verify (const vec *new_rec, df_ref *old_rec, +df_refs_verify (const vec *new_rec, df_ref old_rec, bool abort_if_fail) { unsigned int ix; @@ -4202,7 +4064,7 @@ df_refs_verify (const vec *new_rec, df_ref *old_rec, 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)) { if (abort_if_fail) gcc_assert (0); @@ -4214,17 +4076,17 @@ df_refs_verify (const vec *new_rec, df_ref *old_rec, that is the context, mark this reg as being seem. */ if (abort_if_fail) { - gcc_assert (DF_REF_IS_REG_MARKED (*old_rec)); - DF_REF_REG_UNMARK (*old_rec); + gcc_assert (DF_REF_IS_REG_MARKED (old_rec)); + DF_REF_REG_UNMARK (old_rec); } - old_rec++; + old_rec = DF_REF_NEXT_LOC (old_rec); } if (abort_if_fail) - gcc_assert (*old_rec == NULL); + gcc_assert (old_rec == NULL); else - return *old_rec == NULL; + return old_rec == NULL; return false; } @@ -4233,7 +4095,7 @@ df_refs_verify (const vec *new_rec, df_ref *old_rec, static bool df_mws_verify (const vec *new_rec, - struct df_mw_hardreg **old_rec, + struct df_mw_hardreg *old_rec, bool abort_if_fail) { unsigned int ix; @@ -4241,20 +4103,20 @@ df_mws_verify (const vec *new_rec, 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)) { if (abort_if_fail) gcc_assert (0); else return false; } - old_rec++; + old_rec = DF_MWS_NEXT (old_rec); } if (abort_if_fail) - gcc_assert (*old_rec == NULL); + gcc_assert (old_rec == NULL); else - return *old_rec == NULL; + return old_rec == NULL; return false; } @@ -4282,15 +4144,6 @@ df_insn_refs_verify (struct df_collection_rec *collection_rec, df_insn_refs_collect (collection_rec, bb, insn_info); - if (!DF_INSN_UID_DEFS (uid)) - { - /* The insn_rec was created but it was never filled out. */ - if (abort_if_fail) - gcc_assert (0); - else - return false; - } - /* Unfortunately we cannot opt out early if one of these is not right because the marks will not get cleared. */ ret1 = df_refs_verify (&collection_rec->def_vec, DF_INSN_UID_DEFS (uid), diff --git a/gcc/df.h b/gcc/df.h index 0582bf0..1533949 100644 --- a/gcc/df.h +++ b/gcc/df.h @@ -339,6 +339,7 @@ struct dataflow REG_UNUSED notes. */ struct df_mw_hardreg { + df_mw_hardreg *next; /* Next entry for this instruction. */ rtx mw_reg; /* The multiword hardreg. */ /* These two bitfields are intentionally oversized, in the hope that accesses to 16-bit fields will usually be quicker. */ @@ -365,6 +366,7 @@ struct df_base_ref int flags : 16; /* Various df_ref_flags. */ unsigned int regno; /* The register number referenced. */ rtx reg; /* The register referenced. */ + union df_ref_d *next_loc; /* Next ref for same insn or bb. */ struct df_link *chain; /* Head of def-use, use-def. */ /* Pointer to the insn info of the containing instruction. FIXME! Currently this is NULL for artificial refs but this will be used @@ -420,11 +422,11 @@ typedef union df_ref_d *df_ref; struct df_insn_info { rtx insn; /* The insn this info comes from. */ - df_ref *defs; /* Head of insn-def chain. */ - df_ref *uses; /* Head of insn-use chain. */ + df_ref defs; /* Head of insn-def chain. */ + df_ref uses; /* Head of insn-use chain. */ /* Head of insn-use chain for uses in REG_EQUAL/EQUIV notes. */ - df_ref *eq_uses; - struct df_mw_hardreg **mw_hardregs; + df_ref eq_uses; + struct df_mw_hardreg *mw_hardregs; /* The logical uid of the insn in the basic block. This is valid after any call to df_analyze but may rot after insns are added, deleted or moved. */ @@ -665,6 +667,7 @@ struct df_d #define DF_REF_REG_MARK(REF) (DF_REF_FLAGS_SET ((REF),DF_REF_REG_MARKER)) #define DF_REF_REG_UNMARK(REF) (DF_REF_FLAGS_CLEAR ((REF),DF_REF_REG_MARKER)) #define DF_REF_IS_REG_MARKED(REF) (DF_REF_FLAGS_IS_SET ((REF),DF_REF_REG_MARKER)) +#define DF_REF_NEXT_LOC(REF) ((REF)->base.next_loc) #define DF_REF_NEXT_REG(REF) ((REF)->base.next_reg) #define DF_REF_PREV_REG(REF) ((REF)->base.prev_reg) /* The following two macros may only be applied if one of @@ -683,6 +686,7 @@ struct df_d #define DF_MWS_REG_DEF_P(MREF) (DF_MWS_TYPE (MREF) == DF_REF_REG_DEF) #define DF_MWS_REG_USE_P(MREF) ((MREF) && !DF_MWS_REG_DEF_P (MREF)) +#define DF_MWS_NEXT(MREF) ((MREF)->next) #define DF_MWS_TYPE(MREF) ((MREF)->type) /* Macros to get the refs out of def_info or use_info refs table. If @@ -755,20 +759,16 @@ struct df_d #define DF_INSN_UID_MWS(INSN) (DF_INSN_UID_GET (INSN)->mw_hardregs) #define FOR_EACH_INSN_INFO_DEF(ITER, INSN) \ - for (df_ref *ITER##_ = DF_INSN_INFO_DEFS (INSN); (ITER = *ITER##_); \ - ++ITER##_) + for (ITER = DF_INSN_INFO_DEFS (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) #define FOR_EACH_INSN_INFO_USE(ITER, INSN) \ - for (df_ref *ITER##_ = DF_INSN_INFO_USES (INSN); (ITER = *ITER##_); \ - ++ITER##_) + for (ITER = DF_INSN_INFO_USES (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) #define FOR_EACH_INSN_INFO_EQ_USE(ITER, INSN) \ - for (df_ref *ITER##_ = DF_INSN_INFO_EQ_USES (INSN); (ITER = *ITER##_); \ - ++ITER##_) + for (ITER = DF_INSN_INFO_EQ_USES (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) #define FOR_EACH_INSN_INFO_MW(ITER, INSN) \ - for (df_mw_hardreg **ITER##_ = DF_INSN_INFO_MWS (INSN); (ITER = *ITER##_); \ - ++ITER##_) + for (ITER = DF_INSN_INFO_MWS (INSN); ITER; ITER = DF_MWS_NEXT (ITER)) #define FOR_EACH_INSN_DEF(ITER, INSN) \ FOR_EACH_INSN_INFO_DEF(ITER, DF_INSN_INFO_GET (INSN)) @@ -780,12 +780,12 @@ struct df_d FOR_EACH_INSN_INFO_EQ_USE(ITER, DF_INSN_INFO_GET (INSN)) #define FOR_EACH_ARTIFICIAL_USE(ITER, BB_INDEX) \ - for (df_ref *ITER##_ = df_get_artificial_uses (BB_INDEX); \ - (ITER = *ITER##_); ++ITER##_) + for (ITER = df_get_artificial_uses (BB_INDEX); ITER; \ + ITER = DF_REF_NEXT_LOC (ITER)) #define FOR_EACH_ARTIFICIAL_DEF(ITER, BB_INDEX) \ - for (df_ref *ITER##_ = df_get_artificial_defs (BB_INDEX); \ - (ITER = *ITER##_); ++ITER##_) + for (ITER = df_get_artificial_defs (BB_INDEX); ITER; \ + ITER = DF_REF_NEXT_LOC (ITER)) /* An obstack for bitmap not related to specific dataflow problems. This obstack should e.g. be used for bitmaps with a short life time @@ -806,13 +806,13 @@ struct df_scan_bb_info Blocks that are the targets of non-local goto's have the hard frame pointer defined at the top of the block. */ - df_ref *artificial_defs; + df_ref artificial_defs; /* Blocks that are targets of exception edges may have some artificial uses. These are logically at the top of the block. Most blocks have artificial uses at the bottom of the block. */ - df_ref *artificial_uses; + df_ref artificial_uses; }; @@ -967,7 +967,7 @@ extern void df_dump_top (basic_block, FILE *); extern void df_dump_bottom (basic_block, FILE *); extern void df_dump_insn_top (const_rtx, FILE *); extern void df_dump_insn_bottom (const_rtx, FILE *); -extern void df_refs_chain_dump (df_ref *, bool, FILE *); +extern void df_refs_chain_dump (df_ref, bool, FILE *); extern void df_regs_chain_dump (df_ref, FILE *); extern void df_insn_debug (rtx, bool, FILE *); extern void df_insn_debug_regno (rtx, FILE *); @@ -1147,7 +1147,7 @@ df_get_live_in (basic_block bb) /* Get basic block info. */ /* Get the artificial defs for a basic block. */ -static inline df_ref * +static inline df_ref df_get_artificial_defs (unsigned int bb_index) { return df_scan_get_bb_info (bb_index)->artificial_defs; @@ -1156,7 +1156,7 @@ df_get_artificial_defs (unsigned int bb_index) /* Get the artificial uses for a basic block. */ -static inline df_ref * +static inline df_ref df_get_artificial_uses (unsigned int bb_index) { return df_scan_get_bb_info (bb_index)->artificial_uses; @@ -1168,8 +1168,8 @@ df_get_artificial_uses (unsigned int bb_index) static inline df_ref df_single_def (const df_insn_info *info) { - df_ref *defs = DF_INSN_INFO_DEFS (info); - return defs[0] && !defs[1] ? defs[0] : NULL; + df_ref defs = DF_INSN_INFO_DEFS (info); + return defs && !DF_REF_NEXT_LOC (defs) ? defs : NULL; } /* If INSN uses exactly one register, return the associated reference, @@ -1178,8 +1178,8 @@ df_single_def (const df_insn_info *info) static inline df_ref df_single_use (const df_insn_info *info) { - df_ref *uses = DF_INSN_INFO_USES (info); - return uses[0] && !uses[1] ? uses[0] : NULL; + df_ref uses = DF_INSN_INFO_USES (info); + return uses && !DF_REF_NEXT_LOC (uses) ? uses : NULL; } /* web */ diff --git a/gcc/fwprop.c b/gcc/fwprop.c index eb21d02..a0b9c8b 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -146,10 +146,9 @@ get_def_for_use (df_ref use) (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER) static void -process_defs (df_ref *def_rec, int top_flag) +process_defs (df_ref def, int top_flag) { - df_ref def; - while ((def = *def_rec++) != NULL) + for (; def; def = DF_REF_NEXT_LOC (def)) { df_ref curr_def = reg_defs[DF_REF_REGNO (def)]; unsigned int dregno; @@ -191,10 +190,9 @@ process_defs (df_ref *def_rec, int top_flag) is an artificial use vector. */ static void -process_uses (df_ref *use_rec, int top_flag) +process_uses (df_ref use, int top_flag) { - df_ref use; - while ((use = *use_rec++) != NULL) + for (; use; use = DF_REF_NEXT_LOC (use)) if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == top_flag) { unsigned int uregno = DF_REF_REGNO (use); @@ -849,11 +847,10 @@ static sparseset active_defs_check; too, for checking purposes. */ static void -register_active_defs (df_ref *use_rec) +register_active_defs (df_ref use) { - while (*use_rec) + for (; use; use = DF_REF_NEXT_LOC (use)) { - df_ref use = *use_rec++; df_ref def = get_def_for_use (use); int regno = DF_REF_REGNO (use); @@ -887,11 +884,10 @@ update_df_init (rtx def_insn, rtx insn) in the ACTIVE_DEFS array to match pseudos to their def. */ static inline void -update_uses (df_ref *use_rec) +update_uses (df_ref use) { - while (*use_rec) + for (; use; use = DF_REF_NEXT_LOC (use)) { - df_ref use = *use_rec++; int regno = DF_REF_REGNO (use); /* Set up the use-def chain. */ @@ -1135,7 +1131,7 @@ forward_propagate_asm (df_ref use, rtx def_insn, rtx def_set, rtx reg) { rtx use_insn = DF_REF_INSN (use), src, use_pat, asm_operands, new_rtx, *loc; int speed_p, i; - df_ref *use_vec; + df_ref uses; gcc_assert ((DF_REF_FLAGS (use) & DF_REF_IN_NOTE) == 0); @@ -1144,8 +1140,8 @@ forward_propagate_asm (df_ref use, rtx def_insn, rtx def_set, rtx reg) /* In __asm don't replace if src might need more registers than reg, as that could increase register pressure on the __asm. */ - use_vec = DF_INSN_USES (def_insn); - if (use_vec[0] && use_vec[1]) + uses = DF_INSN_USES (def_insn); + if (uses && DF_REF_NEXT_LOC (uses)) return false; update_df_init (def_insn, use_insn); diff --git a/gcc/web.c b/gcc/web.c index 029919f..0e9f5da 100644 --- a/gcc/web.c +++ b/gcc/web.c @@ -93,8 +93,8 @@ union_match_dups (rtx insn, struct web_entry *def_entry, bool (*fun) (struct web_entry *, struct web_entry *)) { struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref *use_link = DF_INSN_INFO_USES (insn_info); - df_ref *def_link = DF_INSN_INFO_DEFS (insn_info); + df_ref use_link = DF_INSN_INFO_USES (insn_info); + df_ref def_link = DF_INSN_INFO_DEFS (insn_info); struct web_entry *dup_entry; int i; @@ -104,18 +104,19 @@ union_match_dups (rtx insn, struct web_entry *def_entry, { int op = recog_data.dup_num[i]; enum op_type type = recog_data.operand_type[op]; - df_ref *ref, *dupref; + df_ref ref, dupref; struct web_entry *entry; - for (dup_entry = use_entry, dupref = use_link; *dupref; dupref++) - if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i]) + dup_entry = use_entry; + for (dupref = use_link; dupref; dupref = DF_REF_NEXT_LOC (dupref)) + if (DF_REF_LOC (dupref) == recog_data.dup_loc[i]) break; - if (*dupref == NULL && type == OP_INOUT) + if (dupref == NULL && type == OP_INOUT) { - - for (dup_entry = def_entry, dupref = def_link; *dupref; dupref++) - if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i]) + dup_entry = def_entry; + for (dupref = def_link; dupref; dupref = DF_REF_NEXT_LOC (dupref)) + if (DF_REF_LOC (dupref) == recog_data.dup_loc[i]) break; } /* ??? *DUPREF can still be zero, because when an operand matches @@ -125,35 +126,36 @@ union_match_dups (rtx insn, struct web_entry *def_entry, even though it is there. Example: i686-pc-linux-gnu gcc.c-torture/compile/950607-1.c -O3 -fomit-frame-pointer -funroll-loops */ - if (*dupref == NULL - || DF_REF_REGNO (*dupref) < FIRST_PSEUDO_REGISTER) + if (dupref == NULL + || DF_REF_REGNO (dupref) < FIRST_PSEUDO_REGISTER) continue; ref = type == OP_IN ? use_link : def_link; entry = type == OP_IN ? use_entry : def_entry; - for (; *ref; ref++) + for (; ref; ref = DF_REF_NEXT_LOC (ref)) { - rtx *l = DF_REF_LOC (*ref); + rtx *l = DF_REF_LOC (ref); if (l == recog_data.operand_loc[op]) break; - if (l && DF_REF_REAL_LOC (*ref) == recog_data.operand_loc[op]) + if (l && DF_REF_REAL_LOC (ref) == recog_data.operand_loc[op]) break; } - if (!*ref && type == OP_INOUT) + if (!ref && type == OP_INOUT) { - for (ref = use_link, entry = use_entry; *ref; ref++) + entry = use_entry; + for (ref = use_link; ref; ref = DF_REF_NEXT_LOC (ref)) { - rtx *l = DF_REF_LOC (*ref); + rtx *l = DF_REF_LOC (ref); if (l == recog_data.operand_loc[op]) break; - if (l && DF_REF_REAL_LOC (*ref) == recog_data.operand_loc[op]) + if (l && DF_REF_REAL_LOC (ref) == recog_data.operand_loc[op]) break; } } - gcc_assert (*ref); - (*fun) (dup_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref)); + gcc_assert (ref); + (*fun) (dup_entry + DF_REF_ID (dupref), entry + DF_REF_ID (ref)); } } -- 2.7.4