diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 04774a596f6..00236182f83 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2004-03-05 Paolo Bonzini + + * rtlanal.c: Include target.h and output.h + (rtx_cost, address_cost, default_address_cost): Move from... + * cse.c (rtx_cost, address_cost, default_address_cost): + ... this file. + * rtl.h (rtx_cost, address_cost): Move under rtlanal.c. + * Makefile.in: Adjust dependencies. + 2004-03-05 Paolo Bonzini * cse.c (cse_end_of_basic_block): Make static. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 994f0e8ceed..81c79e62476 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1568,7 +1568,7 @@ print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) real.h $(TM_P_H) rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \ $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) real.h flags.h \ - $(BASIC_BLOCK_H) $(REGS_H) + $(BASIC_BLOCK_H) $(REGS_H) output.h target.h errors.o : errors.c $(CONFIG_H) $(SYSTEM_H) errors.h $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) diff --git a/gcc/cse.c b/gcc/cse.c index 27732e4c41f..c84e761f2ba 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -812,109 +812,6 @@ notreg_cost (rtx x, enum rtx_code outer) : rtx_cost (x, outer) * 2); } -/* Return an estimate of the cost of computing rtx X. - One use is in cse, to decide which expression to keep in the hash table. - Another is in rtl generation, to pick the cheapest way to multiply. - Other uses like the latter are expected in the future. */ - -int -rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED) -{ - int i, j; - enum rtx_code code; - const char *fmt; - int total; - - if (x == 0) - return 0; - - /* Compute the default costs of certain things. - Note that targetm.rtx_costs can override the defaults. */ - - code = GET_CODE (x); - switch (code) - { - case MULT: - total = COSTS_N_INSNS (5); - break; - case DIV: - case UDIV: - case MOD: - case UMOD: - total = COSTS_N_INSNS (7); - break; - case USE: - /* Used in loop.c and combine.c as a marker. */ - total = 0; - break; - default: - total = COSTS_N_INSNS (1); - } - - switch (code) - { - case REG: - return 0; - - case SUBREG: - /* If we can't tie these modes, make this expensive. The larger - the mode, the more expensive it is. */ - if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x)))) - return COSTS_N_INSNS (2 - + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD); - break; - - default: - if ((*targetm.rtx_costs) (x, code, outer_code, &total)) - return total; - break; - } - - /* Sum the costs of the sub-rtx's, plus cost of this operation, - which is already in total. */ - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - if (fmt[i] == 'e') - total += rtx_cost (XEXP (x, i), code); - else if (fmt[i] == 'E') - for (j = 0; j < XVECLEN (x, i); j++) - total += rtx_cost (XVECEXP (x, i, j), code); - - return total; -} - -/* Return cost of address expression X. - Expect that X is properly formed address reference. */ - -int -address_cost (rtx x, enum machine_mode mode) -{ - /* The address_cost target hook does not deal with ADDRESSOF nodes. But, - during CSE, such nodes are present. Using an ADDRESSOF node which - refers to the address of a REG is a good thing because we can then - turn (MEM (ADDRESSSOF (REG))) into just plain REG. */ - - if (GET_CODE (x) == ADDRESSOF && REG_P (XEXP ((x), 0))) - return -1; - - /* We may be asked for cost of various unusual addresses, such as operands - of push instruction. It is not worthwhile to complicate writing - of the target hook by such cases. */ - - if (!memory_address_p (mode, x)) - return 1000; - - return (*targetm.address_cost) (x); -} - -/* If the target doesn't override, compute the cost as with arithmetic. */ - -int -default_address_cost (rtx x) -{ - return rtx_cost (x, MEM); -} static struct cse_reg_info * get_cse_reg_info (unsigned int regno) diff --git a/gcc/rtl.h b/gcc/rtl.h index 2e911362578..94dc136e53b 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1168,6 +1168,17 @@ enum label_kind #define SUBREG_BYTE(RTX) XCUINT (RTX, 1, SUBREG) /* in rtlanal.c */ +/* Return the right cost to give to an operation + to make the cost of the corresponding register-to-register instruction + N times that of a fast register-to-register instruction. */ +#define COSTS_N_INSNS(N) ((N) * 4) + +/* Maximum cost of an rtl expression. This value has the special meaning + not to use an rtx with this cost under any circumstances. */ +#define MAX_COST INT_MAX + +extern int rtx_cost (rtx, enum rtx_code); +extern int address_cost (rtx, enum machine_mode); extern unsigned int subreg_lsb (rtx); extern unsigned int subreg_lsb_1 (enum machine_mode, enum machine_mode, unsigned int); @@ -2099,25 +2110,10 @@ extern int no_new_pseudos; extern int rtx_to_tree_code (enum rtx_code); /* In cse.c */ -struct cse_basic_block_data; - -/* Return the right cost to give to an operation - to make the cost of the corresponding register-to-register instruction - N times that of a fast register-to-register instruction. */ -#define COSTS_N_INSNS(N) ((N) * 4) - -/* Maximum cost of an rtl expression. This value has the special meaning - not to use an rtx with this cost under any circumstances. */ -#define MAX_COST INT_MAX - -extern int rtx_cost (rtx, enum rtx_code); -extern int address_cost (rtx, enum machine_mode); extern int delete_trivially_dead_insns (rtx, int); #ifdef BUFSIZ extern int cse_main (rtx, int, int, FILE *); #endif -extern void cse_end_of_basic_block (rtx, struct cse_basic_block_data *, - int, int, int); extern void cse_condition_code_reg (void); /* In jump.c */ @@ -2238,12 +2234,10 @@ extern void print_inline_rtx (FILE *, rtx, int); /* In loop.c */ extern void init_loop (void); -extern rtx libcall_other_reg (rtx, rtx); #ifdef BUFSIZ extern void loop_optimize (rtx, FILE *, int); #endif extern void branch_target_load_optimize (rtx, bool); -extern void record_excess_regs (rtx, rtx, rtx *); /* In function.c */ extern void reposition_prologue_and_epilogue_notes (rtx); @@ -2343,7 +2337,6 @@ extern void dbr_schedule (rtx, FILE *); extern void dump_local_alloc (FILE *); #endif extern int local_alloc (void); -extern int function_invariant_p (rtx); /* In profile.c */ extern void init_branch_prob (void); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index d37bba1d807..15fc7ad2fbc 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -29,6 +29,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "hard-reg-set.h" #include "insn-config.h" #include "recog.h" +#include "target.h" +#include "output.h" #include "tm_p.h" #include "flags.h" #include "basic-block.h" @@ -3785,3 +3787,107 @@ label_is_jump_target_p (rtx label, rtx jump_insn) return false; } + +/* Return an estimate of the cost of computing rtx X. + One use is in cse, to decide which expression to keep in the hash table. + Another is in rtl generation, to pick the cheapest way to multiply. + Other uses like the latter are expected in the future. */ + +int +rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED) +{ + int i, j; + enum rtx_code code; + const char *fmt; + int total; + + if (x == 0) + return 0; + + /* Compute the default costs of certain things. + Note that targetm.rtx_costs can override the defaults. */ + + code = GET_CODE (x); + switch (code) + { + case MULT: + total = COSTS_N_INSNS (5); + break; + case DIV: + case UDIV: + case MOD: + case UMOD: + total = COSTS_N_INSNS (7); + break; + case USE: + /* Used in loop.c and combine.c as a marker. */ + total = 0; + break; + default: + total = COSTS_N_INSNS (1); + } + + switch (code) + { + case REG: + return 0; + + case SUBREG: + /* If we can't tie these modes, make this expensive. The larger + the mode, the more expensive it is. */ + if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x)))) + return COSTS_N_INSNS (2 + + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD); + break; + + default: + if ((*targetm.rtx_costs) (x, code, outer_code, &total)) + return total; + break; + } + + /* Sum the costs of the sub-rtx's, plus cost of this operation, + which is already in total. */ + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + if (fmt[i] == 'e') + total += rtx_cost (XEXP (x, i), code); + else if (fmt[i] == 'E') + for (j = 0; j < XVECLEN (x, i); j++) + total += rtx_cost (XVECEXP (x, i, j), code); + + return total; +} + +/* Return cost of address expression X. + Expect that X is properly formed address reference. */ + +int +address_cost (rtx x, enum machine_mode mode) +{ + /* The address_cost target hook does not deal with ADDRESSOF nodes. But, + during CSE, such nodes are present. Using an ADDRESSOF node which + refers to the address of a REG is a good thing because we can then + turn (MEM (ADDRESSOF (REG))) into just plain REG. */ + + if (GET_CODE (x) == ADDRESSOF && REG_P (XEXP ((x), 0))) + return -1; + + /* We may be asked for cost of various unusual addresses, such as operands + of push instruction. It is not worthwhile to complicate writing + of the target hook by such cases. */ + + if (!memory_address_p (mode, x)) + return 1000; + + return (*targetm.address_cost) (x); +} + +/* If the target doesn't override, compute the cost as with arithmetic. */ + +int +default_address_cost (rtx x) +{ + return rtx_cost (x, MEM); +}