X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fbt-load.c;h=5e3d12c359a047d239e605072756adff181d5468;hb=653d0639db9f426c9cc72bdb620d2d06055af72e;hp=fbb413561f332c6401fa05d05b7a94c352f140da;hpb=deb2741b38fe5c3702de0139b72df56eb72ebe35;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/bt-load.c b/gcc/bt-load.c index fbb413561f3..5e3d12c359a 100644 --- a/gcc/bt-load.c +++ b/gcc/bt-load.c @@ -1,12 +1,12 @@ /* Perform branch target register load optimizations. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -112,8 +111,8 @@ typedef struct btr_def_s static int issue_rate; -static int basic_block_freq (basic_block); -static int insn_sets_btr_p (rtx, int, int *); +static int basic_block_freq (const_basic_block); +static int insn_sets_btr_p (const_rtx, int, int *); static rtx *find_btr_use (rtx); static int btr_referenced_p (rtx, rtx *); static int find_btr_reference (rtx *, void *); @@ -141,8 +140,8 @@ static void btr_def_live_range (btr_def, HARD_REG_SET *); static void move_btr_def (basic_block, int, btr_def, bitmap, HARD_REG_SET *); static int migrate_btr_def (btr_def, int); static void migrate_btr_defs (enum reg_class, int); -static int can_move_up (basic_block, rtx, int); -static void note_btr_set (rtx, rtx, void *); +static int can_move_up (const_basic_block, const_rtx, int); +static void note_btr_set (rtx, const_rtx, void *); /* The following code performs code motion of target load instructions (instructions that set branch target registers), to move them @@ -180,7 +179,7 @@ static int first_btr, last_btr; /* Return an estimate of the frequency of execution of block bb. */ static int -basic_block_freq (basic_block bb) +basic_block_freq (const_basic_block bb) { return bb->frequency; } @@ -223,7 +222,7 @@ btr_referenced_p (rtx x, rtx *excludep) If such a set is found and REGNO is nonzero, assign the register number of the destination register to *REGNO. */ static int -insn_sets_btr_p (rtx insn, int check_const, int *regno) +insn_sets_btr_p (const_rtx insn, int check_const, int *regno) { rtx set; @@ -280,8 +279,7 @@ find_btr_def_group (btr_def_group *all_btr_def_groups, btr_def def) if (!this_group) { - this_group = obstack_alloc (&migrate_btrl_obstack, - sizeof (struct btr_def_group_s)); + this_group = XOBNEW (&migrate_btrl_obstack, struct btr_def_group_s); this_group->src = def_src; this_group->members = NULL; this_group->next = *all_btr_def_groups; @@ -303,31 +301,30 @@ add_btr_def (fibheap_t all_btr_defs, basic_block bb, int insn_luid, rtx insn, unsigned int dest_reg, int other_btr_uses_before_def, btr_def_group *all_btr_def_groups) { - btr_def this - = obstack_alloc (&migrate_btrl_obstack, sizeof (struct btr_def_s)); - this->bb = bb; - this->luid = insn_luid; - this->insn = insn; - this->btr = dest_reg; - this->cost = basic_block_freq (bb); - this->has_ambiguous_use = 0; - this->other_btr_uses_before_def = other_btr_uses_before_def; - this->other_btr_uses_after_use = 0; - this->next_this_bb = NULL; - this->next_this_group = NULL; - this->uses = NULL; - this->live_range = NULL; - find_btr_def_group (all_btr_def_groups, this); - - fibheap_insert (all_btr_defs, -this->cost, this); + btr_def this_def = XOBNEW (&migrate_btrl_obstack, struct btr_def_s); + this_def->bb = bb; + this_def->luid = insn_luid; + this_def->insn = insn; + this_def->btr = dest_reg; + this_def->cost = basic_block_freq (bb); + this_def->has_ambiguous_use = 0; + this_def->other_btr_uses_before_def = other_btr_uses_before_def; + this_def->other_btr_uses_after_use = 0; + this_def->next_this_bb = NULL; + this_def->next_this_group = NULL; + this_def->uses = NULL; + this_def->live_range = NULL; + find_btr_def_group (all_btr_def_groups, this_def); + + fibheap_insert (all_btr_defs, -this_def->cost, this_def); if (dump_file) fprintf (dump_file, "Found target reg definition: sets %u { bb %d, insn %d }%s priority %d\n", - dest_reg, bb->index, INSN_UID (insn), (this->group ? "" : ":not const"), - this->cost); + dest_reg, bb->index, INSN_UID (insn), + (this_def->group ? "" : ":not const"), this_def->cost); - return this; + return this_def; } /* Create a new target register user structure, for a use in block BB, @@ -355,7 +352,7 @@ new_btr_user (basic_block bb, int insn_luid, rtx insn) usep = NULL; } use = usep ? *usep : NULL_RTX; - user = obstack_alloc (&migrate_btrl_obstack, sizeof (struct btr_user_s)); + user = XOBNEW (&migrate_btrl_obstack, struct btr_user_s); user->bb = bb; user->luid = insn_luid; user->insn = insn; @@ -424,9 +421,9 @@ typedef struct { straightforward definitions. DATA points to information about the current basic block that needs updating. */ static void -note_btr_set (rtx dest, rtx set ATTRIBUTE_UNUSED, void *data) +note_btr_set (rtx dest, const_rtx set ATTRIBUTE_UNUSED, void *data) { - defs_uses_info *info = data; + defs_uses_info *info = (defs_uses_info *) data; int regno, end_regno; if (!REG_P (dest)) @@ -460,8 +457,8 @@ compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array, btr_def_group all_btr_def_groups = NULL; defs_uses_info info; - sbitmap_vector_zero (bb_gen, n_basic_blocks); - for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++) + sbitmap_vector_zero (bb_gen, last_basic_block); + for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++) { basic_block bb = BASIC_BLOCK (i); int reg; @@ -509,7 +506,7 @@ compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array, note_other_use_this_block (regno, info.users_this_bb); } /* Check for the blockage emitted by expand_nl_goto_receiver. */ - else if (current_function_has_nonlocal_label + else if (cfun->has_nonlocal_label && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE) { btr_user user; @@ -621,8 +618,8 @@ compute_kill (sbitmap *bb_kill, sbitmap *btr_defset, /* For each basic block, form the set BB_KILL - the set of definitions that the block kills. */ - sbitmap_vector_zero (bb_kill, n_basic_blocks); - for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++) + sbitmap_vector_zero (bb_kill, last_basic_block); + for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++) { for (regno = first_btr; regno <= last_btr; regno++) if (TEST_HARD_REG_BIT (all_btrs, regno) @@ -645,14 +642,14 @@ compute_out (sbitmap *bb_out, sbitmap *bb_gen, sbitmap *bb_kill, int max_uid) int changed; sbitmap bb_in = sbitmap_alloc (max_uid); - for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++) + for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++) sbitmap_copy (bb_out[i], bb_gen[i]); changed = 1; while (changed) { changed = 0; - for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++) + for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++) { sbitmap_union_of_preds (bb_in, bb_out, i); changed |= sbitmap_union_of_diff_cg (bb_out[i], bb_gen[i], @@ -671,7 +668,7 @@ link_btr_uses (btr_def *def_array, btr_user *use_array, sbitmap *bb_out, /* Link uses to the uses lists of all of their reaching defs. Count up the number of reaching defs of each use. */ - for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++) + for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++) { basic_block bb = BASIC_BLOCK (i); rtx insn; @@ -783,8 +780,8 @@ build_btr_def_use_webs (fibheap_t all_btr_defs) btr_user *use_array = XCNEWVEC (btr_user, max_uid); sbitmap *btr_defset = sbitmap_vector_alloc ( (last_btr - first_btr) + 1, max_uid); - sbitmap *bb_gen = sbitmap_vector_alloc (n_basic_blocks, max_uid); - HARD_REG_SET *btrs_written = XCNEWVEC (HARD_REG_SET, n_basic_blocks); + sbitmap *bb_gen = sbitmap_vector_alloc (last_basic_block, max_uid); + HARD_REG_SET *btrs_written = XCNEWVEC (HARD_REG_SET, last_basic_block); sbitmap *bb_kill; sbitmap *bb_out; @@ -793,11 +790,11 @@ build_btr_def_use_webs (fibheap_t all_btr_defs) compute_defs_uses_and_gen (all_btr_defs, def_array, use_array, btr_defset, bb_gen, btrs_written); - bb_kill = sbitmap_vector_alloc (n_basic_blocks, max_uid); + bb_kill = sbitmap_vector_alloc (last_basic_block, max_uid); compute_kill (bb_kill, btr_defset, btrs_written); free (btrs_written); - bb_out = sbitmap_vector_alloc (n_basic_blocks, max_uid); + bb_out = sbitmap_vector_alloc (last_basic_block, max_uid); compute_out (bb_out, bb_gen, bb_kill, max_uid); sbitmap_vector_free (bb_gen); @@ -1236,7 +1233,7 @@ move_btr_def (basic_block new_def_bb, int btr, btr_def def, bitmap live_range, /* We anticipate intra-block scheduling to be done. See if INSN could move up within BB by N_INSNS. */ static int -can_move_up (basic_block bb, rtx insn, int n_insns) +can_move_up (const_basic_block bb, const_rtx insn, int n_insns) { while (insn != BB_HEAD (bb) && n_insns > 0) { @@ -1276,7 +1273,7 @@ migrate_btr_def (btr_def def, int min_cost) HARD_REG_SET btrs_live_in_range; int btr_used_near_def = 0; int def_basic_block_freq; - basic_block try; + basic_block attempt; int give_up = 0; int def_moved = 0; btr_user user; @@ -1330,31 +1327,31 @@ migrate_btr_def (btr_def def, int min_cost) def_basic_block_freq = basic_block_freq (def->bb); - for (try = get_immediate_dominator (CDI_DOMINATORS, def->bb); - !give_up && try && try != ENTRY_BLOCK_PTR && def->cost >= min_cost; - try = get_immediate_dominator (CDI_DOMINATORS, try)) + for (attempt = get_immediate_dominator (CDI_DOMINATORS, def->bb); + !give_up && attempt && attempt != ENTRY_BLOCK_PTR && def->cost >= min_cost; + attempt = get_immediate_dominator (CDI_DOMINATORS, attempt)) { /* Try to move the instruction that sets the target register into - basic block TRY. */ - int try_freq = basic_block_freq (try); + basic block ATTEMPT. */ + int try_freq = basic_block_freq (attempt); edge_iterator ei; edge e; - /* If TRY has abnormal edges, skip it. */ - FOR_EACH_EDGE (e, ei, try->succs) + /* If ATTEMPT has abnormal edges, skip it. */ + FOR_EACH_EDGE (e, ei, attempt->succs) if (e->flags & EDGE_COMPLEX) break; if (e) continue; if (dump_file) - fprintf (dump_file, "trying block %d ...", try->index); + fprintf (dump_file, "trying block %d ...", attempt->index); if (try_freq < def_basic_block_freq || (try_freq == def_basic_block_freq && btr_used_near_def)) { int btr; - augment_live_range (live_range, &btrs_live_in_range, def->bb, try, + augment_live_range (live_range, &btrs_live_in_range, def->bb, attempt, flag_btr_bb_exclusive); if (dump_file) { @@ -1365,7 +1362,7 @@ migrate_btr_def (btr_def def, int min_cost) btr = choose_btr (btrs_live_in_range); if (btr != -1) { - move_btr_def (try, btr, def, live_range, &btrs_live_in_range); + move_btr_def (attempt, btr, def, live_range, &btrs_live_in_range); bitmap_copy(live_range, def->live_range); btr_used_near_def = 0; def_moved = 1; @@ -1406,7 +1403,7 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save) { int i; - for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++) + for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++) { basic_block bb = BASIC_BLOCK (i); fprintf(dump_file, @@ -1420,7 +1417,7 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save) CLEAR_HARD_REG_SET (all_btrs); for (first_btr = -1, reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++) if (TEST_HARD_REG_BIT (reg_class_contents[(int) btr_class], reg) - && (allow_callee_save || call_used_regs[reg] + && (allow_callee_save || call_used_regs[reg] || df_regs_ever_live_p (reg))) { SET_HARD_REG_BIT (all_btrs, reg); @@ -1429,14 +1426,14 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save) first_btr = reg; } - btrs_live = xcalloc (n_basic_blocks, sizeof (HARD_REG_SET)); - btrs_live_at_end = xcalloc (n_basic_blocks, sizeof (HARD_REG_SET)); + btrs_live = XCNEWVEC (HARD_REG_SET, last_basic_block); + btrs_live_at_end = XCNEWVEC (HARD_REG_SET, last_basic_block); build_btr_def_use_webs (all_btr_defs); while (!fibheap_empty (all_btr_defs)) { - btr_def def = fibheap_extract_min (all_btr_defs); + btr_def def = (btr_def) fibheap_extract_min (all_btr_defs); int min_cost = -fibheap_min_key (all_btr_defs); if (migrate_btr_def (def, min_cost)) { @@ -1461,8 +1458,8 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save) static void branch_target_load_optimize (bool after_prologue_epilogue_gen) { - enum reg_class class = targetm.branch_target_register_class (); - if (class != NO_REGS) + enum reg_class klass = targetm.branch_target_register_class (); + if (klass != NO_REGS) { /* Initialize issue_rate. */ if (targetm.sched.issue_rate) @@ -1484,7 +1481,7 @@ branch_target_load_optimize (bool after_prologue_epilogue_gen) /* Dominator info is also needed for migrate_btr_def. */ calculate_dominance_info (CDI_DOMINATORS); - migrate_btr_defs (class, + migrate_btr_defs (klass, (targetm.branch_target_register_callee_saved (after_prologue_epilogue_gen))); @@ -1506,22 +1503,25 @@ rest_of_handle_branch_target_load_optimize1 (void) return 0; } -struct tree_opt_pass pass_branch_target_load_optimize1 = +struct rtl_opt_pass pass_branch_target_load_optimize1 = { + { + RTL_PASS, "btl1", /* name */ gate_handle_branch_target_load_optimize1, /* gate */ rest_of_handle_branch_target_load_optimize1, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - 0, /* tv_id */ + TV_NONE, /* tv_id */ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | + TODO_verify_rtl_sharing | TODO_ggc_collect, /* todo_flags_finish */ - 'd' /* letter */ + } }; static bool @@ -1553,21 +1553,22 @@ rest_of_handle_branch_target_load_optimize2 (void) return 0; } -struct tree_opt_pass pass_branch_target_load_optimize2 = +struct rtl_opt_pass pass_branch_target_load_optimize2 = { + { + RTL_PASS, "btl2", /* name */ gate_handle_branch_target_load_optimize2, /* gate */ rest_of_handle_branch_target_load_optimize2, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - 0, /* tv_id */ + TV_NONE, /* tv_id */ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | TODO_ggc_collect, /* todo_flags_finish */ - 'd' /* letter */ + } }; -