From patchwork Sun Nov 6 23:34:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dimitrios Apostolou X-Patchwork-Id: 123983 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 0A5561007D3 for ; Mon, 7 Nov 2011 10:35:08 +1100 (EST) Received: (qmail 588 invoked by alias); 6 Nov 2011 23:35:05 -0000 Received: (qmail 28513 invoked by uid 22791); 6 Nov 2011 23:34:50 -0000 X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mailout-de.gmx.net (HELO mailout-de.gmx.net) (213.165.64.22) by sourceware.org (qpsmtpd/0.43rc1) with SMTP; Sun, 06 Nov 2011 23:34:20 +0000 Received: (qmail invoked by alias); 06 Nov 2011 23:34:17 -0000 Received: from teras.ics.forth.gr (EHLO [139.91.70.93]) [139.91.70.93] by mail.gmx.net (mp062) with SMTP; 07 Nov 2011 00:34:17 +0100 Date: Mon, 7 Nov 2011 01:34:15 +0200 (EET) From: Dimitrios Apostolou To: Paolo Bonzini , Jakub Jelinek cc: GCC Patches Subject: Re: repost: [DF] Use HARD_REG_SETs instead of bitmaps In-Reply-To: <20111106125508.GB27375@tyan-ft48-01.lab.bos.redhat.com> Message-ID: References: <4E528F62.5030901@redhat.com> <4EB679A5.4060309@gnu.org> <20111106125508.GB27375@tyan-ft48-01.lab.bos.redhat.com> User-Agent: Alpine 2.02 (LNX 1266 2009-07-14) MIME-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi Paolo, Jakub, thanks for the feedback on my patch. I'm attaching two versions of it: hardreg-struct-v4c: HARD_REG_SET is always a struct, and only references to it are passed in all relevant function calls. hardreg-struct-v5b: keep original HARD_REG_SET, for target.live_on_entry() pass a pointer to a wrapper struct including a pointer to the original HARD_REG_SET. I measured both versions on x86_64 (one long per HARD_REG_SET) and sparc-linux-gnu (multiple longs per HARD_REG_SET). In both archs there is no performance penalty that can be measured reliably, timings are too close to tell, so I consider the performance issue of my original patch to be fixed. FWIW here is the instruction count from callgrind on x86_64 for "gcc -O3 -g vla4.f90" from the testsuite: trunk: 49716078 v4c: 49731151 v5b: 49725263 Now which one is actually better? My personal opinion is that v4c is cleaner (I love deleting code...) but v5b is easier to be merged since it touches less code. What do you think? Thanks, Dimitris === modified file 'gcc/config/i386/i386.c' --- gcc/config/i386/i386.c 2011-10-21 19:32:20 +0000 +++ gcc/config/i386/i386.c 2011-11-06 22:05:13 +0000 @@ -11206,12 +11206,12 @@ ix86_expand_split_stack_prologue (void) is initializing a scratch register. */ static void -ix86_live_on_entry (bitmap regs) +ix86_live_on_entry (struct hard_reg_set_container *regs) { if (cfun->machine->split_stack_varargs_pointer != NULL_RTX) { gcc_assert (flag_split_stack); - bitmap_set_bit (regs, split_stack_prologue_scratch_regno ()); + SET_HARD_REG_BIT (*regs->set, split_stack_prologue_scratch_regno ()); } } === modified file 'gcc/config/mips/mips.c' --- gcc/config/mips/mips.c 2011-10-02 17:46:11 +0000 +++ gcc/config/mips/mips.c 2011-11-06 22:07:38 +0000 @@ -9419,22 +9419,22 @@ mips_initial_elimination_offset (int fro /* Implement TARGET_EXTRA_LIVE_ON_ENTRY. */ static void -mips_extra_live_on_entry (bitmap regs) +mips_extra_live_on_entry (struct hard_reg_set_container *regs) { if (TARGET_USE_GOT) { /* PIC_FUNCTION_ADDR_REGNUM is live if we need it to set up the global pointer. */ if (!TARGET_ABSOLUTE_ABICALLS) - bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM); + SET_HARD_REG_BIT (*regs->set, PIC_FUNCTION_ADDR_REGNUM); /* The prologue may set MIPS16_PIC_TEMP_REGNUM to the value of the global pointer. */ if (TARGET_MIPS16) - bitmap_set_bit (regs, MIPS16_PIC_TEMP_REGNUM); + SET_HARD_REG_BIT (*regs->set, MIPS16_PIC_TEMP_REGNUM); /* See the comment above load_call for details. */ - bitmap_set_bit (regs, GOT_VERSION_REGNUM); + SET_HARD_REG_BIT (*regs->set, GOT_VERSION_REGNUM); } } === modified file 'gcc/config/pa/pa.c' --- gcc/config/pa/pa.c 2011-10-12 13:08:11 +0000 +++ gcc/config/pa/pa.c 2011-11-06 22:08:06 +0000 @@ -171,7 +171,7 @@ static struct machine_function * pa_init static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t, enum machine_mode, secondary_reload_info *); -static void pa_extra_live_on_entry (bitmap); +static void pa_extra_live_on_entry (struct hard_reg_set_container); static enum machine_mode pa_promote_function_mode (const_tree, enum machine_mode, int *, const_tree, int); @@ -5936,10 +5936,10 @@ pa_secondary_reload (bool in_p, rtx x, r so we need to mark it here. */ static void -pa_extra_live_on_entry (bitmap regs) +pa_extra_live_on_entry (struct hard_reg_set_container *regs) { if (TARGET_64BIT) - bitmap_set_bit (regs, ARG_POINTER_REGNUM); + SET_HARD_REG_BIT (*regs->set, ARG_POINTER_REGNUM); } /* Implement EH_RETURN_HANDLER_RTX. The MEM needs to be volatile === modified file 'gcc/dce.c' --- gcc/dce.c 2011-07-19 17:43:15 +0000 +++ gcc/dce.c 2011-11-05 23:54:04 +0000 @@ -867,7 +867,7 @@ word_dce_process_block (basic_block bb, artificial uses. */ static bool -dce_process_block (basic_block bb, bool redo_out, bitmap au) +dce_process_block (basic_block bb, bool redo_out, HARD_REG_SET au) { bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack); rtx insn; @@ -906,7 +906,8 @@ dce_process_block (basic_block bb, bool if (!needed) for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec)) - || bitmap_bit_p (au, DF_REF_REGNO (*def_rec))) + || ( DF_REF_REGNO (*def_rec) < FIRST_PSEUDO_REGISTER + && TEST_HARD_REG_BIT (au, DF_REF_REGNO (*def_rec)))) { needed = true; mark_insn (insn, true); @@ -952,13 +953,16 @@ fast_dce (bool word_level) bool global_changed = true; /* These regs are considered always live so if they end up dying - because of some def, we need to bring the back again. Calling + because of some def, we need to bring them back again. Calling df_simulate_fixup_sets has the disadvantage of calling bb_has_eh_pred once per insn, so we cache the information here. */ - bitmap au = &df->regular_block_artificial_uses; - bitmap au_eh = &df->eh_block_artificial_uses; + HARD_REG_SET au; + HARD_REG_SET au_eh; int i; + + COPY_HARD_REG_SET (au, df->regular_block_artificial_uses); + COPY_HARD_REG_SET (au_eh, df->eh_block_artificial_uses); prescan_insns_for_dce (true); === modified file 'gcc/df-core.c' --- gcc/df-core.c 2011-04-20 18:19:03 +0000 +++ gcc/df-core.c 2011-11-05 23:54:04 +0000 @@ -1885,6 +1885,17 @@ df_print_regset (FILE *file, bitmap r) fprintf (file, "\n"); } +void +df_print_hard_reg_set (FILE *f, HARD_REG_SET r) +{ + unsigned int i; + hard_reg_set_iterator iter; + + EXECUTE_IF_SET_IN_HARD_REG_SET (r, 0, i, iter) + fprintf (f, " %d [%s]", i, reg_names[i]); + fprintf (f, "\n"); +} + /* Write information about registers and basic blocks into FILE. The bitmap is in the form used by df_byte_lr. This is part of making a === modified file 'gcc/df-problems.c' --- gcc/df-problems.c 2011-08-26 14:21:19 +0000 +++ gcc/df-problems.c 2011-11-05 23:54:04 +0000 @@ -432,6 +432,7 @@ df_rd_local_compute (bitmap all_blocks) { unsigned int bb_index; bitmap_iterator bi; + hard_reg_set_iterator iter; unsigned int regno; struct df_rd_problem_data *problem_data = (struct df_rd_problem_data *) df_rd->problem_data; @@ -449,7 +450,7 @@ df_rd_local_compute (bitmap all_blocks) } /* Set up the knockout bit vectors to be applied across EH_EDGES. */ - EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, regno, bi) + EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, iter) { if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD) bitmap_set_bit (sparse_invalidated, regno); @@ -887,6 +888,31 @@ df_lr_bb_local_compute (unsigned int bb_ df_recompute_luids (bb); } +/* TODO optimise per-word */ +static void +bitmap_copy_from_hard_reg_set(bitmap to, HARD_REG_SET from) +{ + unsigned int i; + hard_reg_set_iterator iter; + + bitmap_clear (to); + EXECUTE_IF_SET_IN_HARD_REG_SET (from, 0, i, iter) + bitmap_set_bit (to, i); +} + +/* TODO optimise per-word */ +static bool +bitmap_ior_from_hard_reg_set(bitmap to, HARD_REG_SET from) +{ + bool ret= false; + hard_reg_set_iterator iter; + unsigned int i; + + EXECUTE_IF_SET_IN_HARD_REG_SET (from, 0, i, iter) + ret |= bitmap_set_bit (to, i); + + return ret; +} /* Compute local live register info for each basic block within BLOCKS. */ @@ -896,10 +922,10 @@ df_lr_local_compute (bitmap all_blocks A unsigned int bb_index; bitmap_iterator bi; - bitmap_clear (&df->hardware_regs_used); + CLEAR_HARD_REG_SET (df->hardware_regs_used); /* The all-important stack pointer must always be live. */ - bitmap_set_bit (&df->hardware_regs_used, STACK_POINTER_REGNUM); + SET_HARD_REG_BIT (df->hardware_regs_used, STACK_POINTER_REGNUM); /* Before reload, there are a few registers that must be forced live everywhere -- which might not already be the case for @@ -909,20 +935,20 @@ df_lr_local_compute (bitmap all_blocks A unsigned int pic_offset_table_regnum = PIC_OFFSET_TABLE_REGNUM; /* Any reference to any pseudo before reload is a potential reference of the frame pointer. */ - bitmap_set_bit (&df->hardware_regs_used, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (df->hardware_regs_used, FRAME_POINTER_REGNUM); #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM /* Pseudos with argument area equivalences may require reloading via the argument pointer. */ if (fixed_regs[ARG_POINTER_REGNUM]) - bitmap_set_bit (&df->hardware_regs_used, ARG_POINTER_REGNUM); + SET_HARD_REG_BIT (df->hardware_regs_used, ARG_POINTER_REGNUM); #endif /* Any constant, or pseudo with constant equivalences, may require reloading from memory using the pic register. */ if (pic_offset_table_regnum != INVALID_REGNUM && fixed_regs[pic_offset_table_regnum]) - bitmap_set_bit (&df->hardware_regs_used, pic_offset_table_regnum); + SET_HARD_REG_BIT (df->hardware_regs_used, pic_offset_table_regnum); } EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi) @@ -932,7 +958,7 @@ df_lr_local_compute (bitmap all_blocks A /* The exit block is special for this problem and its bits are computed from thin air. */ struct df_lr_bb_info *bb_info = df_lr_get_bb_info (EXIT_BLOCK); - bitmap_copy (&bb_info->use, df->exit_block_uses); + bitmap_copy_from_hard_reg_set (&bb_info->use, df->exit_block_uses); } else df_lr_bb_local_compute (bb_index); @@ -967,9 +993,32 @@ df_lr_confluence_0 (basic_block bb) { bitmap op1 = &df_lr_get_bb_info (bb->index)->out; if (bb != EXIT_BLOCK_PTR) - bitmap_copy (op1, &df->hardware_regs_used); + bitmap_copy_from_hard_reg_set (op1, df->hardware_regs_used); } +/* to |= from1 & ~from2 + from2 is of type HARD_REG_SET */ + +static bool +bitmap_ior_and_compl_from_hard_reg_set (bitmap to, const_bitmap from1, + HARD_REG_SET from2) +{ + bool ret; + unsigned int i; + bitmap_head from1_tmp; + hard_reg_set_iterator iter; + + bitmap_initialize (&from1_tmp, &bitmap_default_obstack); + bitmap_copy (&from1_tmp, from1); + + /* TODO optimise per-word */ + EXECUTE_IF_SET_IN_HARD_REG_SET (from2, 0, i, iter) + bitmap_clear_bit (&from1_tmp, i); + ret = bitmap_ior_into (to, &from1_tmp); + + bitmap_clear (&from1_tmp); + return ret; +} /* Confluence function that ignores fake edges. */ @@ -984,11 +1033,12 @@ df_lr_confluence_n (edge e) /* ??? Abnormal call edges ignored for the moment, as this gets confused by sibling call edges, which crashes reg-stack. */ if (e->flags & EDGE_EH) - changed = bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset); + changed = bitmap_ior_and_compl_from_hard_reg_set (op1, op2, + regs_invalidated_by_call); else changed = bitmap_ior_into (op1, op2); - changed |= bitmap_ior_into (op1, &df->hardware_regs_used); + changed |= bitmap_ior_from_hard_reg_set (op1, df->hardware_regs_used); return changed; } @@ -2507,19 +2557,10 @@ df_word_lr_local_compute (bitmap all_blo unsigned int bb_index; bitmap_iterator bi; - EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi) - { - if (bb_index == EXIT_BLOCK) - { - unsigned regno; - bitmap_iterator bi; - EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER, - regno, bi) - gcc_unreachable (); - } - else - df_word_lr_bb_local_compute (bb_index); - } + EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, + 0, bb_index, bi) + if (bb_index != EXIT_BLOCK) + df_word_lr_bb_local_compute (bb_index); bitmap_clear (df_word_lr->out_of_date_transfer_functions); } @@ -3650,9 +3691,9 @@ df_simulate_fixup_sets (basic_block bb, /* These regs are considered always live so if they end up dying because of some def, we need to bring the back again. */ if (bb_has_eh_pred (bb)) - bitmap_ior_into (live, &df->eh_block_artificial_uses); + bitmap_ior_from_hard_reg_set (live, df->eh_block_artificial_uses); else - bitmap_ior_into (live, &df->regular_block_artificial_uses); + bitmap_ior_from_hard_reg_set (live, df->regular_block_artificial_uses); } @@ -4471,8 +4512,8 @@ df_md_confluence_n (edge e) return false; if (e->flags & EDGE_EH) - return bitmap_ior_and_compl_into (op1, op2, - regs_invalidated_by_call_regset); + return bitmap_ior_and_compl_from_hard_reg_set (op1, op2, + regs_invalidated_by_call); else return bitmap_ior_into (op1, op2); } === modified file 'gcc/df-scan.c' --- gcc/df-scan.c 2011-08-27 17:38:58 +0000 +++ gcc/df-scan.c 2011-11-06 22:05:52 +0000 @@ -131,13 +131,13 @@ static void df_insn_refs_collect (struct basic_block, struct df_insn_info *); static void df_canonize_collection_rec (struct df_collection_rec *); -static void df_get_regular_block_artificial_uses (bitmap); -static void df_get_eh_block_artificial_uses (bitmap); +static void df_get_regular_block_artificial_uses (HARD_REG_SET *); +static void df_get_eh_block_artificial_uses (HARD_REG_SET *); -static void df_record_entry_block_defs (bitmap); -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_record_entry_block_defs (HARD_REG_SET); +static void df_record_exit_block_uses (HARD_REG_SET); +static void df_get_exit_block_use_set (HARD_REG_SET *); +static void df_get_entry_block_def_set (HARD_REG_SET *); 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 *); @@ -146,8 +146,8 @@ static void df_refs_add_to_chains (struc basic_block, rtx); 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_exit_block_uses_collect (struct df_collection_rec *, bitmap); +static void df_entry_block_defs_collect (struct df_collection_rec *, HARD_REG_SET); +static void df_exit_block_uses_collect (struct df_collection_rec *, HARD_REG_SET); static void df_install_ref (df_ref, struct df_reg_info *, struct df_ref_info *, bool); @@ -162,7 +162,7 @@ static int df_mw_compare (const void *, regs. Final uses it to generate the code in the function prologue and epilogue to save and restore registers as needed. */ -static bool regs_ever_live[FIRST_PSEUDO_REGISTER]; +static HARD_REG_SET regs_ever_live; /*---------------------------------------------------------------------------- SCANNING DATAFLOW PROBLEM @@ -253,11 +253,9 @@ df_scan_free_internal (void) df_scan->block_info = NULL; df_scan->block_info_size = 0; - bitmap_clear (&df->hardware_regs_used); - bitmap_clear (&df->regular_block_artificial_uses); - bitmap_clear (&df->eh_block_artificial_uses); - BITMAP_FREE (df->entry_block_defs); - BITMAP_FREE (df->exit_block_uses); + CLEAR_HARD_REG_SET (df->hardware_regs_used); + CLEAR_HARD_REG_SET (df->regular_block_artificial_uses); + CLEAR_HARD_REG_SET (df->eh_block_artificial_uses); bitmap_clear (&df->insns_to_delete); bitmap_clear (&df->insns_to_rescan); bitmap_clear (&df->insns_to_notes_rescan); @@ -366,11 +364,11 @@ df_scan_alloc (bitmap all_blocks ATTRIBU bb_info->artificial_uses = NULL; } - bitmap_initialize (&df->hardware_regs_used, &problem_data->reg_bitmaps); - bitmap_initialize (&df->regular_block_artificial_uses, &problem_data->reg_bitmaps); - bitmap_initialize (&df->eh_block_artificial_uses, &problem_data->reg_bitmaps); - df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps); - df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps); + CLEAR_HARD_REG_SET (df->hardware_regs_used); + CLEAR_HARD_REG_SET (df->regular_block_artificial_uses); + CLEAR_HARD_REG_SET (df->eh_block_artificial_uses); + CLEAR_HARD_REG_SET (df->entry_block_defs); + CLEAR_HARD_REG_SET (df->exit_block_uses); bitmap_initialize (&df->insns_to_delete, &problem_data->insn_bitmaps); bitmap_initialize (&df->insns_to_rescan, &problem_data->insn_bitmaps); bitmap_initialize (&df->insns_to_notes_rescan, &problem_data->insn_bitmaps); @@ -409,21 +407,28 @@ df_scan_start_dump (FILE *file ATTRIBUTE rtx insn; fprintf (file, ";; invalidated by call \t"); - df_print_regset (file, regs_invalidated_by_call_regset); + df_print_hard_reg_set (file, regs_invalidated_by_call); + fprintf (file, ";; hardware regs used \t"); - df_print_regset (file, &df->hardware_regs_used); + df_print_hard_reg_set (file, df->hardware_regs_used); + fprintf (file, ";; regular block artificial uses \t"); - df_print_regset (file, &df->regular_block_artificial_uses); + df_print_hard_reg_set (file, df->regular_block_artificial_uses); + fprintf (file, ";; eh block artificial uses \t"); - df_print_regset (file, &df->eh_block_artificial_uses); + df_print_hard_reg_set (file, df->eh_block_artificial_uses); + fprintf (file, ";; entry block defs \t"); - df_print_regset (file, df->entry_block_defs); + df_print_hard_reg_set (file, df->entry_block_defs); + fprintf (file, ";; exit block uses \t"); - df_print_regset (file, df->exit_block_uses); + df_print_hard_reg_set (file, df->exit_block_uses); + fprintf (file, ";; regs ever live \t"); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (df_regs_ever_live_p (i)) fprintf (file, " %d[%s]", i, reg_names[i]); + fprintf (file, "\n;; ref usage \t"); for (i = 0; i < (int)df->regs_inited; i++) @@ -662,13 +667,13 @@ df_scan_blocks (void) df_get_regular_block_artificial_uses (&df->regular_block_artificial_uses); df_get_eh_block_artificial_uses (&df->eh_block_artificial_uses); - bitmap_ior_into (&df->eh_block_artificial_uses, - &df->regular_block_artificial_uses); + IOR_HARD_REG_SET (df->eh_block_artificial_uses, + df->regular_block_artificial_uses); /* ENTRY and EXIT blocks have special defs/uses. */ - df_get_entry_block_def_set (df->entry_block_defs); + df_get_entry_block_def_set (&df->entry_block_defs); df_record_entry_block_defs (df->entry_block_defs); - df_get_exit_block_use_set (df->exit_block_uses); + df_get_exit_block_use_set (&df->exit_block_uses); df_record_exit_block_uses (df->exit_block_uses); df_set_bb_dirty (BASIC_BLOCK (ENTRY_BLOCK)); df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK)); @@ -3318,20 +3323,20 @@ df_get_call_refs (struct df_collection_r int flags) { rtx note; - bitmap_iterator bi; + hard_reg_set_iterator iter; unsigned int ui; bool is_sibling_call; unsigned int i; df_ref def; - bitmap_head defs_generated; + HARD_REG_SET defs_generated; - bitmap_initialize (&defs_generated, &df_bitmap_obstack); + CLEAR_HARD_REG_SET(defs_generated); /* Do not generate clobbers for registers that are the result of the call. This causes ordering problems in the chain building code depending on which def is seen first. */ FOR_EACH_VEC_ELT (df_ref, collection_rec->def_vec, i, def) - bitmap_set_bit (&defs_generated, DF_REF_REGNO (def)); + SET_HARD_REG_BIT (defs_generated, DF_REF_REGNO (def)); /* Record the registers used to pass arguments, and explicitly noted as clobbered. */ @@ -3346,7 +3351,7 @@ df_get_call_refs (struct df_collection_r if (REG_P (XEXP (XEXP (note, 0), 0))) { unsigned int regno = REGNO (XEXP (XEXP (note, 0), 0)); - if (!bitmap_bit_p (&defs_generated, regno)) + if (!TEST_HARD_REG_BIT (defs_generated, regno)) df_defs_record (collection_rec, XEXP (note, 0), bb, insn_info, flags); } @@ -3376,12 +3381,12 @@ df_get_call_refs (struct df_collection_r } is_sibling_call = SIBLING_CALL_P (insn_info->insn); - EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, ui, bi) + EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, ui, iter) { if (!global_regs[ui] - && (!bitmap_bit_p (&defs_generated, ui)) + && (!TEST_HARD_REG_BIT (defs_generated, ui)) && (!is_sibling_call - || !bitmap_bit_p (df->exit_block_uses, ui) + || !TEST_HARD_REG_BIT (df->exit_block_uses, ui) || refers_to_regno_p (ui, ui+1, crtl->return_rtx, NULL))) df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[ui], @@ -3389,7 +3394,6 @@ df_get_call_refs (struct df_collection_r DF_REF_MAY_CLOBBER | flags); } - bitmap_clear (&defs_generated); return; } @@ -3535,13 +3539,13 @@ df_bb_refs_collect (struct df_collection /* Add the artificial uses. */ if (bb->index >= NUM_FIXED_BLOCKS) { - bitmap_iterator bi; + hard_reg_set_iterator iter; unsigned int regno; - bitmap au = bb_has_eh_pred (bb) - ? &df->eh_block_artificial_uses - : &df->regular_block_artificial_uses; + HARD_REG_SET *au= bb_has_eh_pred (bb) + ? &(df->eh_block_artificial_uses) + : &(df->regular_block_artificial_uses); - EXECUTE_IF_SET_IN_BITMAP (au, 0, regno, bi) + EXECUTE_IF_SET_IN_HARD_REG_SET (*au, 0, regno, iter) { df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL, bb, NULL, DF_REF_REG_USE, 0); @@ -3608,18 +3612,18 @@ df_bb_refs_record (int bb_index, bool sc block. */ static void -df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses) +df_get_regular_block_artificial_uses (HARD_REG_SET *regular_block_artificial_uses) { #ifdef EH_USES unsigned int i; #endif - bitmap_clear (regular_block_artificial_uses); + CLEAR_HARD_REG_SET (*regular_block_artificial_uses); if (reload_completed) { if (frame_pointer_needed) - bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); } else /* Before reload, there are a few registers that must be forced @@ -3630,27 +3634,27 @@ df_get_regular_block_artificial_uses (bi /* Any reference to any pseudo before reload is a potential reference of the frame pointer. */ - bitmap_set_bit (regular_block_artificial_uses, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, FRAME_POINTER_REGNUM); #if !HARD_FRAME_POINTER_IS_FRAME_POINTER - bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); #endif #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM /* Pseudos with argument area equivalences may require reloading via the argument pointer. */ if (fixed_regs[ARG_POINTER_REGNUM]) - bitmap_set_bit (regular_block_artificial_uses, ARG_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, ARG_POINTER_REGNUM); #endif /* Any constant, or pseudo with constant equivalences, may require reloading from memory using the pic register. */ if (picreg != INVALID_REGNUM && fixed_regs[picreg]) - bitmap_set_bit (regular_block_artificial_uses, picreg); + SET_HARD_REG_BIT (*regular_block_artificial_uses, picreg); } /* The all-important stack pointer must always be live. */ - bitmap_set_bit (regular_block_artificial_uses, STACK_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, STACK_POINTER_REGNUM); #ifdef EH_USES /* EH_USES registers are used: @@ -3663,7 +3667,7 @@ df_get_regular_block_artificial_uses (bi (noreturn call or infinite loop). */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (EH_USES (i)) - bitmap_set_bit (regular_block_artificial_uses, i); + SET_HARD_REG_BIT (*regular_block_artificial_uses, i); #endif } @@ -3671,9 +3675,9 @@ df_get_regular_block_artificial_uses (bi /* Get the artificial use set for an eh block. */ static void -df_get_eh_block_artificial_uses (bitmap eh_block_artificial_uses) +df_get_eh_block_artificial_uses (HARD_REG_SET *eh_block_artificial_uses) { - bitmap_clear (eh_block_artificial_uses); + CLEAR_HARD_REG_SET (*eh_block_artificial_uses); /* The following code (down thru the arg_pointer setting APPEARS to be necessary because there is nothing that actually @@ -3683,14 +3687,14 @@ df_get_eh_block_artificial_uses (bitmap { if (frame_pointer_needed) { - bitmap_set_bit (eh_block_artificial_uses, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*eh_block_artificial_uses, FRAME_POINTER_REGNUM); #if !HARD_FRAME_POINTER_IS_FRAME_POINTER - bitmap_set_bit (eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); #endif } #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM if (fixed_regs[ARG_POINTER_REGNUM]) - bitmap_set_bit (eh_block_artificial_uses, ARG_POINTER_REGNUM); + SET_HARD_REG_BIT (*eh_block_artificial_uses, ARG_POINTER_REGNUM); #endif } } @@ -3708,7 +3712,7 @@ df_get_eh_block_artificial_uses (bitmap static void df_mark_reg (rtx reg, void *vset) { - bitmap set = (bitmap) vset; + HARD_REG_SET *set = (HARD_REG_SET *) vset; int regno = REGNO (reg); gcc_assert (GET_MODE (reg) != BLKmode); @@ -3716,29 +3720,35 @@ df_mark_reg (rtx reg, void *vset) if (regno < FIRST_PSEUDO_REGISTER) { int n = hard_regno_nregs[regno][GET_MODE (reg)]; - bitmap_set_range (set, regno, n); + int i; + for (i=regno; ientry_block_defs) - { - if (!bitmap_equal_p (df->entry_block_defs, &refs)) - { - struct df_scan_bb_info *bb_info = df_scan_get_bb_info (ENTRY_BLOCK); - df_ref_chain_delete_du_chain (bb_info->artificial_defs); - df_ref_chain_delete (bb_info->artificial_defs); - bb_info->artificial_defs = NULL; - changed = true; - } - } - else + if (!hard_reg_set_equal_p (df->entry_block_defs, refs)) { - struct df_scan_problem_data *problem_data - = (struct df_scan_problem_data *) df_scan->problem_data; - gcc_unreachable (); - df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps); - changed = true; - } + struct df_scan_bb_info *bb_info = df_scan_get_bb_info (ENTRY_BLOCK); + df_ref_chain_delete_du_chain (bb_info->artificial_defs); + df_ref_chain_delete (bb_info->artificial_defs); + bb_info->artificial_defs = NULL; - if (changed) - { - df_record_entry_block_defs (&refs); - bitmap_copy (df->entry_block_defs, &refs); + df_record_entry_block_defs (refs); + COPY_HARD_REG_SET (df->entry_block_defs, refs); df_set_bb_dirty (BASIC_BLOCK (ENTRY_BLOCK)); } - bitmap_clear (&refs); } /* Set the bit for regs that are considered being used at the exit. */ static void -df_get_exit_block_use_set (bitmap exit_block_uses) +df_get_exit_block_use_set (HARD_REG_SET *exit_block_uses) { unsigned int i; unsigned int picreg = PIC_OFFSET_TABLE_REGNUM; - bitmap_clear (exit_block_uses); + CLEAR_HARD_REG_SET (*exit_block_uses); /* Stack pointer is always live at the exit. */ - bitmap_set_bit (exit_block_uses, STACK_POINTER_REGNUM); + SET_HARD_REG_BIT (*exit_block_uses, STACK_POINTER_REGNUM); /* Mark the frame pointer if needed at the end of the function. If we end up eliminating it, it will be removed from the live @@ -3903,11 +3898,11 @@ df_get_exit_block_use_set (bitmap exit_b if ((!reload_completed) || frame_pointer_needed) { - bitmap_set_bit (exit_block_uses, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*exit_block_uses, FRAME_POINTER_REGNUM); #if !HARD_FRAME_POINTER_IS_FRAME_POINTER /* If they are different, also mark the hard frame pointer as live. */ if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM)) - bitmap_set_bit (exit_block_uses, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*exit_block_uses, HARD_FRAME_POINTER_REGNUM); #endif } @@ -3917,14 +3912,14 @@ df_get_exit_block_use_set (bitmap exit_b if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED && picreg != INVALID_REGNUM && fixed_regs[picreg]) - bitmap_set_bit (exit_block_uses, picreg); + SET_HARD_REG_BIT (*exit_block_uses, picreg); /* Mark all global registers, and all registers used by the epilogue as being live at the end of the function since they may be referenced by our caller. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (global_regs[i] || EPILOGUE_USES (i)) - bitmap_set_bit (exit_block_uses, i); + SET_HARD_REG_BIT (*exit_block_uses, i); if (HAVE_epilogue && epilogue_completed) { @@ -3932,7 +3927,7 @@ df_get_exit_block_use_set (bitmap exit_b for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (df_regs_ever_live_p (i) && !LOCAL_REGNO (i) && !TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) - bitmap_set_bit (exit_block_uses, i); + SET_HARD_REG_BIT (*exit_block_uses, i); } #ifdef EH_RETURN_DATA_REGNO @@ -3943,7 +3938,7 @@ df_get_exit_block_use_set (bitmap exit_b unsigned regno = EH_RETURN_DATA_REGNO (i); if (regno == INVALID_REGNUM) break; - bitmap_set_bit (exit_block_uses, regno); + SET_HARD_REG_BIT (*exit_block_uses, regno); } #endif @@ -3976,12 +3971,12 @@ df_get_exit_block_use_set (bitmap exit_b It uses df->exit_block_uses to determine register to include. */ static void -df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exit_block_uses) +df_exit_block_uses_collect (struct df_collection_rec *collection_rec, HARD_REG_SET exit_block_uses) { unsigned int i; - bitmap_iterator bi; + hard_reg_set_iterator iter; - EXECUTE_IF_SET_IN_BITMAP (exit_block_uses, 0, i, bi) + EXECUTE_IF_SET_IN_HARD_REG_SET (exit_block_uses, 0, i, iter) df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL, EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0); @@ -3989,7 +3984,7 @@ df_exit_block_uses_collect (struct df_co /* It is deliberate that this is not put in the exit block uses but I do not know why. */ if (reload_completed - && !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM) + && !TEST_HARD_REG_BIT (exit_block_uses, ARG_POINTER_REGNUM) && bb_has_eh_pred (EXIT_BLOCK_PTR) && fixed_regs[ARG_POINTER_REGNUM]) df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL, @@ -4004,16 +3999,17 @@ df_exit_block_uses_collect (struct df_co It uses df->exit_block_uses to determine which bit to include. */ static void -df_record_exit_block_uses (bitmap exit_block_uses) +df_record_exit_block_uses (HARD_REG_SET exit_block_uses) { struct df_collection_rec collection_rec; + memset (&collection_rec, 0, sizeof (struct df_collection_rec)); collection_rec.use_vec = VEC_alloc (df_ref, stack, FIRST_PSEUDO_REGISTER); df_exit_block_uses_collect (&collection_rec, exit_block_uses); - /* Process bb_refs chain */ df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (EXIT_BLOCK), NULL); + VEC_free (df_ref, stack, collection_rec.use_vec); } @@ -4023,38 +4019,20 @@ df_record_exit_block_uses (bitmap exit_b void df_update_exit_block_uses (void) { - bitmap_head refs; - bool changed = false; + HARD_REG_SET refs; - bitmap_initialize (&refs, &df_bitmap_obstack); df_get_exit_block_use_set (&refs); - if (df->exit_block_uses) - { - if (!bitmap_equal_p (df->exit_block_uses, &refs)) - { - struct df_scan_bb_info *bb_info = df_scan_get_bb_info (EXIT_BLOCK); - df_ref_chain_delete_du_chain (bb_info->artificial_uses); - df_ref_chain_delete (bb_info->artificial_uses); - bb_info->artificial_uses = NULL; - changed = true; - } - } - else + if (!hard_reg_set_equal_p (df->exit_block_uses, refs)) { - struct df_scan_problem_data *problem_data - = (struct df_scan_problem_data *) df_scan->problem_data; - gcc_unreachable (); - df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps); - changed = true; - } + struct df_scan_bb_info *bb_info = df_scan_get_bb_info (EXIT_BLOCK); + df_ref_chain_delete_du_chain (bb_info->artificial_uses); + df_ref_chain_delete (bb_info->artificial_uses); + bb_info->artificial_uses = NULL; - if (changed) - { - df_record_exit_block_uses (&refs); - bitmap_copy (df->exit_block_uses,& refs); + df_record_exit_block_uses (refs); + COPY_HARD_REG_SET (df->exit_block_uses, refs); df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK)); } - bitmap_clear (&refs); } static bool initialized = false; @@ -4143,7 +4121,7 @@ df_hard_reg_used_count (unsigned int reg bool df_regs_ever_live_p (unsigned int regno) { - return regs_ever_live[regno]; + return TEST_HARD_REG_BIT (regs_ever_live, regno); } @@ -4153,10 +4131,14 @@ df_regs_ever_live_p (unsigned int regno) void df_set_regs_ever_live (unsigned int regno, bool value) { - if (regs_ever_live[regno] == value) + if (df_regs_ever_live_p (regno) == value) return; - regs_ever_live[regno] = value; + if (value) + SET_HARD_REG_BIT (regs_ever_live, regno); + else + CLEAR_HARD_REG_BIT (regs_ever_live, regno); + if (df) df->redo_entry_and_exit = true; } @@ -4172,12 +4154,12 @@ df_compute_regs_ever_live (bool reset) bool changed = df->redo_entry_and_exit; if (reset) - memset (regs_ever_live, 0, sizeof (regs_ever_live)); + CLEAR_HARD_REG_SET (regs_ever_live); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if ((!regs_ever_live[i]) && df_hard_reg_used_p (i)) + if ((!df_regs_ever_live_p (i)) && df_hard_reg_used_p (i)) { - regs_ever_live[i] = true; + df_set_regs_ever_live (i, true); changed = true; } if (changed) @@ -4410,26 +4392,23 @@ df_bb_verify (basic_block bb) static bool df_entry_block_bitmap_verify (bool abort_if_fail) { - bitmap_head entry_block_defs; + HARD_REG_SET entry_block_defs; bool is_eq; - bitmap_initialize (&entry_block_defs, &df_bitmap_obstack); df_get_entry_block_def_set (&entry_block_defs); - is_eq = bitmap_equal_p (&entry_block_defs, df->entry_block_defs); + is_eq = hard_reg_set_equal_p (entry_block_defs, df->entry_block_defs); if (!is_eq && abort_if_fail) { print_current_pass (stderr); fprintf (stderr, "entry_block_defs = "); - df_print_regset (stderr, &entry_block_defs); + df_print_hard_reg_set (stderr, entry_block_defs); fprintf (stderr, "df->entry_block_defs = "); - df_print_regset (stderr, df->entry_block_defs); + df_print_hard_reg_set (stderr, df->entry_block_defs); gcc_assert (0); } - bitmap_clear (&entry_block_defs); - return is_eq; } @@ -4440,26 +4419,23 @@ df_entry_block_bitmap_verify (bool abort static bool df_exit_block_bitmap_verify (bool abort_if_fail) { - bitmap_head exit_block_uses; + HARD_REG_SET exit_block_uses; bool is_eq; - bitmap_initialize (&exit_block_uses, &df_bitmap_obstack); df_get_exit_block_use_set (&exit_block_uses); - is_eq = bitmap_equal_p (&exit_block_uses, df->exit_block_uses); + is_eq = hard_reg_set_equal_p (exit_block_uses, df->exit_block_uses); if (!is_eq && abort_if_fail) { print_current_pass (stderr); fprintf (stderr, "exit_block_uses = "); - df_print_regset (stderr, &exit_block_uses); + df_print_hard_reg_set (stderr, exit_block_uses); fprintf (stderr, "df->exit_block_uses = "); - df_print_regset (stderr, df->exit_block_uses); + df_print_hard_reg_set (stderr, df->exit_block_uses); gcc_assert (0); } - bitmap_clear (&exit_block_uses); - return is_eq; } @@ -4472,8 +4448,8 @@ df_scan_verify (void) { unsigned int i; basic_block bb; - bitmap_head regular_block_artificial_uses; - bitmap_head eh_block_artificial_uses; + HARD_REG_SET regular_block_artificial_uses; + HARD_REG_SET eh_block_artificial_uses; if (!df) return; @@ -4494,23 +4470,18 @@ df_scan_verify (void) /* (2) There are various bitmaps whose value may change over the course of the compilation. This step recomputes them to make sure that they have not slipped out of date. */ - bitmap_initialize (®ular_block_artificial_uses, &df_bitmap_obstack); - bitmap_initialize (&eh_block_artificial_uses, &df_bitmap_obstack); df_get_regular_block_artificial_uses (®ular_block_artificial_uses); df_get_eh_block_artificial_uses (&eh_block_artificial_uses); - bitmap_ior_into (&eh_block_artificial_uses, - ®ular_block_artificial_uses); + IOR_HARD_REG_SET (eh_block_artificial_uses, + regular_block_artificial_uses); /* Check artificial_uses bitmaps didn't change. */ - gcc_assert (bitmap_equal_p (®ular_block_artificial_uses, - &df->regular_block_artificial_uses)); - gcc_assert (bitmap_equal_p (&eh_block_artificial_uses, - &df->eh_block_artificial_uses)); - - bitmap_clear (®ular_block_artificial_uses); - bitmap_clear (&eh_block_artificial_uses); + gcc_assert (hard_reg_set_equal_p (regular_block_artificial_uses, + df->regular_block_artificial_uses)); + gcc_assert (hard_reg_set_equal_p (eh_block_artificial_uses, + df->eh_block_artificial_uses)); /* Verify entry block and exit block. These only verify the bitmaps, the refs are verified in df_bb_verify. */ === modified file 'gcc/df.h' --- gcc/df.h 2010-12-14 00:23:40 +0000 +++ gcc/df.h 2011-11-05 23:54:04 +0000 @@ -69,7 +69,7 @@ enum df_flow_dir /* Descriminator for the various df_ref types. */ enum df_ref_class {DF_REF_BASE, DF_REF_ARTIFICIAL, DF_REF_REGULAR}; -/* The first of these us a set of a registers. The remaining three +/* The first of these uses a set of a registers. The remaining three are all uses of a register (the mem_load and mem_store relate to how the register as an addressing operand). */ enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, @@ -545,16 +545,17 @@ struct df_d int num_problems_defined; - bitmap_head hardware_regs_used; /* The set of hardware registers used. */ + HARD_REG_SET hardware_regs_used; /* The set of hardware registers used. */ /* The set of hard regs that are in the artificial uses at the end of a regular basic block. */ - bitmap_head regular_block_artificial_uses; + HARD_REG_SET regular_block_artificial_uses; /* The set of hard regs that are in the artificial uses at the end of a basic block that has an EH pred. */ - bitmap_head eh_block_artificial_uses; + HARD_REG_SET eh_block_artificial_uses; /* The set of hardware registers live on entry to the function. */ - bitmap entry_block_defs; - bitmap exit_block_uses; /* The set of hardware registers used in exit block. */ + HARD_REG_SET entry_block_defs; + /* The set of hardware registers used in exit block. */ + HARD_REG_SET exit_block_uses; /* Insns to delete, rescan or reprocess the notes at next df_rescan_all or df_process_deferred_rescans. */ @@ -911,6 +912,7 @@ extern bool df_reg_defined (rtx, rtx); extern df_ref df_find_use (rtx, rtx); extern bool df_reg_used (rtx, rtx); extern void df_worklist_dataflow (struct dataflow *,bitmap, int *, int); +extern void df_print_hard_reg_set (FILE *f, HARD_REG_SET r); extern void df_print_regset (FILE *file, bitmap r); extern void df_print_word_regset (FILE *file, bitmap r); extern void df_dump (FILE *); === modified file 'gcc/doc/tm.texi' --- gcc/doc/tm.texi 2011-10-20 20:10:05 +0000 +++ gcc/doc/tm.texi 2011-11-06 22:08:20 +0000 @@ -4946,7 +4946,7 @@ as the @code{sibcall} md pattern can not may vary greatly between different architectures. @end deftypefn -@deftypefn {Target Hook} void TARGET_EXTRA_LIVE_ON_ENTRY (bitmap @var{regs}) +@deftypefn {Target Hook} void TARGET_EXTRA_LIVE_ON_ENTRY (struct hard_reg_set_container *@var{regs}) Add any hard registers to @var{regs} that are live on entry to the function. This hook only needs to be defined to provide registers that cannot be found by examination of FUNCTION_ARG_REGNO_P, the callee saved === modified file 'gcc/hard-reg-set.h' --- gcc/hard-reg-set.h 2011-01-03 20:52:22 +0000 +++ gcc/hard-reg-set.h 2011-11-06 22:07:00 +0000 @@ -54,6 +54,10 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[H #endif +struct hard_reg_set_container { + HARD_REG_SET *set; +}; + /* HARD_CONST is used to cast a constant to the appropriate type for use with a HARD_REG_SET. */ === modified file 'gcc/reginfo.c' --- gcc/reginfo.c 2011-07-19 22:34:31 +0000 +++ gcc/reginfo.c 2011-11-05 23:54:04 +0000 @@ -90,14 +90,6 @@ char global_regs[FIRST_PSEUDO_REGISTER]; /* Declaration for the global register. */ static tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER]; -/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used - in dataflow more conveniently. */ -regset regs_invalidated_by_call_regset; - -/* The bitmap_obstack is used to hold some static variables that - should not be reset after each function is compiled. */ -static bitmap_obstack persistent_obstack; - /* Used to initialize reg_alloc_order. */ #ifdef REG_ALLOC_ORDER static int initial_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER; @@ -444,13 +436,6 @@ init_reg_sets_1 (void) CLEAR_HARD_REG_SET (call_used_reg_set); CLEAR_HARD_REG_SET (call_fixed_reg_set); CLEAR_HARD_REG_SET (regs_invalidated_by_call); - if (!regs_invalidated_by_call_regset) - { - bitmap_obstack_initialize (&persistent_obstack); - regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack); - } - else - CLEAR_REG_SET (regs_invalidated_by_call_regset); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { @@ -480,10 +465,7 @@ init_reg_sets_1 (void) if (i == STACK_POINTER_REGNUM) ; else if (global_regs[i]) - { SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } else if (i == FRAME_POINTER_REGNUM) ; #if !HARD_FRAME_POINTER_IS_FRAME_POINTER @@ -498,10 +480,7 @@ init_reg_sets_1 (void) && i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i]) ; else if (CALL_REALLY_USED_REGNO_P (i)) - { SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } } COPY_HARD_REG_SET(call_fixed_reg_set, fixed_reg_set); @@ -862,10 +841,7 @@ globalize_reg (tree decl, int i) appropriate regs_invalidated_by_call bit, even if it's already set in fixed_regs. */ if (i != STACK_POINTER_REGNUM) - { SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } /* If already fixed, nothing else to do. */ if (fixed_regs[i]) === modified file 'gcc/regset.h' --- gcc/regset.h 2010-05-22 21:24:53 +0000 +++ gcc/regset.h 2011-11-05 23:54:04 +0000 @@ -110,11 +110,6 @@ typedef bitmap_iterator reg_set_iterator #define EXECUTE_IF_AND_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, RSI) \ EXECUTE_IF_AND_IN_BITMAP (REGSET1, REGSET2, MIN, REGNUM, RSI) \ -/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used - in dataflow more conveniently. */ - -extern regset regs_invalidated_by_call_regset; - /* An obstack for regsets. */ extern bitmap_obstack reg_obstack; === modified file 'gcc/reorg.c' --- gcc/reorg.c 2011-10-15 10:32:33 +0000 +++ gcc/reorg.c 2011-11-05 23:54:04 +0000 @@ -293,18 +293,7 @@ resource_conflicts_p (struct resources * || res1->volatil || res2->volatil) return 1; -#ifdef HARD_REG_SET - return (res1->regs & res2->regs) != HARD_CONST (0); -#else - { - int i; - - for (i = 0; i < HARD_REG_SET_LONGS; i++) - if ((res1->regs[i] & res2->regs[i]) != 0) - return 1; - return 0; - } -#endif + return hard_reg_set_intersect_p(res1->regs, res2->regs); } /* Return TRUE if any resource marked in RES, a `struct resources', is === modified file 'gcc/target.def' --- gcc/target.def 2011-10-20 20:10:05 +0000 +++ gcc/target.def 2011-11-06 22:08:27 +0000 @@ -2598,8 +2598,8 @@ HOOK_VECTOR_END (target_option) DEFHOOK (extra_live_on_entry, "", - void, (bitmap regs), - hook_void_bitmap) + void, (struct hard_reg_set_container *regs), + hook_void_hard_reg_set) /* Determine the type of unwind info to emit for debugging. */ DEFHOOK === modified file 'gcc/target.h' --- gcc/target.h 2011-06-16 13:45:47 +0000 +++ gcc/target.h 2011-11-06 18:29:34 +0000 @@ -52,6 +52,9 @@ #include "insn-modes.h" +/* We can't include target-dependant hard-reg-set.h thus the opaque struct */ +struct hard_reg_set_container; + #ifdef ENABLE_CHECKING typedef struct { void *magic; void *p; } cumulative_args_t; === modified file 'gcc/targhooks.c' --- gcc/targhooks.c 2011-10-06 19:25:53 +0000 +++ gcc/targhooks.c 2011-11-06 22:06:18 +0000 @@ -607,7 +607,7 @@ default_function_arg_round_boundary (enu } void -hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) +hook_void_hard_reg_set (struct hard_reg_set_container *regs ATTRIBUTE_UNUSED) { } === modified file 'gcc/targhooks.h' --- gcc/targhooks.h 2011-10-06 19:25:53 +0000 +++ gcc/targhooks.h 2011-11-06 22:06:32 +0000 @@ -128,7 +128,7 @@ extern reg_class_t default_secondary_rel enum machine_mode, secondary_reload_info *); extern void default_target_option_override (void); -extern void hook_void_bitmap (bitmap); +extern void hook_void_hard_reg_set (struct hard_reg_set_container *); extern int default_reloc_rw_mask (void); extern tree default_mangle_decl_assembler_name (tree, tree); extern tree default_emutls_var_fields (tree, tree *); === modified file 'gcc/config/i386/i386.c' --- gcc/config/i386/i386.c 2011-10-21 19:32:20 +0000 +++ gcc/config/i386/i386.c 2011-11-06 23:00:48 +0000 @@ -11206,12 +11206,12 @@ ix86_expand_split_stack_prologue (void) is initializing a scratch register. */ static void -ix86_live_on_entry (bitmap regs) +ix86_live_on_entry (HARD_REG_SET *regs) { if (cfun->machine->split_stack_varargs_pointer != NULL_RTX) { gcc_assert (flag_split_stack); - bitmap_set_bit (regs, split_stack_prologue_scratch_regno ()); + SET_HARD_REG_BIT (*regs, split_stack_prologue_scratch_regno ()); } } === modified file 'gcc/config/mips/mips.c' --- gcc/config/mips/mips.c 2011-10-02 17:46:11 +0000 +++ gcc/config/mips/mips.c 2011-11-06 23:00:48 +0000 @@ -9419,22 +9419,22 @@ mips_initial_elimination_offset (int fro /* Implement TARGET_EXTRA_LIVE_ON_ENTRY. */ static void -mips_extra_live_on_entry (bitmap regs) +mips_extra_live_on_entry (HARD_REG_SET *regs) { if (TARGET_USE_GOT) { /* PIC_FUNCTION_ADDR_REGNUM is live if we need it to set up the global pointer. */ if (!TARGET_ABSOLUTE_ABICALLS) - bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM); + SET_HARD_REG_BIT (*regs, PIC_FUNCTION_ADDR_REGNUM); /* The prologue may set MIPS16_PIC_TEMP_REGNUM to the value of the global pointer. */ if (TARGET_MIPS16) - bitmap_set_bit (regs, MIPS16_PIC_TEMP_REGNUM); + SET_HARD_REG_BIT (*regs, MIPS16_PIC_TEMP_REGNUM); /* See the comment above load_call for details. */ - bitmap_set_bit (regs, GOT_VERSION_REGNUM); + SET_HARD_REG_BIT (*regs, GOT_VERSION_REGNUM); } } === modified file 'gcc/config/pa/pa.c' --- gcc/config/pa/pa.c 2011-10-12 13:08:11 +0000 +++ gcc/config/pa/pa.c 2011-11-06 23:00:48 +0000 @@ -171,7 +171,7 @@ static struct machine_function * pa_init static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t, enum machine_mode, secondary_reload_info *); -static void pa_extra_live_on_entry (bitmap); +static void pa_extra_live_on_entry (HARD_REG_SET *); static enum machine_mode pa_promote_function_mode (const_tree, enum machine_mode, int *, const_tree, int); @@ -5936,10 +5936,10 @@ pa_secondary_reload (bool in_p, rtx x, r so we need to mark it here. */ static void -pa_extra_live_on_entry (bitmap regs) +pa_extra_live_on_entry (HARD_REG_SET *regs) { if (TARGET_64BIT) - bitmap_set_bit (regs, ARG_POINTER_REGNUM); + SET_HARD_REG_BIT (*regs, ARG_POINTER_REGNUM); } /* Implement EH_RETURN_HANDLER_RTX. The MEM needs to be volatile === modified file 'gcc/dce.c' --- gcc/dce.c 2011-07-19 17:43:15 +0000 +++ gcc/dce.c 2011-11-05 23:54:04 +0000 @@ -867,7 +867,7 @@ word_dce_process_block (basic_block bb, artificial uses. */ static bool -dce_process_block (basic_block bb, bool redo_out, bitmap au) +dce_process_block (basic_block bb, bool redo_out, HARD_REG_SET au) { bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack); rtx insn; @@ -906,7 +906,8 @@ dce_process_block (basic_block bb, bool if (!needed) for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec)) - || bitmap_bit_p (au, DF_REF_REGNO (*def_rec))) + || ( DF_REF_REGNO (*def_rec) < FIRST_PSEUDO_REGISTER + && TEST_HARD_REG_BIT (au, DF_REF_REGNO (*def_rec)))) { needed = true; mark_insn (insn, true); @@ -952,13 +953,16 @@ fast_dce (bool word_level) bool global_changed = true; /* These regs are considered always live so if they end up dying - because of some def, we need to bring the back again. Calling + because of some def, we need to bring them back again. Calling df_simulate_fixup_sets has the disadvantage of calling bb_has_eh_pred once per insn, so we cache the information here. */ - bitmap au = &df->regular_block_artificial_uses; - bitmap au_eh = &df->eh_block_artificial_uses; + HARD_REG_SET au; + HARD_REG_SET au_eh; int i; + + COPY_HARD_REG_SET (au, df->regular_block_artificial_uses); + COPY_HARD_REG_SET (au_eh, df->eh_block_artificial_uses); prescan_insns_for_dce (true); === modified file 'gcc/df-core.c' --- gcc/df-core.c 2011-04-20 18:19:03 +0000 +++ gcc/df-core.c 2011-11-05 23:54:04 +0000 @@ -1885,6 +1885,17 @@ df_print_regset (FILE *file, bitmap r) fprintf (file, "\n"); } +void +df_print_hard_reg_set (FILE *f, HARD_REG_SET r) +{ + unsigned int i; + hard_reg_set_iterator iter; + + EXECUTE_IF_SET_IN_HARD_REG_SET (r, 0, i, iter) + fprintf (f, " %d [%s]", i, reg_names[i]); + fprintf (f, "\n"); +} + /* Write information about registers and basic blocks into FILE. The bitmap is in the form used by df_byte_lr. This is part of making a === modified file 'gcc/df-problems.c' --- gcc/df-problems.c 2011-08-26 14:21:19 +0000 +++ gcc/df-problems.c 2011-11-05 23:54:04 +0000 @@ -432,6 +432,7 @@ df_rd_local_compute (bitmap all_blocks) { unsigned int bb_index; bitmap_iterator bi; + hard_reg_set_iterator iter; unsigned int regno; struct df_rd_problem_data *problem_data = (struct df_rd_problem_data *) df_rd->problem_data; @@ -449,7 +450,7 @@ df_rd_local_compute (bitmap all_blocks) } /* Set up the knockout bit vectors to be applied across EH_EDGES. */ - EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, regno, bi) + EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, iter) { if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD) bitmap_set_bit (sparse_invalidated, regno); @@ -887,6 +888,31 @@ df_lr_bb_local_compute (unsigned int bb_ df_recompute_luids (bb); } +/* TODO optimise per-word */ +static void +bitmap_copy_from_hard_reg_set(bitmap to, HARD_REG_SET from) +{ + unsigned int i; + hard_reg_set_iterator iter; + + bitmap_clear (to); + EXECUTE_IF_SET_IN_HARD_REG_SET (from, 0, i, iter) + bitmap_set_bit (to, i); +} + +/* TODO optimise per-word */ +static bool +bitmap_ior_from_hard_reg_set(bitmap to, HARD_REG_SET from) +{ + bool ret= false; + hard_reg_set_iterator iter; + unsigned int i; + + EXECUTE_IF_SET_IN_HARD_REG_SET (from, 0, i, iter) + ret |= bitmap_set_bit (to, i); + + return ret; +} /* Compute local live register info for each basic block within BLOCKS. */ @@ -896,10 +922,10 @@ df_lr_local_compute (bitmap all_blocks A unsigned int bb_index; bitmap_iterator bi; - bitmap_clear (&df->hardware_regs_used); + CLEAR_HARD_REG_SET (df->hardware_regs_used); /* The all-important stack pointer must always be live. */ - bitmap_set_bit (&df->hardware_regs_used, STACK_POINTER_REGNUM); + SET_HARD_REG_BIT (df->hardware_regs_used, STACK_POINTER_REGNUM); /* Before reload, there are a few registers that must be forced live everywhere -- which might not already be the case for @@ -909,20 +935,20 @@ df_lr_local_compute (bitmap all_blocks A unsigned int pic_offset_table_regnum = PIC_OFFSET_TABLE_REGNUM; /* Any reference to any pseudo before reload is a potential reference of the frame pointer. */ - bitmap_set_bit (&df->hardware_regs_used, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (df->hardware_regs_used, FRAME_POINTER_REGNUM); #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM /* Pseudos with argument area equivalences may require reloading via the argument pointer. */ if (fixed_regs[ARG_POINTER_REGNUM]) - bitmap_set_bit (&df->hardware_regs_used, ARG_POINTER_REGNUM); + SET_HARD_REG_BIT (df->hardware_regs_used, ARG_POINTER_REGNUM); #endif /* Any constant, or pseudo with constant equivalences, may require reloading from memory using the pic register. */ if (pic_offset_table_regnum != INVALID_REGNUM && fixed_regs[pic_offset_table_regnum]) - bitmap_set_bit (&df->hardware_regs_used, pic_offset_table_regnum); + SET_HARD_REG_BIT (df->hardware_regs_used, pic_offset_table_regnum); } EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi) @@ -932,7 +958,7 @@ df_lr_local_compute (bitmap all_blocks A /* The exit block is special for this problem and its bits are computed from thin air. */ struct df_lr_bb_info *bb_info = df_lr_get_bb_info (EXIT_BLOCK); - bitmap_copy (&bb_info->use, df->exit_block_uses); + bitmap_copy_from_hard_reg_set (&bb_info->use, df->exit_block_uses); } else df_lr_bb_local_compute (bb_index); @@ -967,9 +993,32 @@ df_lr_confluence_0 (basic_block bb) { bitmap op1 = &df_lr_get_bb_info (bb->index)->out; if (bb != EXIT_BLOCK_PTR) - bitmap_copy (op1, &df->hardware_regs_used); + bitmap_copy_from_hard_reg_set (op1, df->hardware_regs_used); } +/* to |= from1 & ~from2 + from2 is of type HARD_REG_SET */ + +static bool +bitmap_ior_and_compl_from_hard_reg_set (bitmap to, const_bitmap from1, + HARD_REG_SET from2) +{ + bool ret; + unsigned int i; + bitmap_head from1_tmp; + hard_reg_set_iterator iter; + + bitmap_initialize (&from1_tmp, &bitmap_default_obstack); + bitmap_copy (&from1_tmp, from1); + + /* TODO optimise per-word */ + EXECUTE_IF_SET_IN_HARD_REG_SET (from2, 0, i, iter) + bitmap_clear_bit (&from1_tmp, i); + ret = bitmap_ior_into (to, &from1_tmp); + + bitmap_clear (&from1_tmp); + return ret; +} /* Confluence function that ignores fake edges. */ @@ -984,11 +1033,12 @@ df_lr_confluence_n (edge e) /* ??? Abnormal call edges ignored for the moment, as this gets confused by sibling call edges, which crashes reg-stack. */ if (e->flags & EDGE_EH) - changed = bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset); + changed = bitmap_ior_and_compl_from_hard_reg_set (op1, op2, + regs_invalidated_by_call); else changed = bitmap_ior_into (op1, op2); - changed |= bitmap_ior_into (op1, &df->hardware_regs_used); + changed |= bitmap_ior_from_hard_reg_set (op1, df->hardware_regs_used); return changed; } @@ -2507,19 +2557,10 @@ df_word_lr_local_compute (bitmap all_blo unsigned int bb_index; bitmap_iterator bi; - EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi) - { - if (bb_index == EXIT_BLOCK) - { - unsigned regno; - bitmap_iterator bi; - EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER, - regno, bi) - gcc_unreachable (); - } - else - df_word_lr_bb_local_compute (bb_index); - } + EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, + 0, bb_index, bi) + if (bb_index != EXIT_BLOCK) + df_word_lr_bb_local_compute (bb_index); bitmap_clear (df_word_lr->out_of_date_transfer_functions); } @@ -3650,9 +3691,9 @@ df_simulate_fixup_sets (basic_block bb, /* These regs are considered always live so if they end up dying because of some def, we need to bring the back again. */ if (bb_has_eh_pred (bb)) - bitmap_ior_into (live, &df->eh_block_artificial_uses); + bitmap_ior_from_hard_reg_set (live, df->eh_block_artificial_uses); else - bitmap_ior_into (live, &df->regular_block_artificial_uses); + bitmap_ior_from_hard_reg_set (live, df->regular_block_artificial_uses); } @@ -4471,8 +4512,8 @@ df_md_confluence_n (edge e) return false; if (e->flags & EDGE_EH) - return bitmap_ior_and_compl_into (op1, op2, - regs_invalidated_by_call_regset); + return bitmap_ior_and_compl_from_hard_reg_set (op1, op2, + regs_invalidated_by_call); else return bitmap_ior_into (op1, op2); } === modified file 'gcc/df-scan.c' --- gcc/df-scan.c 2011-08-27 17:38:58 +0000 +++ gcc/df-scan.c 2011-11-06 23:00:48 +0000 @@ -131,13 +131,13 @@ static void df_insn_refs_collect (struct basic_block, struct df_insn_info *); static void df_canonize_collection_rec (struct df_collection_rec *); -static void df_get_regular_block_artificial_uses (bitmap); -static void df_get_eh_block_artificial_uses (bitmap); +static void df_get_regular_block_artificial_uses (HARD_REG_SET *); +static void df_get_eh_block_artificial_uses (HARD_REG_SET *); -static void df_record_entry_block_defs (bitmap); -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_record_entry_block_defs (HARD_REG_SET); +static void df_record_exit_block_uses (HARD_REG_SET); +static void df_get_exit_block_use_set (HARD_REG_SET *); +static void df_get_entry_block_def_set (HARD_REG_SET *); 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 *); @@ -146,8 +146,8 @@ static void df_refs_add_to_chains (struc basic_block, rtx); 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_exit_block_uses_collect (struct df_collection_rec *, bitmap); +static void df_entry_block_defs_collect (struct df_collection_rec *, HARD_REG_SET); +static void df_exit_block_uses_collect (struct df_collection_rec *, HARD_REG_SET); static void df_install_ref (df_ref, struct df_reg_info *, struct df_ref_info *, bool); @@ -162,7 +162,7 @@ static int df_mw_compare (const void *, regs. Final uses it to generate the code in the function prologue and epilogue to save and restore registers as needed. */ -static bool regs_ever_live[FIRST_PSEUDO_REGISTER]; +static HARD_REG_SET regs_ever_live; /*---------------------------------------------------------------------------- SCANNING DATAFLOW PROBLEM @@ -253,11 +253,9 @@ df_scan_free_internal (void) df_scan->block_info = NULL; df_scan->block_info_size = 0; - bitmap_clear (&df->hardware_regs_used); - bitmap_clear (&df->regular_block_artificial_uses); - bitmap_clear (&df->eh_block_artificial_uses); - BITMAP_FREE (df->entry_block_defs); - BITMAP_FREE (df->exit_block_uses); + CLEAR_HARD_REG_SET (df->hardware_regs_used); + CLEAR_HARD_REG_SET (df->regular_block_artificial_uses); + CLEAR_HARD_REG_SET (df->eh_block_artificial_uses); bitmap_clear (&df->insns_to_delete); bitmap_clear (&df->insns_to_rescan); bitmap_clear (&df->insns_to_notes_rescan); @@ -366,11 +364,11 @@ df_scan_alloc (bitmap all_blocks ATTRIBU bb_info->artificial_uses = NULL; } - bitmap_initialize (&df->hardware_regs_used, &problem_data->reg_bitmaps); - bitmap_initialize (&df->regular_block_artificial_uses, &problem_data->reg_bitmaps); - bitmap_initialize (&df->eh_block_artificial_uses, &problem_data->reg_bitmaps); - df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps); - df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps); + CLEAR_HARD_REG_SET (df->hardware_regs_used); + CLEAR_HARD_REG_SET (df->regular_block_artificial_uses); + CLEAR_HARD_REG_SET (df->eh_block_artificial_uses); + CLEAR_HARD_REG_SET (df->entry_block_defs); + CLEAR_HARD_REG_SET (df->exit_block_uses); bitmap_initialize (&df->insns_to_delete, &problem_data->insn_bitmaps); bitmap_initialize (&df->insns_to_rescan, &problem_data->insn_bitmaps); bitmap_initialize (&df->insns_to_notes_rescan, &problem_data->insn_bitmaps); @@ -409,21 +407,28 @@ df_scan_start_dump (FILE *file ATTRIBUTE rtx insn; fprintf (file, ";; invalidated by call \t"); - df_print_regset (file, regs_invalidated_by_call_regset); + df_print_hard_reg_set (file, regs_invalidated_by_call); + fprintf (file, ";; hardware regs used \t"); - df_print_regset (file, &df->hardware_regs_used); + df_print_hard_reg_set (file, df->hardware_regs_used); + fprintf (file, ";; regular block artificial uses \t"); - df_print_regset (file, &df->regular_block_artificial_uses); + df_print_hard_reg_set (file, df->regular_block_artificial_uses); + fprintf (file, ";; eh block artificial uses \t"); - df_print_regset (file, &df->eh_block_artificial_uses); + df_print_hard_reg_set (file, df->eh_block_artificial_uses); + fprintf (file, ";; entry block defs \t"); - df_print_regset (file, df->entry_block_defs); + df_print_hard_reg_set (file, df->entry_block_defs); + fprintf (file, ";; exit block uses \t"); - df_print_regset (file, df->exit_block_uses); + df_print_hard_reg_set (file, df->exit_block_uses); + fprintf (file, ";; regs ever live \t"); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (df_regs_ever_live_p (i)) fprintf (file, " %d[%s]", i, reg_names[i]); + fprintf (file, "\n;; ref usage \t"); for (i = 0; i < (int)df->regs_inited; i++) @@ -662,13 +667,13 @@ df_scan_blocks (void) df_get_regular_block_artificial_uses (&df->regular_block_artificial_uses); df_get_eh_block_artificial_uses (&df->eh_block_artificial_uses); - bitmap_ior_into (&df->eh_block_artificial_uses, - &df->regular_block_artificial_uses); + IOR_HARD_REG_SET (df->eh_block_artificial_uses, + df->regular_block_artificial_uses); /* ENTRY and EXIT blocks have special defs/uses. */ - df_get_entry_block_def_set (df->entry_block_defs); + df_get_entry_block_def_set (&df->entry_block_defs); df_record_entry_block_defs (df->entry_block_defs); - df_get_exit_block_use_set (df->exit_block_uses); + df_get_exit_block_use_set (&df->exit_block_uses); df_record_exit_block_uses (df->exit_block_uses); df_set_bb_dirty (BASIC_BLOCK (ENTRY_BLOCK)); df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK)); @@ -3318,20 +3323,20 @@ df_get_call_refs (struct df_collection_r int flags) { rtx note; - bitmap_iterator bi; + hard_reg_set_iterator iter; unsigned int ui; bool is_sibling_call; unsigned int i; df_ref def; - bitmap_head defs_generated; + HARD_REG_SET defs_generated; - bitmap_initialize (&defs_generated, &df_bitmap_obstack); + CLEAR_HARD_REG_SET(defs_generated); /* Do not generate clobbers for registers that are the result of the call. This causes ordering problems in the chain building code depending on which def is seen first. */ FOR_EACH_VEC_ELT (df_ref, collection_rec->def_vec, i, def) - bitmap_set_bit (&defs_generated, DF_REF_REGNO (def)); + SET_HARD_REG_BIT (defs_generated, DF_REF_REGNO (def)); /* Record the registers used to pass arguments, and explicitly noted as clobbered. */ @@ -3346,7 +3351,7 @@ df_get_call_refs (struct df_collection_r if (REG_P (XEXP (XEXP (note, 0), 0))) { unsigned int regno = REGNO (XEXP (XEXP (note, 0), 0)); - if (!bitmap_bit_p (&defs_generated, regno)) + if (!TEST_HARD_REG_BIT (defs_generated, regno)) df_defs_record (collection_rec, XEXP (note, 0), bb, insn_info, flags); } @@ -3376,12 +3381,12 @@ df_get_call_refs (struct df_collection_r } is_sibling_call = SIBLING_CALL_P (insn_info->insn); - EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, ui, bi) + EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, ui, iter) { if (!global_regs[ui] - && (!bitmap_bit_p (&defs_generated, ui)) + && (!TEST_HARD_REG_BIT (defs_generated, ui)) && (!is_sibling_call - || !bitmap_bit_p (df->exit_block_uses, ui) + || !TEST_HARD_REG_BIT (df->exit_block_uses, ui) || refers_to_regno_p (ui, ui+1, crtl->return_rtx, NULL))) df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[ui], @@ -3389,7 +3394,6 @@ df_get_call_refs (struct df_collection_r DF_REF_MAY_CLOBBER | flags); } - bitmap_clear (&defs_generated); return; } @@ -3535,13 +3539,13 @@ df_bb_refs_collect (struct df_collection /* Add the artificial uses. */ if (bb->index >= NUM_FIXED_BLOCKS) { - bitmap_iterator bi; + hard_reg_set_iterator iter; unsigned int regno; - bitmap au = bb_has_eh_pred (bb) - ? &df->eh_block_artificial_uses - : &df->regular_block_artificial_uses; + HARD_REG_SET *au= bb_has_eh_pred (bb) + ? &(df->eh_block_artificial_uses) + : &(df->regular_block_artificial_uses); - EXECUTE_IF_SET_IN_BITMAP (au, 0, regno, bi) + EXECUTE_IF_SET_IN_HARD_REG_SET (*au, 0, regno, iter) { df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL, bb, NULL, DF_REF_REG_USE, 0); @@ -3608,18 +3612,18 @@ df_bb_refs_record (int bb_index, bool sc block. */ static void -df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses) +df_get_regular_block_artificial_uses (HARD_REG_SET *regular_block_artificial_uses) { #ifdef EH_USES unsigned int i; #endif - bitmap_clear (regular_block_artificial_uses); + CLEAR_HARD_REG_SET (*regular_block_artificial_uses); if (reload_completed) { if (frame_pointer_needed) - bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); } else /* Before reload, there are a few registers that must be forced @@ -3630,27 +3634,27 @@ df_get_regular_block_artificial_uses (bi /* Any reference to any pseudo before reload is a potential reference of the frame pointer. */ - bitmap_set_bit (regular_block_artificial_uses, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, FRAME_POINTER_REGNUM); #if !HARD_FRAME_POINTER_IS_FRAME_POINTER - bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); #endif #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM /* Pseudos with argument area equivalences may require reloading via the argument pointer. */ if (fixed_regs[ARG_POINTER_REGNUM]) - bitmap_set_bit (regular_block_artificial_uses, ARG_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, ARG_POINTER_REGNUM); #endif /* Any constant, or pseudo with constant equivalences, may require reloading from memory using the pic register. */ if (picreg != INVALID_REGNUM && fixed_regs[picreg]) - bitmap_set_bit (regular_block_artificial_uses, picreg); + SET_HARD_REG_BIT (*regular_block_artificial_uses, picreg); } /* The all-important stack pointer must always be live. */ - bitmap_set_bit (regular_block_artificial_uses, STACK_POINTER_REGNUM); + SET_HARD_REG_BIT (*regular_block_artificial_uses, STACK_POINTER_REGNUM); #ifdef EH_USES /* EH_USES registers are used: @@ -3663,7 +3667,7 @@ df_get_regular_block_artificial_uses (bi (noreturn call or infinite loop). */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (EH_USES (i)) - bitmap_set_bit (regular_block_artificial_uses, i); + SET_HARD_REG_BIT (*regular_block_artificial_uses, i); #endif } @@ -3671,9 +3675,9 @@ df_get_regular_block_artificial_uses (bi /* Get the artificial use set for an eh block. */ static void -df_get_eh_block_artificial_uses (bitmap eh_block_artificial_uses) +df_get_eh_block_artificial_uses (HARD_REG_SET *eh_block_artificial_uses) { - bitmap_clear (eh_block_artificial_uses); + CLEAR_HARD_REG_SET (*eh_block_artificial_uses); /* The following code (down thru the arg_pointer setting APPEARS to be necessary because there is nothing that actually @@ -3683,14 +3687,14 @@ df_get_eh_block_artificial_uses (bitmap { if (frame_pointer_needed) { - bitmap_set_bit (eh_block_artificial_uses, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*eh_block_artificial_uses, FRAME_POINTER_REGNUM); #if !HARD_FRAME_POINTER_IS_FRAME_POINTER - bitmap_set_bit (eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM); #endif } #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM if (fixed_regs[ARG_POINTER_REGNUM]) - bitmap_set_bit (eh_block_artificial_uses, ARG_POINTER_REGNUM); + SET_HARD_REG_BIT (*eh_block_artificial_uses, ARG_POINTER_REGNUM); #endif } } @@ -3708,7 +3712,7 @@ df_get_eh_block_artificial_uses (bitmap static void df_mark_reg (rtx reg, void *vset) { - bitmap set = (bitmap) vset; + HARD_REG_SET *set = (HARD_REG_SET *) vset; int regno = REGNO (reg); gcc_assert (GET_MODE (reg) != BLKmode); @@ -3716,29 +3720,34 @@ df_mark_reg (rtx reg, void *vset) if (regno < FIRST_PSEUDO_REGISTER) { int n = hard_regno_nregs[regno][GET_MODE (reg)]; - bitmap_set_range (set, regno, n); + int i; + for (i=regno; ientry_block_defs) - { - if (!bitmap_equal_p (df->entry_block_defs, &refs)) - { - struct df_scan_bb_info *bb_info = df_scan_get_bb_info (ENTRY_BLOCK); - df_ref_chain_delete_du_chain (bb_info->artificial_defs); - df_ref_chain_delete (bb_info->artificial_defs); - bb_info->artificial_defs = NULL; - changed = true; - } - } - else + if (!hard_reg_set_equal_p (df->entry_block_defs, refs)) { - struct df_scan_problem_data *problem_data - = (struct df_scan_problem_data *) df_scan->problem_data; - gcc_unreachable (); - df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps); - changed = true; - } + struct df_scan_bb_info *bb_info = df_scan_get_bb_info (ENTRY_BLOCK); + df_ref_chain_delete_du_chain (bb_info->artificial_defs); + df_ref_chain_delete (bb_info->artificial_defs); + bb_info->artificial_defs = NULL; - if (changed) - { - df_record_entry_block_defs (&refs); - bitmap_copy (df->entry_block_defs, &refs); + df_record_entry_block_defs (refs); + COPY_HARD_REG_SET (df->entry_block_defs, refs); df_set_bb_dirty (BASIC_BLOCK (ENTRY_BLOCK)); } - bitmap_clear (&refs); } /* Set the bit for regs that are considered being used at the exit. */ static void -df_get_exit_block_use_set (bitmap exit_block_uses) +df_get_exit_block_use_set (HARD_REG_SET *exit_block_uses) { unsigned int i; unsigned int picreg = PIC_OFFSET_TABLE_REGNUM; - bitmap_clear (exit_block_uses); + CLEAR_HARD_REG_SET (*exit_block_uses); /* Stack pointer is always live at the exit. */ - bitmap_set_bit (exit_block_uses, STACK_POINTER_REGNUM); + SET_HARD_REG_BIT (*exit_block_uses, STACK_POINTER_REGNUM); /* Mark the frame pointer if needed at the end of the function. If we end up eliminating it, it will be removed from the live @@ -3903,11 +3896,11 @@ df_get_exit_block_use_set (bitmap exit_b if ((!reload_completed) || frame_pointer_needed) { - bitmap_set_bit (exit_block_uses, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*exit_block_uses, FRAME_POINTER_REGNUM); #if !HARD_FRAME_POINTER_IS_FRAME_POINTER /* If they are different, also mark the hard frame pointer as live. */ if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM)) - bitmap_set_bit (exit_block_uses, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*exit_block_uses, HARD_FRAME_POINTER_REGNUM); #endif } @@ -3917,14 +3910,14 @@ df_get_exit_block_use_set (bitmap exit_b if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED && picreg != INVALID_REGNUM && fixed_regs[picreg]) - bitmap_set_bit (exit_block_uses, picreg); + SET_HARD_REG_BIT (*exit_block_uses, picreg); /* Mark all global registers, and all registers used by the epilogue as being live at the end of the function since they may be referenced by our caller. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (global_regs[i] || EPILOGUE_USES (i)) - bitmap_set_bit (exit_block_uses, i); + SET_HARD_REG_BIT (*exit_block_uses, i); if (HAVE_epilogue && epilogue_completed) { @@ -3932,7 +3925,7 @@ df_get_exit_block_use_set (bitmap exit_b for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (df_regs_ever_live_p (i) && !LOCAL_REGNO (i) && !TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) - bitmap_set_bit (exit_block_uses, i); + SET_HARD_REG_BIT (*exit_block_uses, i); } #ifdef EH_RETURN_DATA_REGNO @@ -3943,7 +3936,7 @@ df_get_exit_block_use_set (bitmap exit_b unsigned regno = EH_RETURN_DATA_REGNO (i); if (regno == INVALID_REGNUM) break; - bitmap_set_bit (exit_block_uses, regno); + SET_HARD_REG_BIT (*exit_block_uses, regno); } #endif @@ -3976,12 +3969,12 @@ df_get_exit_block_use_set (bitmap exit_b It uses df->exit_block_uses to determine register to include. */ static void -df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exit_block_uses) +df_exit_block_uses_collect (struct df_collection_rec *collection_rec, HARD_REG_SET exit_block_uses) { unsigned int i; - bitmap_iterator bi; + hard_reg_set_iterator iter; - EXECUTE_IF_SET_IN_BITMAP (exit_block_uses, 0, i, bi) + EXECUTE_IF_SET_IN_HARD_REG_SET (exit_block_uses, 0, i, iter) df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL, EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0); @@ -3989,7 +3982,7 @@ df_exit_block_uses_collect (struct df_co /* It is deliberate that this is not put in the exit block uses but I do not know why. */ if (reload_completed - && !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM) + && !TEST_HARD_REG_BIT (exit_block_uses, ARG_POINTER_REGNUM) && bb_has_eh_pred (EXIT_BLOCK_PTR) && fixed_regs[ARG_POINTER_REGNUM]) df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL, @@ -4004,16 +3997,17 @@ df_exit_block_uses_collect (struct df_co It uses df->exit_block_uses to determine which bit to include. */ static void -df_record_exit_block_uses (bitmap exit_block_uses) +df_record_exit_block_uses (HARD_REG_SET exit_block_uses) { struct df_collection_rec collection_rec; + memset (&collection_rec, 0, sizeof (struct df_collection_rec)); collection_rec.use_vec = VEC_alloc (df_ref, stack, FIRST_PSEUDO_REGISTER); df_exit_block_uses_collect (&collection_rec, exit_block_uses); - /* Process bb_refs chain */ df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (EXIT_BLOCK), NULL); + VEC_free (df_ref, stack, collection_rec.use_vec); } @@ -4023,38 +4017,20 @@ df_record_exit_block_uses (bitmap exit_b void df_update_exit_block_uses (void) { - bitmap_head refs; - bool changed = false; + HARD_REG_SET refs; - bitmap_initialize (&refs, &df_bitmap_obstack); df_get_exit_block_use_set (&refs); - if (df->exit_block_uses) - { - if (!bitmap_equal_p (df->exit_block_uses, &refs)) - { - struct df_scan_bb_info *bb_info = df_scan_get_bb_info (EXIT_BLOCK); - df_ref_chain_delete_du_chain (bb_info->artificial_uses); - df_ref_chain_delete (bb_info->artificial_uses); - bb_info->artificial_uses = NULL; - changed = true; - } - } - else + if (!hard_reg_set_equal_p (df->exit_block_uses, refs)) { - struct df_scan_problem_data *problem_data - = (struct df_scan_problem_data *) df_scan->problem_data; - gcc_unreachable (); - df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps); - changed = true; - } + struct df_scan_bb_info *bb_info = df_scan_get_bb_info (EXIT_BLOCK); + df_ref_chain_delete_du_chain (bb_info->artificial_uses); + df_ref_chain_delete (bb_info->artificial_uses); + bb_info->artificial_uses = NULL; - if (changed) - { - df_record_exit_block_uses (&refs); - bitmap_copy (df->exit_block_uses,& refs); + df_record_exit_block_uses (refs); + COPY_HARD_REG_SET (df->exit_block_uses, refs); df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK)); } - bitmap_clear (&refs); } static bool initialized = false; @@ -4143,7 +4119,7 @@ df_hard_reg_used_count (unsigned int reg bool df_regs_ever_live_p (unsigned int regno) { - return regs_ever_live[regno]; + return TEST_HARD_REG_BIT (regs_ever_live, regno); } @@ -4153,10 +4129,14 @@ df_regs_ever_live_p (unsigned int regno) void df_set_regs_ever_live (unsigned int regno, bool value) { - if (regs_ever_live[regno] == value) + if (df_regs_ever_live_p (regno) == value) return; - regs_ever_live[regno] = value; + if (value) + SET_HARD_REG_BIT (regs_ever_live, regno); + else + CLEAR_HARD_REG_BIT (regs_ever_live, regno); + if (df) df->redo_entry_and_exit = true; } @@ -4172,12 +4152,12 @@ df_compute_regs_ever_live (bool reset) bool changed = df->redo_entry_and_exit; if (reset) - memset (regs_ever_live, 0, sizeof (regs_ever_live)); + CLEAR_HARD_REG_SET (regs_ever_live); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if ((!regs_ever_live[i]) && df_hard_reg_used_p (i)) + if ((!df_regs_ever_live_p (i)) && df_hard_reg_used_p (i)) { - regs_ever_live[i] = true; + df_set_regs_ever_live (i, true); changed = true; } if (changed) @@ -4410,26 +4390,23 @@ df_bb_verify (basic_block bb) static bool df_entry_block_bitmap_verify (bool abort_if_fail) { - bitmap_head entry_block_defs; + HARD_REG_SET entry_block_defs; bool is_eq; - bitmap_initialize (&entry_block_defs, &df_bitmap_obstack); df_get_entry_block_def_set (&entry_block_defs); - is_eq = bitmap_equal_p (&entry_block_defs, df->entry_block_defs); + is_eq = hard_reg_set_equal_p (entry_block_defs, df->entry_block_defs); if (!is_eq && abort_if_fail) { print_current_pass (stderr); fprintf (stderr, "entry_block_defs = "); - df_print_regset (stderr, &entry_block_defs); + df_print_hard_reg_set (stderr, entry_block_defs); fprintf (stderr, "df->entry_block_defs = "); - df_print_regset (stderr, df->entry_block_defs); + df_print_hard_reg_set (stderr, df->entry_block_defs); gcc_assert (0); } - bitmap_clear (&entry_block_defs); - return is_eq; } @@ -4440,26 +4417,23 @@ df_entry_block_bitmap_verify (bool abort static bool df_exit_block_bitmap_verify (bool abort_if_fail) { - bitmap_head exit_block_uses; + HARD_REG_SET exit_block_uses; bool is_eq; - bitmap_initialize (&exit_block_uses, &df_bitmap_obstack); df_get_exit_block_use_set (&exit_block_uses); - is_eq = bitmap_equal_p (&exit_block_uses, df->exit_block_uses); + is_eq = hard_reg_set_equal_p (exit_block_uses, df->exit_block_uses); if (!is_eq && abort_if_fail) { print_current_pass (stderr); fprintf (stderr, "exit_block_uses = "); - df_print_regset (stderr, &exit_block_uses); + df_print_hard_reg_set (stderr, exit_block_uses); fprintf (stderr, "df->exit_block_uses = "); - df_print_regset (stderr, df->exit_block_uses); + df_print_hard_reg_set (stderr, df->exit_block_uses); gcc_assert (0); } - bitmap_clear (&exit_block_uses); - return is_eq; } @@ -4472,8 +4446,8 @@ df_scan_verify (void) { unsigned int i; basic_block bb; - bitmap_head regular_block_artificial_uses; - bitmap_head eh_block_artificial_uses; + HARD_REG_SET regular_block_artificial_uses; + HARD_REG_SET eh_block_artificial_uses; if (!df) return; @@ -4494,23 +4468,18 @@ df_scan_verify (void) /* (2) There are various bitmaps whose value may change over the course of the compilation. This step recomputes them to make sure that they have not slipped out of date. */ - bitmap_initialize (®ular_block_artificial_uses, &df_bitmap_obstack); - bitmap_initialize (&eh_block_artificial_uses, &df_bitmap_obstack); df_get_regular_block_artificial_uses (®ular_block_artificial_uses); df_get_eh_block_artificial_uses (&eh_block_artificial_uses); - bitmap_ior_into (&eh_block_artificial_uses, - ®ular_block_artificial_uses); + IOR_HARD_REG_SET (eh_block_artificial_uses, + regular_block_artificial_uses); /* Check artificial_uses bitmaps didn't change. */ - gcc_assert (bitmap_equal_p (®ular_block_artificial_uses, - &df->regular_block_artificial_uses)); - gcc_assert (bitmap_equal_p (&eh_block_artificial_uses, - &df->eh_block_artificial_uses)); - - bitmap_clear (®ular_block_artificial_uses); - bitmap_clear (&eh_block_artificial_uses); + gcc_assert (hard_reg_set_equal_p (regular_block_artificial_uses, + df->regular_block_artificial_uses)); + gcc_assert (hard_reg_set_equal_p (eh_block_artificial_uses, + df->eh_block_artificial_uses)); /* Verify entry block and exit block. These only verify the bitmaps, the refs are verified in df_bb_verify. */ === modified file 'gcc/df.h' --- gcc/df.h 2010-12-14 00:23:40 +0000 +++ gcc/df.h 2011-11-05 23:54:04 +0000 @@ -69,7 +69,7 @@ enum df_flow_dir /* Descriminator for the various df_ref types. */ enum df_ref_class {DF_REF_BASE, DF_REF_ARTIFICIAL, DF_REF_REGULAR}; -/* The first of these us a set of a registers. The remaining three +/* The first of these uses a set of a registers. The remaining three are all uses of a register (the mem_load and mem_store relate to how the register as an addressing operand). */ enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, @@ -545,16 +545,17 @@ struct df_d int num_problems_defined; - bitmap_head hardware_regs_used; /* The set of hardware registers used. */ + HARD_REG_SET hardware_regs_used; /* The set of hardware registers used. */ /* The set of hard regs that are in the artificial uses at the end of a regular basic block. */ - bitmap_head regular_block_artificial_uses; + HARD_REG_SET regular_block_artificial_uses; /* The set of hard regs that are in the artificial uses at the end of a basic block that has an EH pred. */ - bitmap_head eh_block_artificial_uses; + HARD_REG_SET eh_block_artificial_uses; /* The set of hardware registers live on entry to the function. */ - bitmap entry_block_defs; - bitmap exit_block_uses; /* The set of hardware registers used in exit block. */ + HARD_REG_SET entry_block_defs; + /* The set of hardware registers used in exit block. */ + HARD_REG_SET exit_block_uses; /* Insns to delete, rescan or reprocess the notes at next df_rescan_all or df_process_deferred_rescans. */ @@ -911,6 +912,7 @@ extern bool df_reg_defined (rtx, rtx); extern df_ref df_find_use (rtx, rtx); extern bool df_reg_used (rtx, rtx); extern void df_worklist_dataflow (struct dataflow *,bitmap, int *, int); +extern void df_print_hard_reg_set (FILE *f, HARD_REG_SET r); extern void df_print_regset (FILE *file, bitmap r); extern void df_print_word_regset (FILE *file, bitmap r); extern void df_dump (FILE *); === modified file 'gcc/doc/tm.texi' --- gcc/doc/tm.texi 2011-10-20 20:10:05 +0000 +++ gcc/doc/tm.texi 2011-11-06 23:00:48 +0000 @@ -4946,7 +4946,7 @@ as the @code{sibcall} md pattern can not may vary greatly between different architectures. @end deftypefn -@deftypefn {Target Hook} void TARGET_EXTRA_LIVE_ON_ENTRY (bitmap @var{regs}) +@deftypefn {Target Hook} void TARGET_EXTRA_LIVE_ON_ENTRY (HARD_REG_SET *@var{regs}) Add any hard registers to @var{regs} that are live on entry to the function. This hook only needs to be defined to provide registers that cannot be found by examination of FUNCTION_ARG_REGNO_P, the callee saved === modified file 'gcc/hard-reg-set.h' --- gcc/hard-reg-set.h 2011-01-03 20:52:22 +0000 +++ gcc/hard-reg-set.h 2011-11-06 23:08:49 +0000 @@ -24,35 +24,31 @@ along with GCC; see the file COPYING3. /* Define the type of a set of hard registers. */ /* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which - will be used for hard reg sets, either alone or in an array. - - If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE, - and it has enough bits to represent all the target machine's hard - registers. Otherwise, it is a typedef for a suitably sized array - of HARD_REG_ELT_TYPEs. HARD_REG_SET_LONGS is defined as how many. + will be used for hard reg sets. An HARD_REG_ELT_TYPE, or an + array of them is wrapped in a struct. Note that lots of code assumes that the first part of a regset is the same format as a HARD_REG_SET. To help make sure this is true, we only try the widest fast integer mode (HOST_WIDEST_FAST_INT) - instead of all the smaller types. This approach loses only if - there are very few registers and then only in the few cases where - we have an array of HARD_REG_SETs, so it needn't be as complex as - it used to be. */ - -typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE; - -#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT - -#define HARD_REG_SET HARD_REG_ELT_TYPE + instead of all the smaller types. */ +#ifdef ENABLE_RTL_CHECKING +#define gcc_rtl_assert(EXPR) gcc_assert (EXPR) #else +#define gcc_rtl_assert(EXPR) ((void)(0 && (EXPR))) +#endif + +typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE; #define HARD_REG_SET_LONGS \ ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1) \ / HOST_BITS_PER_WIDEST_FAST_INT) -typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS]; -#endif +#define HARD_REG_SET struct hard_reg_set + +struct hard_reg_set { + HARD_REG_ELT_TYPE elems[HARD_REG_SET_LONGS]; +}; /* HARD_CONST is used to cast a constant to the appropriate type for use with a HARD_REG_SET. */ @@ -89,406 +85,172 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[H hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect. hard_reg_set_empty_p (X), which returns true if X is empty. */ -#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT) -#ifdef HARD_REG_SET +#define HARD_REG_ELT_BITS ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT) #define SET_HARD_REG_BIT(SET, BIT) \ - ((SET) |= HARD_CONST (1) << (BIT)) + hard_reg_set_set_bit (&(SET), (BIT)) #define CLEAR_HARD_REG_BIT(SET, BIT) \ - ((SET) &= ~(HARD_CONST (1) << (BIT))) + hard_reg_set_clear_bit(&(SET), (BIT)) #define TEST_HARD_REG_BIT(SET, BIT) \ - (!!((SET) & (HARD_CONST (1) << (BIT)))) - -#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) -#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) - -#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM)) -#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM)) - -#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) -#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) -#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM)) -#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return (x & ~y) == HARD_CONST (0); -} + hard_reg_set_bit_p(&(SET), (BIT)) -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return x == y; -} - -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return (x & y) != HARD_CONST (0); -} - -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +static inline void +hard_reg_set_set_bit (HARD_REG_SET *s, unsigned int bit) { - return x == HARD_CONST (0); -} - +#if HARD_REG_SET_LONGS > 1 + int word = bit / HARD_REG_ELT_BITS; + int bitpos = bit % HARD_REG_ELT_BITS; #else - -#define SET_HARD_REG_BIT(SET, BIT) \ - ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ - |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)) - -#define CLEAR_HARD_REG_BIT(SET, BIT) \ - ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ - &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))) - -#define TEST_HARD_REG_BIT(SET, BIT) \ - (!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ - & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))) - -#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0; -} - -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return x[0] == y[0] && x[1] == y[1]; -} - -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0; + int word = 0; + int bitpos = bit; +#endif + gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER); + (s->elems)[word] |= HARD_CONST (1) << bitpos; } -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +static inline void +hard_reg_set_clear_bit (HARD_REG_SET *s, unsigned int bit) { - return x[0] == 0 && x[1] == 0; -} - +#if HARD_REG_SET_LONGS > 1 + int word = bit / HARD_REG_ELT_BITS; + int bitpos = bit % HARD_REG_ELT_BITS; #else -#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; \ - scan_tp_[2] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; \ - scan_tp_[2] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; \ - scan_tp_[2] = scan_fp_[2]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; \ - scan_tp_[2] = ~ scan_fp_[2]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; \ - scan_tp_[2] &= scan_fp_[2]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; \ - scan_tp_[2] &= ~ scan_fp_[2]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; \ - scan_tp_[2] |= scan_fp_[2]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; \ - scan_tp_[2] |= ~ scan_fp_[2]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & ~y[0]) == 0 - && (x[1] & ~y[1]) == 0 - && (x[2] & ~y[2]) == 0); -} - -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return x[0] == y[0] && x[1] == y[1] && x[2] == y[2]; -} - -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & y[0]) != 0 - || (x[1] & y[1]) != 0 - || (x[2] & y[2]) != 0); + int word = 0; + int bitpos = bit; +#endif + gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER); + (s->elems)[word] &= ~(HARD_CONST (1) << bitpos); } static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +hard_reg_set_bit_p (const HARD_REG_SET *s, unsigned int bit) { - return x[0] == 0 && x[1] == 0 && x[2] == 0; -} - +#if HARD_REG_SET_LONGS > 1 + int word = bit / HARD_REG_ELT_BITS; + int bitpos = bit % HARD_REG_ELT_BITS; #else -#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; \ - scan_tp_[2] = 0; \ - scan_tp_[3] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; \ - scan_tp_[2] = -1; \ - scan_tp_[3] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; \ - scan_tp_[2] = scan_fp_[2]; \ - scan_tp_[3] = scan_fp_[3]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; \ - scan_tp_[2] = ~ scan_fp_[2]; \ - scan_tp_[3] = ~ scan_fp_[3]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; \ - scan_tp_[2] &= scan_fp_[2]; \ - scan_tp_[3] &= scan_fp_[3]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; \ - scan_tp_[2] &= ~ scan_fp_[2]; \ - scan_tp_[3] &= ~ scan_fp_[3]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; \ - scan_tp_[2] |= scan_fp_[2]; \ - scan_tp_[3] |= scan_fp_[3]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; \ - scan_tp_[2] |= ~ scan_fp_[2]; \ - scan_tp_[3] |= ~ scan_fp_[3]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & ~y[0]) == 0 - && (x[1] & ~y[1]) == 0 - && (x[2] & ~y[2]) == 0 - && (x[3] & ~y[3]) == 0); -} - -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3]; -} - -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & y[0]) != 0 - || (x[1] & y[1]) != 0 - || (x[2] & y[2]) != 0 - || (x[3] & y[3]) != 0); -} - -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) -{ - return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0; + int word = 0; + int bitpos = bit; +#endif + gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER); + return ((s->elems[word] >> bitpos) & HARD_CONST (1)); } -#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */ - #define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ = 0; } while (0) #define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ = -1; } while (0) #define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ = *scan_fp_++; } while (0) #define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ = ~ *scan_fp_++; } while (0) #define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ &= *scan_fp_++; } while (0) #define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ &= ~ *scan_fp_++; } while (0) #define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ |= *scan_fp_++; } while (0) #define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ |= ~ *scan_fp_++; } while (0) +#define hard_reg_set_subset_p(X, Y) hard_reg_set_subset_p_1 (&(X), &(Y)) + static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_subset_p_1 (const HARD_REG_SET *x, const HARD_REG_SET *y) { int i; for (i = 0; i < HARD_REG_SET_LONGS; i++) - if ((x[i] & ~y[i]) != 0) + if ((x->elems[i] & ~y->elems[i]) != 0) return false; return true; } +#define hard_reg_set_equal_p(X, Y) hard_reg_set_equal_p_1 (&(X), &(Y)) + static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_equal_p_1 (const HARD_REG_SET *x, const HARD_REG_SET *y) { int i; for (i = 0; i < HARD_REG_SET_LONGS; i++) - if (x[i] != y[i]) + if (x->elems[i] != y->elems[i]) return false; return true; } +#define hard_reg_set_intersect_p(X, Y) hard_reg_set_intersect_p_1 (&(X), &(Y)) + static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_intersect_p_1 (const HARD_REG_SET *x, const HARD_REG_SET *y) { int i; for (i = 0; i < HARD_REG_SET_LONGS; i++) - if ((x[i] & y[i]) != 0) + if ((x->elems[i] & y->elems[i]) != 0) return true; return false; } +#define hard_reg_set_empty_p(X) hard_reg_set_empty_p_1 (&(X)) + static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +hard_reg_set_empty_p_1 (const HARD_REG_SET *x) { int i; for (i = 0; i < HARD_REG_SET_LONGS; i++) - if (x[i] != 0) + if (x->elems[i] != 0) return false; return true; } -#endif -#endif -#endif -#endif /* Iterator for hard register sets. */ typedef struct { - /* Pointer to the current element. */ + /* Pointer to the array of elements. */ HARD_REG_ELT_TYPE *pelt; - /* The length of the set. */ - unsigned short length; - /* Word within the current element. */ unsigned short word_no; @@ -498,42 +260,32 @@ typedef struct HARD_REG_ELT_TYPE bits; } hard_reg_set_iterator; -#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT - /* The implementation of the iterator functions is fully analogous to the bitmap iterators. */ static inline void -hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set, +hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET *set, unsigned min, unsigned *regno) { -#ifdef HARD_REG_SET_LONGS - iter->pelt = set; - iter->length = HARD_REG_SET_LONGS; -#else - iter->pelt = &set; - iter->length = 1; -#endif + gcc_rtl_assert (min < FIRST_PSEUDO_REGISTER); iter->word_no = min / HARD_REG_ELT_BITS; - if (iter->word_no < iter->length) - { - iter->bits = iter->pelt[iter->word_no]; - iter->bits >>= min % HARD_REG_ELT_BITS; + gcc_rtl_assert (iter->word_no < HARD_REG_SET_LONGS); + iter->pelt = &(set->elems[0]); + + iter->bits = iter->pelt[iter->word_no]; + iter->bits >>= min % HARD_REG_ELT_BITS; + + /* This is required for correct search of the next bit. */ + min += !iter->bits; - /* This is required for correct search of the next bit. */ - min += !iter->bits; - } *regno = min; } static inline bool hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno) { - while (1) + /* Return false when we're advanced past the end of the set. */ + while (iter->word_no < HARD_REG_SET_LONGS) { - /* Return false when we're advanced past the end of the set. */ - if (iter->word_no >= iter->length) - return false; - if (iter->bits) { /* Find the correct bit and return it. */ @@ -550,7 +302,7 @@ hard_reg_set_iter_set (hard_reg_set_iter *regno -= *regno % HARD_REG_ELT_BITS; /* Find the next non-zero word. */ - while (++iter->word_no < iter->length) + while (++iter->word_no < HARD_REG_SET_LONGS) { iter->bits = iter->pelt[iter->word_no]; if (iter->bits) @@ -558,6 +310,7 @@ hard_reg_set_iter_set (hard_reg_set_iter *regno += HARD_REG_ELT_BITS; } } + return false; } static inline void @@ -568,7 +321,7 @@ hard_reg_set_iter_next (hard_reg_set_ite } #define EXECUTE_IF_SET_IN_HARD_REG_SET(SET, MIN, REGNUM, ITER) \ - for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM)); \ + for (hard_reg_set_iter_init (&(ITER), &(SET), (MIN), &(REGNUM)); \ hard_reg_set_iter_set (&(ITER), &(REGNUM)); \ hard_reg_set_iter_next (&(ITER), &(REGNUM))) === modified file 'gcc/reginfo.c' --- gcc/reginfo.c 2011-07-19 22:34:31 +0000 +++ gcc/reginfo.c 2011-11-05 23:54:04 +0000 @@ -90,14 +90,6 @@ char global_regs[FIRST_PSEUDO_REGISTER]; /* Declaration for the global register. */ static tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER]; -/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used - in dataflow more conveniently. */ -regset regs_invalidated_by_call_regset; - -/* The bitmap_obstack is used to hold some static variables that - should not be reset after each function is compiled. */ -static bitmap_obstack persistent_obstack; - /* Used to initialize reg_alloc_order. */ #ifdef REG_ALLOC_ORDER static int initial_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER; @@ -444,13 +436,6 @@ init_reg_sets_1 (void) CLEAR_HARD_REG_SET (call_used_reg_set); CLEAR_HARD_REG_SET (call_fixed_reg_set); CLEAR_HARD_REG_SET (regs_invalidated_by_call); - if (!regs_invalidated_by_call_regset) - { - bitmap_obstack_initialize (&persistent_obstack); - regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack); - } - else - CLEAR_REG_SET (regs_invalidated_by_call_regset); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { @@ -480,10 +465,7 @@ init_reg_sets_1 (void) if (i == STACK_POINTER_REGNUM) ; else if (global_regs[i]) - { SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } else if (i == FRAME_POINTER_REGNUM) ; #if !HARD_FRAME_POINTER_IS_FRAME_POINTER @@ -498,10 +480,7 @@ init_reg_sets_1 (void) && i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i]) ; else if (CALL_REALLY_USED_REGNO_P (i)) - { SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } } COPY_HARD_REG_SET(call_fixed_reg_set, fixed_reg_set); @@ -862,10 +841,7 @@ globalize_reg (tree decl, int i) appropriate regs_invalidated_by_call bit, even if it's already set in fixed_regs. */ if (i != STACK_POINTER_REGNUM) - { SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } /* If already fixed, nothing else to do. */ if (fixed_regs[i]) === modified file 'gcc/regset.h' --- gcc/regset.h 2010-05-22 21:24:53 +0000 +++ gcc/regset.h 2011-11-05 23:54:04 +0000 @@ -110,11 +110,6 @@ typedef bitmap_iterator reg_set_iterator #define EXECUTE_IF_AND_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, RSI) \ EXECUTE_IF_AND_IN_BITMAP (REGSET1, REGSET2, MIN, REGNUM, RSI) \ -/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used - in dataflow more conveniently. */ - -extern regset regs_invalidated_by_call_regset; - /* An obstack for regsets. */ extern bitmap_obstack reg_obstack; === modified file 'gcc/reorg.c' --- gcc/reorg.c 2011-10-15 10:32:33 +0000 +++ gcc/reorg.c 2011-11-05 23:54:04 +0000 @@ -293,18 +293,7 @@ resource_conflicts_p (struct resources * || res1->volatil || res2->volatil) return 1; -#ifdef HARD_REG_SET - return (res1->regs & res2->regs) != HARD_CONST (0); -#else - { - int i; - - for (i = 0; i < HARD_REG_SET_LONGS; i++) - if ((res1->regs[i] & res2->regs[i]) != 0) - return 1; - return 0; - } -#endif + return hard_reg_set_intersect_p(res1->regs, res2->regs); } /* Return TRUE if any resource marked in RES, a `struct resources', is === modified file 'gcc/target.def' --- gcc/target.def 2011-10-20 20:10:05 +0000 +++ gcc/target.def 2011-11-06 23:00:48 +0000 @@ -2598,8 +2598,8 @@ HOOK_VECTOR_END (target_option) DEFHOOK (extra_live_on_entry, "", - void, (bitmap regs), - hook_void_bitmap) + void, (HARD_REG_SET *regs), + hook_void_hard_reg_set) /* Determine the type of unwind info to emit for debugging. */ DEFHOOK === modified file 'gcc/target.h' --- gcc/target.h 2011-06-16 13:45:47 +0000 +++ gcc/target.h 2011-11-06 23:00:48 +0000 @@ -52,6 +52,11 @@ #include "insn-modes.h" +/* We can't include target-dependant hard-reg-set.h thus the opaque struct */ +struct hard_reg_set; + +#define HARD_REG_SET struct hard_reg_set + #ifdef ENABLE_CHECKING typedef struct { void *magic; void *p; } cumulative_args_t; === modified file 'gcc/targhooks.c' --- gcc/targhooks.c 2011-10-06 19:25:53 +0000 +++ gcc/targhooks.c 2011-11-06 23:00:48 +0000 @@ -607,7 +607,7 @@ default_function_arg_round_boundary (enu } void -hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) +hook_void_hard_reg_set (HARD_REG_SET *regs ATTRIBUTE_UNUSED) { } === modified file 'gcc/targhooks.h' --- gcc/targhooks.h 2011-10-06 19:25:53 +0000 +++ gcc/targhooks.h 2011-11-06 23:00:48 +0000 @@ -128,7 +128,7 @@ extern reg_class_t default_secondary_rel enum machine_mode, secondary_reload_info *); extern void default_target_option_override (void); -extern void hook_void_bitmap (bitmap); +extern void hook_void_hard_reg_set (HARD_REG_SET *); extern int default_reloc_rw_mask (void); extern tree default_mangle_decl_assembler_name (tree, tree); extern tree default_emutls_var_fields (tree, tree *);