X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgcse.c;h=c4fe5bb97dc793eafee9fe4d6670cbd2b4d33fd1;hb=45b51429826bb7a81ef960b120d00b526d15215b;hp=56117f9a170eb56dad493367045d048cdb6ba0c5;hpb=55b833d9d28f2feb21969deabdcdb71f6065b571;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/gcse.c b/gcc/gcse.c index 56117f9a170..c4fe5bb97dc 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */ - do rough calc of how many regs are needed in each block, and a rough calc of how many regs are available in each class and use that to throttle back the code in cases where RTX_COST is minimal. - - dead store elimination - a store to the same address as a load does not kill the load if the source of the store is also the destination of the load. Handling this allows more load motion, particularly out of loops. @@ -166,9 +165,6 @@ Boston, MA 02111-1307, USA. */ #define obstack_chunk_alloc gmalloc #define obstack_chunk_free free -/* Maximum number of passes to perform. */ -#define MAX_PASSES 1 - /* Propagate flow information through back edges and thus enable PRE's moving loop invariant calculations out of loops. @@ -232,7 +228,7 @@ Boston, MA 02111-1307, USA. */ substitutions. PRE is quite expensive in complicated functions because the DFA can take - awhile to converge. Hence we only perform one pass. Macro MAX_PASSES can + awhile to converge. Hence we only perform one pass. The parameter max-gcse-passes can be modified if one wants to experiment. ********************** @@ -500,16 +496,6 @@ static rtx * modify_mem_list; /* This array parallels modify_mem_list, but is kept canonicalized. */ static rtx * canon_modify_mem_list; - -/* For each block, non-zero if memory is set in that block. - This is computed during hash table computation and is used by - expr_killed_p and compute_transp. - ??? Handling of memory is very simple, we don't make any attempt - to optimize things (later). - ??? This can be computed by compute_sets since the information - doesn't change. */ -static char *mem_set_in_block; - /* Various variables for statistics gathering. */ /* Memory used in a pass. @@ -616,7 +602,7 @@ static void compute_transpout PARAMS ((void)); static void compute_local_properties PARAMS ((sbitmap *, sbitmap *, sbitmap *, int)); static void compute_cprop_data PARAMS ((void)); -static void find_used_regs PARAMS ((rtx)); +static void find_used_regs PARAMS ((rtx *, void *)); static int try_replace_reg PARAMS ((rtx, rtx, rtx)); static struct expr *find_avail_set PARAMS ((int, rtx)); static int cprop_jump PARAMS ((rtx, rtx, rtx)); @@ -756,7 +742,7 @@ gcse_main (f, file) a high connectivity will take a long time and is unlikely to be particularly useful. - In normal circumstances a cfg should have about twice has many edges + In normal circumstances a cfg should have about twice as many edges as blocks. But we do not want to punish small functions which have a couple switch statements. So we require a relatively large number of basic blocks and the ratio of edges to blocks to be high. */ @@ -810,7 +796,7 @@ gcse_main (f, file) max_pass_bytes = 0; gcse_obstack_bottom = gcse_alloc (1); changed = 1; - while (changed && pass < MAX_PASSES) + while (changed && pass < MAX_GCSE_PASSES) { changed = 0; if (file) @@ -914,7 +900,7 @@ gcse_main (f, file) pass, pass > 1 ? "es" : "", max_pass_bytes); } - obstack_free (&gcse_obstack, NULL_PTR); + obstack_free (&gcse_obstack, NULL); free_reg_set_mem (); /* We are finished with alias. */ end_alias_analysis (); @@ -948,7 +934,7 @@ compute_can_copy () #else reg = gen_rtx_REG ((enum machine_mode) i, LAST_VIRTUAL_REGISTER + 1); insn = emit_insn (gen_rtx_SET (VOIDmode, reg, reg)); - if (recog (PATTERN (insn), insn, NULL_PTR) >= 0) + if (recog (PATTERN (insn), insn, NULL) >= 0) can_copy_p[i] = 1; #endif } @@ -1035,7 +1021,6 @@ alloc_gcse_mem (f) /* Allocate vars to track sets of regs, memory per block. */ reg_set_in_block = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks, max_gcse_regno); - mem_set_in_block = (char *) gmalloc (n_basic_blocks); /* Allocate array to keep a list of insns which modify memory in each basic block. */ modify_mem_list = (rtx *) gmalloc (n_basic_blocks * sizeof (rtx *)); @@ -1054,8 +1039,7 @@ free_gcse_mem () free (reg_set_bitmap); - free (reg_set_in_block); - free (mem_set_in_block); + sbitmap_vector_free (reg_set_in_block); /* re-Cache any INSN_LIST nodes we have allocated. */ { int i; @@ -1247,7 +1231,7 @@ static void free_reg_set_mem () { free (reg_set_table); - obstack_free (®_set_obstack, NULL_PTR); + obstack_free (®_set_obstack, NULL); } /* Record REGNO in the reg_set table. */ @@ -1320,15 +1304,6 @@ compute_sets (f) static int *reg_first_set; static int *reg_last_set; -/* While computing "first/last set" info, this is the CUID of first/last insn - to set memory or -1 if not set. `mem_last_set' is also used when - performing GCSE to record whether memory has been set since the beginning - of the block. - - Note that handling of memory is very simple, we don't make any attempt - to optimize things (later). */ -static int mem_first_set; -static int mem_last_set; /* See whether X, the source of a set, is something we want to consider for GCSE. */ @@ -1412,12 +1387,6 @@ oprs_unchanged_p (x, insn, avail_p) if (load_killed_in_block_p (BLOCK_FOR_INSN (insn), INSN_CUID (insn), x, avail_p)) return 0; - if (avail_p && mem_last_set != NEVER_SET - && mem_last_set >= INSN_CUID (insn)) - return 0; - else if (! avail_p && mem_first_set != NEVER_SET - && mem_first_set < INSN_CUID (insn)) - return 0; else return oprs_unchanged_p (XEXP (x, 0), insn, avail_p); @@ -2208,7 +2177,14 @@ hash_scan_set (pat, insn, set_p) /* Is SET_SRC something we want to gcse? */ && want_to_gcse_p (src) /* Don't CSE a nop. */ - && ! set_noop_p (pat)) + && ! set_noop_p (pat) + /* Don't GCSE if it has attached REG_EQUIV note. + At this point this only function parameters should have + REG_EQUIV notes and if the argument slot is used somewhere + explicitely, it means address of parameter has been taken, + so we should not extend the lifetime of the pseudo. */ + && ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) == 0 + || GET_CODE (XEXP (note, 0)) != MEM)) { /* An expression is not anticipatable if its operands are modified before this insn or if this is not the only SET in @@ -2406,7 +2382,6 @@ canon_list_insert (dest, unused1, v_insn) alloc_INSN_LIST (dest, canon_modify_mem_list[BLOCK_NUM (insn)]); } -/* Record memory first/last/block set information for INSN. */ /* Record memory modification information for INSN. We do not actually care about the memory location(s) that are set, or even how they are set (consider a CALL_INSN). We merely need to record which insns modify memory. */ @@ -2415,11 +2390,8 @@ static void record_last_mem_set_info (insn) rtx insn; { - if (mem_first_set == NEVER_SET) - mem_first_set = INSN_CUID (insn); - - mem_last_set = INSN_CUID (insn); - mem_set_in_block[BLOCK_NUM (insn)] = 1; + /* load_killed_in_block_p will handle the case of calls clobbering + everything. */ modify_mem_list[BLOCK_NUM (insn)] = alloc_INSN_LIST (insn, modify_mem_list[BLOCK_NUM (insn)]); @@ -2482,12 +2454,9 @@ compute_hash_table (set_p) /* While we compute the hash table we also compute a bit array of which registers are set in which blocks. - We also compute which blocks set memory, in the absence of aliasing - support [which is TODO]. ??? This isn't needed during const/copy propagation, but it's cheap to compute. Later. */ sbitmap_vector_zero (reg_set_in_block, n_basic_blocks); - memset ((char *) mem_set_in_block, 0, n_basic_blocks); /* re-Cache any INSN_LIST nodes we have allocated. */ { @@ -2515,14 +2484,12 @@ compute_hash_table (set_p) /* First pass over the instructions records information used to determine when registers and memory are first and last set. - ??? The mem_set_in_block and hard-reg reg_set_in_block computation + ??? hard-reg reg_set_in_block computation could be moved to compute_sets since they currently don't change. */ for (i = 0; i < max_gcse_regno; i++) reg_first_set[i] = reg_last_set[i] = NEVER_SET; - mem_first_set = NEVER_SET; - mem_last_set = NEVER_SET; for (insn = BLOCK_HEAD (bb); insn && insn != NEXT_INSN (BLOCK_END (bb)); @@ -2544,20 +2511,7 @@ compute_hash_table (set_p) if (GET_CODE (insn) == CALL_INSN) { for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if ((call_used_regs[regno] - && regno != STACK_POINTER_REGNUM -#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM - && regno != HARD_FRAME_POINTER_REGNUM -#endif -#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM - && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno]) -#endif -#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED) - && ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic) -#endif - - && regno != FRAME_POINTER_REGNUM) - || global_regs[regno]) + if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)) record_last_reg_set_info (insn, regno); if (! CONST_CALL_P (insn)) @@ -2756,7 +2710,6 @@ reset_opr_set_tables () /* Also keep a record of the last instruction to modify memory. For now this is very trivial, we only record whether any memory location has been modified. */ - mem_last_set = 0; { int i; @@ -2803,8 +2756,6 @@ oprs_not_set_p (x, insn) if (load_killed_in_block_p (BLOCK_FOR_INSN (insn), INSN_CUID (insn), x, 0)) return 0; - if (mem_last_set != 0) - return 0; else return oprs_not_set_p (XEXP (x, 0), insn); @@ -2843,7 +2794,6 @@ static void mark_call (insn) rtx insn; { - mem_last_set = INSN_CUID (insn); if (! CONST_CALL_P (insn)) record_last_mem_set_info (insn); } @@ -2867,11 +2817,6 @@ mark_set (pat, insn) else if (GET_CODE (dest) == MEM) record_last_mem_set_info (insn); - if (GET_CODE (dest) == REG) - SET_BIT (reg_set_bitmap, REGNO (dest)); - else if (GET_CODE (dest) == MEM) - mem_last_set = INSN_CUID (insn); - if (GET_CODE (SET_SRC (pat)) == CALL) mark_call (insn); } @@ -2890,10 +2835,6 @@ mark_clobber (pat, insn) if (GET_CODE (clob) == REG) SET_BIT (reg_set_bitmap, REGNO (clob)); else - mem_last_set = INSN_CUID (insn); - if (GET_CODE (clob) == REG) - SET_BIT (reg_set_bitmap, REGNO (clob)); - else record_last_mem_set_info (insn); } @@ -2955,10 +2896,10 @@ alloc_rd_mem (n_blocks, n_insns) static void free_rd_mem () { - free (rd_kill); - free (rd_gen); - free (reaching_defs); - free (rd_out); + sbitmap_vector_free (rd_kill); + sbitmap_vector_free (rd_gen); + sbitmap_vector_free (reaching_defs); + sbitmap_vector_free (rd_out); } /* Add INSN to the kills of BB. REGNO, set in BB, is killed by INSN. */ @@ -3003,23 +2944,8 @@ compute_kill_rd () if (GET_CODE (insn) == CALL_INSN) { for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - { - if ((call_used_regs[regno] - && regno != STACK_POINTER_REGNUM -#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM - && regno != HARD_FRAME_POINTER_REGNUM -#endif -#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM - && ! (regno == ARG_POINTER_REGNUM - && fixed_regs[regno]) -#endif -#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED) - && ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic) -#endif - && regno != FRAME_POINTER_REGNUM) - || global_regs[regno]) - handle_rd_kill_set (insn, regno, BASIC_BLOCK (bb)); - } + if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)) + handle_rd_kill_set (insn, regno, BASIC_BLOCK (bb)); } if (GET_CODE (pat) == PARALLEL) @@ -3097,10 +3023,10 @@ alloc_avail_expr_mem (n_blocks, n_exprs) static void free_avail_expr_mem () { - free (ae_kill); - free (ae_gen); - free (ae_in); - free (ae_out); + sbitmap_vector_free (ae_kill); + sbitmap_vector_free (ae_gen); + sbitmap_vector_free (ae_in); + sbitmap_vector_free (ae_out); } /* Compute the set of available expressions generated in each basic block. */ @@ -3145,8 +3071,6 @@ expr_killed_p (x, bb) case MEM: if (load_killed_in_block_p (bb, get_max_uid () + 1, x, 0)) return 1; - if (mem_set_in_block[bb->index]) - return 1; else return expr_killed_p (XEXP (x, 0), bb); @@ -3465,7 +3389,7 @@ handle_avail_expr (insn, expr) rtx insn; struct expr *expr; { - rtx pat, insn_computes_expr; + rtx pat, insn_computes_expr, expr_set; rtx to; struct reg_set *this_reg; int found_setting, use_src; @@ -3476,6 +3400,9 @@ handle_avail_expr (insn, expr) insn_computes_expr = computing_insn (expr, insn); if (insn_computes_expr == NULL) return 0; + expr_set = single_set (insn_computes_expr); + if (!expr_set) + abort (); found_setting = 0; use_src = 0; @@ -3483,12 +3410,12 @@ handle_avail_expr (insn, expr) /* At this point we know only one computation of EXPR outside of this block reaches this insn. Now try to find a register that the expression is computed into. */ - if (GET_CODE (SET_SRC (PATTERN (insn_computes_expr))) == REG) + if (GET_CODE (SET_SRC (expr_set)) == REG) { /* This is the case when the available expression that reaches here has already been handled as an available expression. */ unsigned int regnum_for_replacing - = REGNO (SET_SRC (PATTERN (insn_computes_expr))); + = REGNO (SET_SRC (expr_set)); /* If the register was created by GCSE we can't use `reg_set_table', however we know it's set only once. */ @@ -3507,7 +3434,7 @@ handle_avail_expr (insn, expr) if (!found_setting) { unsigned int regnum_for_replacing - = REGNO (SET_DEST (PATTERN (insn_computes_expr))); + = REGNO (SET_DEST (expr_set)); /* This shouldn't happen. */ if (regnum_for_replacing >= max_gcse_regno) @@ -3526,9 +3453,9 @@ handle_avail_expr (insn, expr) { pat = PATTERN (insn); if (use_src) - to = SET_SRC (PATTERN (insn_computes_expr)); + to = SET_SRC (expr_set); else - to = SET_DEST (PATTERN (insn_computes_expr)); + to = SET_DEST (expr_set); changed = validate_change (insn, &SET_SRC (pat), to, 0); /* We should be able to ignore the return code from validate_change but @@ -3556,15 +3483,14 @@ handle_avail_expr (insn, expr) replace all uses of REGB with REGN. */ rtx new_insn; - to = gen_reg_rtx (GET_MODE (SET_DEST (PATTERN (insn_computes_expr)))); + to = gen_reg_rtx (GET_MODE (SET_DEST (expr_set))); /* Generate the new insn. */ /* ??? If the change fails, we return 0, even though we created an insn. I think this is ok. */ new_insn = emit_insn_after (gen_rtx_SET (VOIDmode, to, - SET_DEST (PATTERN - (insn_computes_expr))), + SET_DEST (expr_set)), insn_computes_expr); /* Keep block number table up to date. */ @@ -3745,10 +3671,10 @@ alloc_cprop_mem (n_blocks, n_sets) static void free_cprop_mem () { - free (cprop_pavloc); - free (cprop_absaltered); - free (cprop_avin); - free (cprop_avout); + sbitmap_vector_free (cprop_pavloc); + sbitmap_vector_free (cprop_absaltered); + sbitmap_vector_free (cprop_avin); + sbitmap_vector_free (cprop_avout); } /* For each block, compute whether X is transparent. X is either an @@ -3847,18 +3773,6 @@ compute_transp (x, indx, bmap, set_p) list_entry = XEXP (list_entry, 1); } } - if (set_p) - { - for (bb = 0; bb < n_basic_blocks; bb++) - if (mem_set_in_block[bb]) - SET_BIT (bmap[bb], indx); - } - else - { - for (bb = 0; bb < n_basic_blocks; bb++) - if (mem_set_in_block[bb]) - RESET_BIT (bmap[bb], indx); - } x = XEXP (x, 0); goto repeat; @@ -3930,56 +3844,29 @@ static int reg_use_count; This doesn't hurt anything but it will slow things down. */ static void -find_used_regs (x) - rtx x; +find_used_regs (xptr, data) + rtx *xptr; + void *data ATTRIBUTE_UNUSED; { int i, j; enum rtx_code code; const char *fmt; + rtx x = *xptr; /* repeat is used to turn tail-recursion into iteration since GCC can't do it when there's no return value. */ repeat: - if (x == 0) return; code = GET_CODE (x); - switch (code) + if (REG_P (x)) { - case REG: if (reg_use_count == MAX_USES) return; reg_use_table[reg_use_count].reg_rtx = x; reg_use_count++; - return; - - case MEM: - x = XEXP (x, 0); - goto repeat; - - case PC: - case CC0: - case CONST: - case CONST_INT: - case CONST_DOUBLE: - case SYMBOL_REF: - case LABEL_REF: - case CLOBBER: - case ADDR_VEC: - case ADDR_DIFF_VEC: - case ASM_INPUT: /*FIXME*/ - return; - - case SET: - if (GET_CODE (SET_DEST (x)) == MEM) - find_used_regs (SET_DEST (x)); - x = SET_SRC (x); - goto repeat; - - default: - break; } /* Recursively scan the operands of this expression. */ @@ -3997,11 +3884,11 @@ find_used_regs (x) goto repeat; } - find_used_regs (XEXP (x, i)); + find_used_regs (&XEXP (x, i), data); } else if (fmt[i] == 'E') for (j = 0; j < XVECLEN (x, i); j++) - find_used_regs (XVECEXP (x, i, j)); + find_used_regs (&XVECEXP (x, i, j), data); } } @@ -4017,30 +3904,20 @@ try_replace_reg (from, to, insn) int success = 0; rtx set = single_set (insn); - /* If this is a single set, try to simplify the source of the set given - our substitution. We could perhaps try this for multiple SETs, but - it probably won't buy us anything. */ - if (set != 0) + success = validate_replace_src (from, to, insn); + + /* If above failed and this is a single set, try to simplify the source of + the set given our substitution. We could perhaps try this for multiple + SETs, but it probably won't buy us anything. */ + if (!success && set != 0) { src = simplify_replace_rtx (SET_SRC (set), from, to); - /* Try this two ways: first just replace SET_SRC. If that doesn't - work and this is a PARALLEL, try to replace the whole pattern - with a new SET. */ - if (validate_change (insn, &SET_SRC (set), src, 0)) - success = 1; - else if (GET_CODE (PATTERN (insn)) == PARALLEL - && validate_change (insn, &PATTERN (insn), - gen_rtx_SET (VOIDmode, SET_DEST (set), - src), - 0)) + if (!rtx_equal_p (src, SET_SRC (set)) + && validate_change (insn, &SET_SRC (set), src, 0)) success = 1; } - /* Otherwise, try to do a global replacement within the insn. */ - if (!success) - success = validate_replace_src (from, to, insn); - /* If we've failed to do replacement, have a single SET, and don't already have a note, add a REG_EQUAL note to not lose information. */ if (!success && note == 0 && set != 0) @@ -4230,19 +4107,17 @@ cprop_insn (insn, alter_jumps) int changed = 0; rtx note; - /* Only propagate into SETs. Note that a conditional jump is a - SET with pc_rtx as the destination. */ - if (GET_CODE (insn) != INSN && GET_CODE (insn) != JUMP_INSN) + if (!INSN_P (insn)) return 0; reg_use_count = 0; - find_used_regs (PATTERN (insn)); + note_uses (&PATTERN (insn), find_used_regs, NULL); note = find_reg_equal_equiv_note (insn); /* We may win even when propagating constants into notes. */ if (note) - find_used_regs (XEXP (note, 0)); + find_used_regs (&XEXP (note, 0), NULL); for (reg_used = ®_use_table[0]; reg_use_count > 0; reg_used++, reg_use_count--) @@ -4495,24 +4370,23 @@ alloc_pre_mem (n_blocks, n_exprs) static void free_pre_mem () { - free (transp); - free (comp); + sbitmap_vector_free (transp); + sbitmap_vector_free (comp); /* ANTLOC and AE_KILL are freed just after pre_lcm finishes. */ if (pre_optimal) - free (pre_optimal); + sbitmap_vector_free (pre_optimal); if (pre_redundant) - free (pre_redundant); + sbitmap_vector_free (pre_redundant); if (pre_insert_map) - free (pre_insert_map); + sbitmap_vector_free (pre_insert_map); if (pre_delete_map) - free (pre_delete_map); - + sbitmap_vector_free (pre_delete_map); if (ae_in) - free (ae_in); + sbitmap_vector_free (ae_in); if (ae_out) - free (ae_out); + sbitmap_vector_free (ae_out); transp = comp = NULL; pre_optimal = pre_redundant = pre_insert_map = pre_delete_map = NULL; @@ -4570,9 +4444,9 @@ compute_pre_data () edge_list = pre_edge_lcm (gcse_file, n_exprs, transp, comp, antloc, ae_kill, &pre_insert_map, &pre_delete_map); - free (antloc); + sbitmap_vector_free (antloc); antloc = NULL; - free (ae_kill); + sbitmap_vector_free (ae_kill); ae_kill = NULL; free (trapping_expr); } @@ -4780,6 +4654,11 @@ insert_insn_end_bb (expr, bb, pre) if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER) abort (); + /* We only care about registers which can hold function + arguments. */ + if (! FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0)))) + continue; + SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0))); nparm_regs++; } @@ -4935,7 +4814,7 @@ pre_edge_insert (edge_list, index_map) } } - free (inserted); + sbitmap_vector_free (inserted); return did_insert; } @@ -4956,8 +4835,7 @@ pre_insert_copy_insn (expr, insn) if (!set) abort (); - new_insn = emit_insn_after (gen_rtx_SET (VOIDmode, reg, SET_DEST (set)), - insn); + new_insn = emit_insn_after (gen_move_insn (reg, SET_DEST (set)), insn); /* Keep block number table up to date. */ set_block_for_new_insns (new_insn, bb); @@ -5541,7 +5419,7 @@ delete_null_pointer_checks (f) a high connectivity will take a long time and is unlikely to be particularly useful. - In normal circumstances a cfg should have about twice has many edges + In normal circumstances a cfg should have about twice as many edges as blocks. But we do not want to punish small functions which have a couple switch statements. So we require a relatively large number of basic blocks and the ratio of edges to blocks to be high. */ @@ -5615,10 +5493,10 @@ delete_null_pointer_checks (f) free (block_reg); /* Free bitmaps. */ - free (npi.nonnull_local); - free (npi.nonnull_killed); - free (nonnull_avin); - free (nonnull_avout); + sbitmap_vector_free (npi.nonnull_local); + sbitmap_vector_free (npi.nonnull_killed); + sbitmap_vector_free (nonnull_avin); + sbitmap_vector_free (nonnull_avout); } /* Code Hoisting variables and subroutines. */ @@ -5663,16 +5541,16 @@ alloc_code_hoist_mem (n_blocks, n_exprs) static void free_code_hoist_mem () { - free (antloc); - free (transp); - free (comp); + sbitmap_vector_free (antloc); + sbitmap_vector_free (transp); + sbitmap_vector_free (comp); - free (hoist_vbein); - free (hoist_vbeout); - free (hoist_exprs); - free (transpout); + sbitmap_vector_free (hoist_vbein); + sbitmap_vector_free (hoist_vbeout); + sbitmap_vector_free (hoist_exprs); + sbitmap_vector_free (transpout); - free (dominators); + sbitmap_vector_free (dominators); } /* Compute the very busy expressions at entry/exit from each block. @@ -6583,21 +6461,8 @@ compute_store_table () if (GET_CODE (insn) == CALL_INSN) { for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if ((call_used_regs[regno] - && regno != STACK_POINTER_REGNUM -#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM - && regno != HARD_FRAME_POINTER_REGNUM -#endif -#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM - && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno]) -#endif -#if defined (PIC_OFFSET_TABLE_REGNUM) && !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED) - && ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic) -#endif - - && regno != FRAME_POINTER_REGNUM) - || global_regs[regno]) - SET_BIT (reg_set_in_block[bb], regno); + if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)) + SET_BIT (reg_set_in_block[bb], regno); } pat = PATTERN (insn); @@ -7054,19 +6919,19 @@ free_store_memory () free_ldst_mems (); if (ae_gen) - free (ae_gen); + sbitmap_vector_free (ae_gen); if (ae_kill) - free (ae_kill); + sbitmap_vector_free (ae_kill); if (transp) - free (transp); + sbitmap_vector_free (transp); if (st_antloc) - free (st_antloc); + sbitmap_vector_free (st_antloc); if (pre_insert_map) - free (pre_insert_map); + sbitmap_vector_free (pre_insert_map); if (pre_delete_map) - free (pre_delete_map); + sbitmap_vector_free (pre_delete_map); if (reg_set_in_block) - free (reg_set_in_block); + sbitmap_vector_free (reg_set_in_block); ae_gen = ae_kill = transp = st_antloc = NULL; pre_insert_map = pre_delete_map = reg_set_in_block = NULL; @@ -7095,7 +6960,7 @@ store_motion () num_stores = compute_store_table (); if (num_stores == 0) { - free (reg_set_in_block); + sbitmap_vector_free (reg_set_in_block); end_alias_analysis (); return; }