Mercurial > hg > CbC > CbC_gcc
diff gcc/reload.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/reload.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/reload.c Tue Mar 22 17:18:12 2011 +0900 @@ -1,6 +1,6 @@ /* Search an insn for pseudo regs that must be in hard regs and are not. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -94,7 +94,7 @@ #include "system.h" #include "coretypes.h" #include "tm.h" -#include "rtl.h" +#include "rtl-error.h" #include "tm_p.h" #include "insn-config.h" #include "expr.h" @@ -108,7 +108,6 @@ #include "flags.h" #include "output.h" #include "function.h" -#include "toplev.h" #include "params.h" #include "target.h" #include "ira.h" @@ -121,9 +120,14 @@ /* True if C is a non-empty register class that has too few registers to be safely used as a reload target class. */ -#define SMALL_REGISTER_CLASS_P(C) \ - (reg_class_size [(C)] == 1 \ - || (reg_class_size [(C)] >= 1 && CLASS_LIKELY_SPILLED_P (C))) + +static inline bool +small_register_class_p (reg_class_t rclass) +{ + return (reg_class_size [(int) rclass] == 1 + || (reg_class_size [(int) rclass] >= 1 + && targetm.class_likely_spilled_p (rclass))); +} /* All reloads of the current insn are recorded here. See reload.h for @@ -259,7 +263,7 @@ static int find_reusable_reload (rtx *, rtx, enum reg_class, enum reload_type, int, int); static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode, - enum machine_mode, enum reg_class, int, int); + enum machine_mode, reg_class_t, int, int); static int hard_reg_set_here_p (unsigned int, unsigned int, rtx); static struct decomposition decompose (rtx); static int immune_p (rtx, rtx, struct decomposition); @@ -363,7 +367,8 @@ sri.icode = CODE_FOR_nothing; sri.prev_sri = prev_sri; - rclass = targetm.secondary_reload (in_p, x, reload_class, reload_mode, &sri); + rclass = (enum reg_class) targetm.secondary_reload (in_p, x, reload_class, + reload_mode, &sri); icode = (enum insn_code) sri.icode; /* If we don't need any secondary registers, done. */ @@ -437,7 +442,7 @@ || (! in_p && rld[s_reload].secondary_out_reload == t_reload)) && ((in_p && rld[s_reload].secondary_in_icode == t_icode) || (! in_p && rld[s_reload].secondary_out_icode == t_icode)) - && (SMALL_REGISTER_CLASS_P (rclass) + && (small_register_class_p (rclass) || targetm.small_register_classes_for_mode_p (VOIDmode)) && MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed, opnum, rld[s_reload].opnum)) @@ -517,16 +522,17 @@ /* If a secondary reload is needed, return its class. If both an intermediate register and a scratch register is needed, we return the class of the intermediate register. */ -enum reg_class -secondary_reload_class (bool in_p, enum reg_class rclass, - enum machine_mode mode, rtx x) +reg_class_t +secondary_reload_class (bool in_p, reg_class_t rclass, enum machine_mode mode, + rtx x) { enum insn_code icode; secondary_reload_info sri; sri.icode = CODE_FOR_nothing; sri.prev_sri = NULL; - rclass = targetm.secondary_reload (in_p, x, rclass, mode, &sri); + rclass + = (enum reg_class) targetm.secondary_reload (in_p, x, rclass, mode, &sri); icode = (enum insn_code) sri.icode; /* If there are no secondary reloads at all, we return NO_REGS. @@ -688,7 +694,7 @@ if (bad || !good) continue; - cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass, dest_class); + cost = register_move_cost (outer, (enum reg_class) rclass, dest_class); if ((reg_class_size[rclass] > best_size && (best_cost < 0 || best_cost >= cost)) @@ -696,7 +702,7 @@ { best_class = (enum reg_class) rclass; best_size = reg_class_size[rclass]; - best_cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass, + best_cost = register_move_cost (outer, (enum reg_class) rclass, dest_class); } } @@ -747,7 +753,7 @@ || (out != 0 && MATCHES (rld[i].out, out) && (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in)))) && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out)) - && (SMALL_REGISTER_CLASS_P (rclass) + && (small_register_class_p (rclass) || targetm.small_register_classes_for_mode_p (VOIDmode)) && MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum)) return i; @@ -773,7 +779,7 @@ && GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC && MATCHES (XEXP (in, 0), rld[i].in))) && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out)) - && (SMALL_REGISTER_CLASS_P (rclass) + && (small_register_class_p (rclass) || targetm.small_register_classes_for_mode_p (VOIDmode)) && MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum)) @@ -1217,21 +1223,20 @@ /* Narrow down the class of register wanted if that is desirable on this machine for efficiency. */ { - enum reg_class preferred_class = rclass; + reg_class_t preferred_class = rclass; if (in != 0) - preferred_class = PREFERRED_RELOAD_CLASS (in, rclass); - - /* Output reloads may need analogous treatment, different in detail. */ -#ifdef PREFERRED_OUTPUT_RELOAD_CLASS + preferred_class = targetm.preferred_reload_class (in, rclass); + + /* Output reloads may need analogous treatment, different in detail. */ if (out != 0) - preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class); -#endif + preferred_class + = targetm.preferred_output_reload_class (out, preferred_class); /* Discard what the target said if we cannot do it. */ if (preferred_class != NO_REGS || (optional && type == RELOAD_FOR_OUTPUT)) - rclass = preferred_class; + rclass = (enum reg_class) preferred_class; } /* Make sure we use a class that can handle the actual pseudo @@ -1913,7 +1918,7 @@ static rtx find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc, enum machine_mode inmode, enum machine_mode outmode, - enum reg_class rclass, int for_real, int earlyclobber) + reg_class_t rclass, int for_real, int earlyclobber) { rtx in = real_in; rtx out = real_out; @@ -1956,9 +1961,9 @@ /* Narrow down the reg class, the same way push_reload will; otherwise we might find a dummy now, but push_reload won't. */ { - enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, rclass); + reg_class_t preferred_class = targetm.preferred_reload_class (in, rclass); if (preferred_class != NO_REGS) - rclass = preferred_class; + rclass = (enum reg_class) preferred_class; } /* See if OUT will do. */ @@ -2581,14 +2586,14 @@ enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS]; int no_input_reloads = 0, no_output_reloads = 0; int n_alternatives; - enum reg_class this_alternative[MAX_RECOG_OPERANDS]; + reg_class_t this_alternative[MAX_RECOG_OPERANDS]; char this_alternative_match_win[MAX_RECOG_OPERANDS]; char this_alternative_win[MAX_RECOG_OPERANDS]; char this_alternative_offmemok[MAX_RECOG_OPERANDS]; char this_alternative_earlyclobber[MAX_RECOG_OPERANDS]; int this_alternative_matches[MAX_RECOG_OPERANDS]; int swapped; - int goal_alternative[MAX_RECOG_OPERANDS]; + reg_class_t goal_alternative[MAX_RECOG_OPERANDS]; int this_alternative_number; int goal_alternative_number = 0; int operand_reloadnum[MAX_RECOG_OPERANDS]; @@ -2600,7 +2605,6 @@ char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS]; int goal_alternative_swapped; int best; - int best_small_class_operands_num; int commutative; char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS]; rtx substed_operand[MAX_RECOG_OPERANDS]; @@ -2651,7 +2655,7 @@ && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER && REG_P (SET_SRC (body)) && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER - && REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)), + && register_move_cost (GET_MODE (SET_SRC (body)), REGNO_REG_CLASS (REGNO (SET_SRC (body))), REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2) return 0; @@ -2926,7 +2930,6 @@ all the operands together against the register constraints. */ best = MAX_RECOG_OPERANDS * 2 + 600; - best_small_class_operands_num = 0; swapped = 0; goal_alternative_swapped = 0; @@ -3468,7 +3471,8 @@ /* If this operand could be handled with a reg, and some reg is allowed, then this operand can be handled. */ - if (winreg && this_alternative[i] != NO_REGS) + if (winreg && this_alternative[i] != NO_REGS + && (win || !class_only_fixed_regs[this_alternative[i]])) badop = 0; /* Record which operands fit this alternative. */ @@ -3500,7 +3504,8 @@ precisely the same as in the code below that calls force_const_mem. */ if (CONST_POOL_OK_P (operand) - && ((PREFERRED_RELOAD_CLASS (operand, this_alternative[i]) + && ((targetm.preferred_reload_class (operand, + this_alternative[i]) == NO_REGS) || no_input_reloads) && operand_mode[i] != VOIDmode) @@ -3528,17 +3533,15 @@ if (! CONSTANT_P (operand) && this_alternative[i] != NO_REGS) { - if (PREFERRED_RELOAD_CLASS (operand, this_alternative[i]) + if (targetm.preferred_reload_class (operand, this_alternative[i]) == NO_REGS) reject = 600; -#ifdef PREFERRED_OUTPUT_RELOAD_CLASS if (operand_type[i] == RELOAD_FOR_OUTPUT - && (PREFERRED_OUTPUT_RELOAD_CLASS (operand, - this_alternative[i]) + && (targetm.preferred_output_reload_class (operand, + this_alternative[i]) == NO_REGS)) reject = 600; -#endif } /* We prefer to reload pseudos over reloading other things, @@ -3587,7 +3590,7 @@ && this_alternative[i] != NO_REGS && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD && reg_class_size [(int) preferred_class[i]] > 0 - && ! SMALL_REGISTER_CLASS_P (preferred_class[i])) + && ! small_register_class_p (preferred_class[i])) { if (! reg_class_subset_p (this_alternative[i], preferred_class[i])) @@ -3645,7 +3648,7 @@ { /* If the output is in a non-empty few-regs class, it's costly to reload it, so reload the input instead. */ - if (SMALL_REGISTER_CLASS_P (this_alternative[i]) + if (small_register_class_p (this_alternative[i]) && (REG_P (recog_data.operand[j]) || GET_CODE (recog_data.operand[j]) == SUBREG)) { @@ -3712,27 +3715,7 @@ record it as the chosen goal for reloading. */ if (! bad) { - bool change_p = false; - int small_class_operands_num = 0; - - if (best >= losers) - { - for (i = 0; i < noperands; i++) - small_class_operands_num - += SMALL_REGISTER_CLASS_P (this_alternative[i]) ? 1 : 0; - if (best > losers - || (best == losers - /* If the cost of the reloads is the same, - prefer alternative which requires minimal - number of small register classes for the - operands. This improves chances of reloads - for insn requiring small register - classes. */ - && (small_class_operands_num - < best_small_class_operands_num))) - change_p = true; - } - if (change_p) + if (best > losers) { for (i = 0; i < noperands; i++) { @@ -3748,7 +3731,6 @@ } goal_alternative_swapped = swapped; best = losers; - best_small_class_operands_num = small_class_operands_num; goal_alternative_number = this_alternative_number; goal_earlyclobber = this_earlyclobber; } @@ -3930,8 +3912,7 @@ } if (CONST_POOL_OK_P (op) - && ((PREFERRED_RELOAD_CLASS (op, - (enum reg_class) goal_alternative[i]) + && ((targetm.preferred_reload_class (op, goal_alternative[i]) == NO_REGS) || no_input_reloads) && mode != VOIDmode) @@ -4109,7 +4090,7 @@ /* If this is only for an output, the optional reload would not actually cause us to use a register now, just note that something is stored here. */ - && ((enum reg_class) goal_alternative[i] != NO_REGS + && (goal_alternative[i] != NO_REGS || modified[i] == RELOAD_WRITE) && ! no_input_reloads /* An optional output reload might allow to delete INSN later. @@ -4183,8 +4164,7 @@ if ((MEM_P (operand) || (REG_P (operand) && REGNO (operand) >= FIRST_PSEUDO_REGISTER)) - && ((enum reg_class) goal_alternative[goal_alternative_matches[i]] - != NO_REGS)) + && (goal_alternative[goal_alternative_matches[i]] != NO_REGS)) operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]] = push_reload (recog_data.operand[goal_alternative_matches[i]], recog_data.operand[i], @@ -5086,8 +5066,13 @@ && REG_P (XEXP (ad, 0)) && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER && CONST_INT_P (XEXP (ad, 1)) - && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, PLUS, - CONST_INT)) + && (regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, PLUS, + CONST_INT) + /* Similarly, if we were to reload the base register and the + mem+offset address is still invalid, then we want to reload + the whole address, not just the base register. */ + || ! maybe_memory_address_addr_space_p + (mode, ad, as, &(XEXP (ad, 0))))) { /* Unshare the MEM rtx so we can safely alter it. */ @@ -5099,7 +5084,9 @@ loc = &XEXP (*loc, 0); } - if (double_reg_address_ok) + if (double_reg_address_ok + && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, + PLUS, CONST_INT)) { /* Unshare the sum as well. */ *loc = ad = copy_rtx (ad); @@ -5172,7 +5159,7 @@ if ((regno_ok_for_base_p (REGNO (operand), mode, inner_code, GET_CODE (addend)) || operand == frame_pointer_rtx -#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM +#if !HARD_FRAME_POINTER_IS_FRAME_POINTER || operand == hard_frame_pointer_rtx #endif #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM @@ -5832,8 +5819,7 @@ rtx equiv = (MEM_P (XEXP (x, 0)) ? XEXP (x, 0) : reg_equiv_mem[regno]); - int icode - = (int) optab_handler (add_optab, GET_MODE (x))->insn_code; + int icode = (int) optab_handler (add_optab, GET_MODE (x)); if (insn && NONJUMP_INSN_P (insn) && equiv && memory_operand (equiv, GET_MODE (equiv)) #ifdef HAVE_cc0 @@ -6064,7 +6050,7 @@ { if (CONSTANT_P (x) && (! LEGITIMATE_CONSTANT_P (x) - || PREFERRED_RELOAD_CLASS (x, rclass) == NO_REGS)) + || targetm.preferred_reload_class (x, rclass) == NO_REGS)) { x = force_const_mem (mode, x); find_reloads_address (mode, &x, XEXP (x, 0), &XEXP (x, 0), @@ -6074,7 +6060,8 @@ else if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)) && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1)) - || PREFERRED_RELOAD_CLASS (XEXP (x, 1), rclass) == NO_REGS)) + || targetm.preferred_reload_class (XEXP (x, 1), rclass) + == NO_REGS)) { rtx tem; @@ -7337,7 +7324,7 @@ /* These functions are used to print the variables set by 'find_reloads' */ -void +DEBUG_FUNCTION void debug_reload_to_stream (FILE *f) { int r; @@ -7432,7 +7419,7 @@ } } -void +DEBUG_FUNCTION void debug_reload (void) { debug_reload_to_stream (stderr);