Mercurial > hg > CbC > CbC_gcc
diff gcc/regs.h @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/regs.h Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/regs.h Fri Oct 27 22:46:09 2017 +0900 @@ -1,7 +1,5 @@ /* Define per-register tables for data flow info and register allocation. - Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008, 2010 Free Software - Foundation, Inc. + Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of GCC. @@ -22,9 +20,6 @@ #ifndef GCC_REGS_H #define GCC_REGS_H -#include "machmode.h" -#include "hard-reg-set.h" - #define REG_BYTES(R) mode_size[(int) GET_MODE (R)] /* When you only have the mode of a pseudo register before it has a hard @@ -44,7 +39,7 @@ regstat_init_n_sets_and_refs from the current values of DF_REG_DEF_COUNT and DF_REG_USE_COUNT. REG_N_REFS and REG_N_SETS should only be used if a pass need to change these values in some - magical way or or the pass needs to have accurate values for these + magical way or the pass needs to have accurate values for these and is not using incremental df scanning. At the end of a pass that uses REG_N_REFS and REG_N_SETS, a call @@ -70,7 +65,7 @@ /* Indexed by n, gives number of times (REG n) is used or set. */ static inline int -REG_N_REFS(int regno) +REG_N_REFS (int regno) { return regstat_n_sets_and_refs[regno].refs; } @@ -90,8 +85,10 @@ #define SET_REG_N_SETS(N,V) (regstat_n_sets_and_refs[N].sets = V) #define INC_REG_N_SETS(N,V) (regstat_n_sets_and_refs[N].sets += V) +/* Given a REG, return TRUE if the reg is a PARM_DECL, FALSE otherwise. */ +extern bool reg_is_parm_p (rtx); -/* Functions defined in reg-stat.c. */ +/* Functions defined in regstat.c. */ extern void regstat_init_n_sets_and_refs (void); extern void regstat_free_n_sets_and_refs (void); extern void regstat_compute_ri (void); @@ -99,7 +96,7 @@ extern bitmap regstat_get_setjmp_crosses (void); extern void regstat_compute_calls_crossed (void); extern void regstat_free_calls_crossed (void); - +extern void dump_reg_info (FILE *); /* Register information indexed by register number. This structure is initialized by calling regstat_compute_ri and is destroyed by @@ -108,10 +105,7 @@ { int freq; /* # estimated frequency (REG n) is used or set */ int deaths; /* # of times (REG n) dies */ - int live_length; /* # of instructions (REG n) is live */ int calls_crossed; /* # of calls (REG n) is live across */ - int freq_calls_crossed; /* # estimated frequency (REG n) crosses call */ - int throw_calls_crossed; /* # of calls that may throw (REG n) is live across */ int basic_block; /* # of basic blocks (REG n) is used in */ }; @@ -134,9 +128,7 @@ or profile driven feedback is available and the function is never executed, frequency is always equivalent. Otherwise rescale the basic block frequency. */ -#define REG_FREQ_FROM_BB(bb) (optimize_size \ - || (flag_branch_probabilities \ - && !ENTRY_BLOCK_PTR->count) \ +#define REG_FREQ_FROM_BB(bb) (optimize_function_for_size_p (cfun) \ ? REG_FREQ_MAX \ : ((bb)->frequency * REG_FREQ_MAX / BB_FREQ_MAX)\ ? ((bb)->frequency * REG_FREQ_MAX / BB_FREQ_MAX)\ @@ -168,30 +160,6 @@ /* Indexed by N, gives number of CALL_INSNS across which (REG n) is live. */ #define REG_N_CALLS_CROSSED(N) (reg_info_p[N].calls_crossed) -#define REG_FREQ_CALLS_CROSSED(N) (reg_info_p[N].freq_calls_crossed) - -/* Indexed by N, gives number of CALL_INSNS that may throw, across which - (REG n) is live. */ - -#define REG_N_THROWING_CALLS_CROSSED(N) (reg_info_p[N].throw_calls_crossed) - -/* Total number of instructions at which (REG n) is live. The larger - this is, the less priority (REG n) gets for allocation in a hard - register (in global-alloc). This is set in df-problems.c whenever - register info is requested and remains valid for the rest of the - compilation of the function; it is used to control register - allocation. - - local-alloc.c may alter this number to change the priority. - - Negative values are special. - -1 is used to mark a pseudo reg which has a constant or memory equivalent - and is used infrequently enough that it should not get a hard register. - -2 is used to mark a pseudo reg for a parameter, when a frame pointer - is not required. global.c makes an allocno for this but does - not try to assign a hard register to it. */ - -#define REG_LIVE_LENGTH(N) (reg_info_p[N].live_length) /* Indexed by n, gives number of basic block that (REG n) is used in. If the value is REG_BLOCK_GLOBAL (-1), @@ -219,28 +187,12 @@ extern int caller_save_needed; -/* Predicate to decide whether to give a hard reg to a pseudo which - is referenced REFS times and would need to be saved and restored - around a call CALLS times. */ - -#ifndef CALLER_SAVE_PROFITABLE -#define CALLER_SAVE_PROFITABLE(REFS, CALLS) (4 * (CALLS) < (REFS)) -#endif - /* Select a register mode required for caller save of hard regno REGNO. */ #ifndef HARD_REGNO_CALLER_SAVE_MODE #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ choose_hard_reg_mode (REGNO, NREGS, false) #endif -/* Registers that get partially clobbered by a call in a given mode. - These must not be call used registers. */ -#ifndef HARD_REGNO_CALL_PART_CLOBBERED -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) 0 -#endif - -typedef unsigned short move_table[N_REG_CLASSES]; - /* Target-dependent globals. */ struct target_regs { /* For each starting hard register, the number of consecutive hard @@ -251,7 +203,7 @@ This will be a MODE_INT mode if the register can hold integers. Otherwise it will be a MODE_FLOAT or a MODE_CC mode, whichever is valid for the register. */ - enum machine_mode x_reg_raw_mode[FIRST_PSEUDO_REGISTER]; + machine_mode x_reg_raw_mode[FIRST_PSEUDO_REGISTER]; /* Vector indexed by machine mode saying whether there are regs of that mode. */ @@ -260,20 +212,9 @@ /* 1 if the corresponding class contains a register of the given mode. */ char x_contains_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE]; - /* Maximum cost of moving from a register in one class to a register - in another class. Based on TARGET_REGISTER_MOVE_COST. */ - move_table *x_move_cost[MAX_MACHINE_MODE]; - - /* Similar, but here we don't have to move if the first index is a - subset of the second so in that case the cost is zero. */ - move_table *x_may_move_in_cost[MAX_MACHINE_MODE]; - - /* Similar, but here we don't have to move if the first index is a - superset of the second so in that case the cost is zero. */ - move_table *x_may_move_out_cost[MAX_MACHINE_MODE]; - - /* Keep track of the last mode we initialized move costs for. */ - int x_last_mode_for_init_move_cost; + /* 1 if the corresponding class contains a register of the given mode + which is not global and can therefore be allocated. */ + char x_contains_allocatable_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE]; /* Record for each mode whether we can move a register directly to or from an object of that mode in memory. If we can't, we won't try @@ -291,21 +232,14 @@ #else #define this_target_regs (&default_target_regs) #endif - -#define hard_regno_nregs \ - (this_target_regs->x_hard_regno_nregs) #define reg_raw_mode \ (this_target_regs->x_reg_raw_mode) #define have_regs_of_mode \ (this_target_regs->x_have_regs_of_mode) #define contains_reg_of_mode \ (this_target_regs->x_contains_reg_of_mode) -#define move_cost \ - (this_target_regs->x_move_cost) -#define may_move_in_cost \ - (this_target_regs->x_may_move_in_cost) -#define may_move_out_cost \ - (this_target_regs->x_may_move_out_cost) +#define contains_allocatable_reg_of_mode \ + (this_target_regs->x_contains_allocatable_reg_of_mode) #define direct_load \ (this_target_regs->x_direct_load) #define direct_store \ @@ -313,28 +247,28 @@ #define float_extend_from_mem \ (this_target_regs->x_float_extend_from_mem) +/* Return the number of hard registers in (reg:MODE REGNO). */ + +ALWAYS_INLINE unsigned char +hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + return this_target_regs->x_hard_regno_nregs[regno][mode]; +} + /* Return an exclusive upper bound on the registers occupied by hard register (reg:MODE REGNO). */ static inline unsigned int -end_hard_regno (enum machine_mode mode, unsigned int regno) +end_hard_regno (machine_mode mode, unsigned int regno) { - return regno + hard_regno_nregs[regno][(int) mode]; + return regno + hard_regno_nregs (regno, mode); } -/* Likewise for hard register X. */ - -#define END_HARD_REGNO(X) end_hard_regno (GET_MODE (X), REGNO (X)) - -/* Likewise for hard or pseudo register X. */ - -#define END_REGNO(X) (HARD_REGISTER_P (X) ? END_HARD_REGNO (X) : REGNO (X) + 1) - /* Add to REGS all the registers required to store a value of mode MODE in register REGNO. */ static inline void -add_to_hard_reg_set (HARD_REG_SET *regs, enum machine_mode mode, +add_to_hard_reg_set (HARD_REG_SET *regs, machine_mode mode, unsigned int regno) { unsigned int end_regno; @@ -348,7 +282,7 @@ /* Likewise, but remove the registers. */ static inline void -remove_from_hard_reg_set (HARD_REG_SET *regs, enum machine_mode mode, +remove_from_hard_reg_set (HARD_REG_SET *regs, machine_mode mode, unsigned int regno) { unsigned int end_regno; @@ -362,15 +296,21 @@ /* Return true if REGS contains the whole of (reg:MODE REGNO). */ static inline bool -in_hard_reg_set_p (const HARD_REG_SET regs, enum machine_mode mode, +in_hard_reg_set_p (const HARD_REG_SET regs, machine_mode mode, unsigned int regno) { unsigned int end_regno; + gcc_assert (HARD_REGISTER_NUM_P (regno)); + if (!TEST_HARD_REG_BIT (regs, regno)) return false; end_regno = end_hard_regno (mode, regno); + + if (!HARD_REGISTER_NUM_P (end_regno - 1)) + return false; + while (++regno < end_regno) if (!TEST_HARD_REG_BIT (regs, regno)) return false; @@ -381,7 +321,7 @@ /* Return true if (reg:MODE REGNO) includes an element of REGS. */ static inline bool -overlaps_hard_reg_set_p (const HARD_REG_SET regs, enum machine_mode mode, +overlaps_hard_reg_set_p (const HARD_REG_SET regs, machine_mode mode, unsigned int regno) { unsigned int end_regno; @@ -397,4 +337,52 @@ return false; } +/* Like add_to_hard_reg_set, but use a REGNO/NREGS range instead of + REGNO and MODE. */ + +static inline void +add_range_to_hard_reg_set (HARD_REG_SET *regs, unsigned int regno, + int nregs) +{ + while (nregs-- > 0) + SET_HARD_REG_BIT (*regs, regno + nregs); +} + +/* Likewise, but remove the registers. */ + +static inline void +remove_range_from_hard_reg_set (HARD_REG_SET *regs, unsigned int regno, + int nregs) +{ + while (nregs-- > 0) + CLEAR_HARD_REG_BIT (*regs, regno + nregs); +} + +/* Like overlaps_hard_reg_set_p, but use a REGNO/NREGS range instead of + REGNO and MODE. */ +static inline bool +range_overlaps_hard_reg_set_p (const HARD_REG_SET set, unsigned regno, + int nregs) +{ + while (nregs-- > 0) + if (TEST_HARD_REG_BIT (set, regno + nregs)) + return true; + return false; +} + +/* Like in_hard_reg_set_p, but use a REGNO/NREGS range instead of + REGNO and MODE. */ +static inline bool +range_in_hard_reg_set_p (const HARD_REG_SET set, unsigned regno, int nregs) +{ + while (nregs-- > 0) + if (!TEST_HARD_REG_BIT (set, regno + nregs)) + return false; + return true; +} + +/* Get registers used by given function call instruction. */ +extern bool get_call_reg_set_usage (rtx_insn *insn, HARD_REG_SET *reg_set, + HARD_REG_SET default_set); + #endif /* GCC_REGS_H */