Mercurial > hg > CbC > CbC_gcc
diff gcc/reginfo.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/reginfo.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/reginfo.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* Compute different info about registers. - Copyright (C) 1987-2018 Free Software Foundation, Inc. + Copyright (C) 1987-2020 Free Software Foundation, Inc. This file is part of GCC. @@ -43,6 +43,7 @@ #include "reload.h" #include "output.h" #include "tree-pass.h" +#include "function-abi.h" /* Maximum register number used in this function, plus one. */ @@ -50,8 +51,9 @@ /* Used to cache the results of simplifiable_subregs. SHAPE is the input parameter and SIMPLIFIABLE_REGS is the result. */ -struct simplifiable_subreg +class simplifiable_subreg { +public: simplifiable_subreg (const subreg_shape &); subreg_shape shape; @@ -65,21 +67,22 @@ struct target_regs *this_target_regs = &default_target_regs; #endif +#define call_used_regs \ + (this_target_hard_regs->x_call_used_regs) +#define regs_invalidated_by_call \ + (this_target_hard_regs->x_regs_invalidated_by_call) + /* Data for initializing fixed_regs. */ static const char initial_fixed_regs[] = FIXED_REGISTERS; /* Data for initializing call_used_regs. */ -static const char initial_call_used_regs[] = CALL_USED_REGISTERS; - #ifdef CALL_REALLY_USED_REGISTERS -/* Data for initializing call_really_used_regs. */ -static const char initial_call_really_used_regs[] = CALL_REALLY_USED_REGISTERS; +#ifdef CALL_USED_REGISTERS +#error CALL_USED_REGISTERS and CALL_REALLY_USED_REGISTERS are both defined #endif - -#ifdef CALL_REALLY_USED_REGISTERS -#define CALL_REALLY_USED_REGNO_P(X) call_really_used_regs[X] +static const char initial_call_used_regs[] = CALL_REALLY_USED_REGISTERS; #else -#define CALL_REALLY_USED_REGNO_P(X) call_used_regs[X] +static const char initial_call_used_regs[] = CALL_USED_REGISTERS; #endif /* Indexed by hard register number, contains 1 for registers @@ -91,17 +94,6 @@ /* Declaration for the global register. */ tree global_regs_decl[FIRST_PSEUDO_REGISTER]; -/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used - in dataflow more conveniently. */ -regset regs_invalidated_by_call_regset; - -/* Same information as FIXED_REG_SET but in regset form. */ -regset fixed_reg_set_regset; - -/* The bitmap_obstack is used to hold some static variables that - should not be reset after each function is compiled. */ -static bitmap_obstack persistent_obstack; - /* Used to initialize reg_alloc_order. */ #ifdef REG_ALLOC_ORDER static int initial_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER; @@ -171,10 +163,6 @@ CALL_USED_REGISTERS had the right number of initializers. */ gcc_assert (sizeof fixed_regs == sizeof initial_fixed_regs); gcc_assert (sizeof call_used_regs == sizeof initial_call_used_regs); -#ifdef CALL_REALLY_USED_REGISTERS - gcc_assert (sizeof call_really_used_regs - == sizeof initial_call_really_used_regs); -#endif #ifdef REG_ALLOC_ORDER gcc_assert (sizeof reg_alloc_order == sizeof initial_reg_alloc_order); #endif @@ -182,10 +170,6 @@ memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs); memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs); -#ifdef CALL_REALLY_USED_REGISTERS - memcpy (call_really_used_regs, initial_call_really_used_regs, - sizeof call_really_used_regs); -#endif #ifdef REG_ALLOC_ORDER memcpy (reg_alloc_order, initial_reg_alloc_order, sizeof reg_alloc_order); #endif @@ -200,9 +184,6 @@ subsequent back-end reinitialization. */ static char saved_fixed_regs[FIRST_PSEUDO_REGISTER]; static char saved_call_used_regs[FIRST_PSEUDO_REGISTER]; -#ifdef CALL_REALLY_USED_REGISTERS -static char saved_call_really_used_regs[FIRST_PSEUDO_REGISTER]; -#endif static const char *saved_reg_names[FIRST_PSEUDO_REGISTER]; static HARD_REG_SET saved_accessible_reg_set; static HARD_REG_SET saved_operand_reg_set; @@ -218,19 +199,11 @@ memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs); memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs); - /* Likewise for call_really_used_regs. */ -#ifdef CALL_REALLY_USED_REGISTERS - gcc_assert (sizeof call_really_used_regs - == sizeof saved_call_really_used_regs); - memcpy (saved_call_really_used_regs, call_really_used_regs, - sizeof call_really_used_regs); -#endif - /* And similarly for reg_names. */ gcc_assert (sizeof reg_names == sizeof saved_reg_names); memcpy (saved_reg_names, reg_names, sizeof reg_names); - COPY_HARD_REG_SET (saved_accessible_reg_set, accessible_reg_set); - COPY_HARD_REG_SET (saved_operand_reg_set, operand_reg_set); + saved_accessible_reg_set = accessible_reg_set; + saved_operand_reg_set = operand_reg_set; } /* Restore the register information. */ @@ -240,14 +213,9 @@ memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs); memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs); -#ifdef CALL_REALLY_USED_REGISTERS - memcpy (call_really_used_regs, saved_call_really_used_regs, - sizeof call_really_used_regs); -#endif - memcpy (reg_names, saved_reg_names, sizeof reg_names); - COPY_HARD_REG_SET (accessible_reg_set, saved_accessible_reg_set); - COPY_HARD_REG_SET (operand_reg_set, saved_operand_reg_set); + accessible_reg_set = saved_accessible_reg_set; + operand_reg_set = saved_operand_reg_set; } /* After switches have been processed, which perhaps alter @@ -297,8 +265,7 @@ HARD_REG_SET c; int k; - COPY_HARD_REG_SET (c, reg_class_contents[i]); - IOR_HARD_REG_SET (c, reg_class_contents[j]); + c = reg_class_contents[i] | reg_class_contents[j]; for (k = 0; k < N_REG_CLASSES; k++) if (hard_reg_set_subset_p (reg_class_contents[k], c) && !hard_reg_set_subset_p (reg_class_contents[k], @@ -320,8 +287,7 @@ HARD_REG_SET c; int k; - COPY_HARD_REG_SET (c, reg_class_contents[i]); - IOR_HARD_REG_SET (c, reg_class_contents[j]); + c = reg_class_contents[i] | reg_class_contents[j]; for (k = 0; k < N_REG_CLASSES; k++) if (hard_reg_set_subset_p (c, reg_class_contents[k])) break; @@ -362,22 +328,9 @@ /* Initialize "constant" tables. */ CLEAR_HARD_REG_SET (fixed_reg_set); - CLEAR_HARD_REG_SET (call_used_reg_set); - CLEAR_HARD_REG_SET (call_fixed_reg_set); CLEAR_HARD_REG_SET (regs_invalidated_by_call); - if (!regs_invalidated_by_call_regset) - { - bitmap_obstack_initialize (&persistent_obstack); - regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack); - } - else - CLEAR_REG_SET (regs_invalidated_by_call_regset); - if (!fixed_reg_set_regset) - fixed_reg_set_regset = ALLOC_REG_SET (&persistent_obstack); - else - CLEAR_REG_SET (fixed_reg_set_regset); - AND_HARD_REG_SET (operand_reg_set, accessible_reg_set); + operand_reg_set &= accessible_reg_set; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { /* As a special exception, registers whose class is NO_REGS are @@ -393,26 +346,10 @@ /* If a register is too limited to be treated as a register operand, then it should never be allocated to a pseudo. */ if (!TEST_HARD_REG_BIT (operand_reg_set, i)) - { - fixed_regs[i] = 1; - call_used_regs[i] = 1; - } - - /* call_used_regs must include fixed_regs. */ - gcc_assert (!fixed_regs[i] || call_used_regs[i]); -#ifdef CALL_REALLY_USED_REGISTERS - /* call_used_regs must include call_really_used_regs. */ - gcc_assert (!call_really_used_regs[i] || call_used_regs[i]); -#endif + fixed_regs[i] = 1; if (fixed_regs[i]) - { - SET_HARD_REG_BIT (fixed_reg_set, i); - SET_REGNO_REG_SET (fixed_reg_set_regset, i); - } - - if (call_used_regs[i]) - SET_HARD_REG_BIT (call_used_reg_set, i); + SET_HARD_REG_BIT (fixed_reg_set, i); /* There are a couple of fixed registers that we know are safe to exclude from being clobbered by calls: @@ -427,10 +364,7 @@ if (i == STACK_POINTER_REGNUM) ; else if (global_regs[i]) - { - SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } + SET_HARD_REG_BIT (regs_invalidated_by_call, i); else if (i == FRAME_POINTER_REGNUM) ; else if (!HARD_FRAME_POINTER_IS_FRAME_POINTER @@ -442,15 +376,12 @@ else if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED && i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i]) ; - else if (CALL_REALLY_USED_REGNO_P (i)) - { - SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } + else if (call_used_regs[i]) + SET_HARD_REG_BIT (regs_invalidated_by_call, i); } - COPY_HARD_REG_SET (call_fixed_reg_set, fixed_reg_set); - COPY_HARD_REG_SET (fixed_nonglobal_reg_set, fixed_reg_set); + SET_HARD_REG_SET (savable_regs); + fixed_nonglobal_reg_set = fixed_reg_set; /* Preserve global registers if called more than once. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) @@ -459,8 +390,6 @@ { fixed_regs[i] = call_used_regs[i] = 1; SET_HARD_REG_BIT (fixed_reg_set, i); - SET_HARD_REG_BIT (call_used_reg_set, i); - SET_HARD_REG_BIT (call_fixed_reg_set, i); } } @@ -493,6 +422,8 @@ } } } + + default_function_abi.initialize (0, regs_invalidated_by_call); } /* Compute the table of register modes. @@ -513,7 +444,7 @@ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { - reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false); + reg_raw_mode[i] = choose_hard_reg_mode (i, 1, NULL); /* If we couldn't find a valid mode, just use the previous mode if it is suitable, otherwise fall back on word_mode. */ @@ -621,10 +552,11 @@ /* Return a machine mode that is legitimate for hard reg REGNO and large enough to save nregs. If we can't find one, return VOIDmode. - If CALL_SAVED is true, only consider modes that are call saved. */ + If ABI is nonnull, only consider modes that are preserved across + calls that use ABI. */ machine_mode choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED, - unsigned int nregs, bool call_saved) + unsigned int nregs, const predefined_function_abi *abi) { unsigned int /* machine_mode */ m; machine_mode found_mode = VOIDmode, mode; @@ -638,32 +570,28 @@ FOR_EACH_MODE_IN_CLASS (mode, MODE_INT) if (hard_regno_nregs (regno, mode) == nregs && targetm.hard_regno_mode_ok (regno, mode) - && (!call_saved - || !targetm.hard_regno_call_part_clobbered (regno, mode)) + && (!abi || !abi->clobbers_reg_p (mode, regno)) && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode))) found_mode = mode; FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT) if (hard_regno_nregs (regno, mode) == nregs && targetm.hard_regno_mode_ok (regno, mode) - && (!call_saved - || !targetm.hard_regno_call_part_clobbered (regno, mode)) + && (!abi || !abi->clobbers_reg_p (mode, regno)) && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode))) found_mode = mode; FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT) if (hard_regno_nregs (regno, mode) == nregs && targetm.hard_regno_mode_ok (regno, mode) - && (!call_saved - || !targetm.hard_regno_call_part_clobbered (regno, mode)) + && (!abi || !abi->clobbers_reg_p (mode, regno)) && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode))) found_mode = mode; FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT) if (hard_regno_nregs (regno, mode) == nregs && targetm.hard_regno_mode_ok (regno, mode) - && (!call_saved - || !targetm.hard_regno_call_part_clobbered (regno, mode)) + && (!abi || !abi->clobbers_reg_p (mode, regno)) && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode))) found_mode = mode; @@ -676,8 +604,7 @@ mode = (machine_mode) m; if (hard_regno_nregs (regno, mode) == nregs && targetm.hard_regno_mode_ok (regno, mode) - && (!call_saved - || !targetm.hard_regno_call_part_clobbered (regno, mode))) + && (!abi || !abi->clobbers_reg_p (mode, regno))) return mode; } @@ -717,11 +644,11 @@ switch (call_used) { case 0: - error ("can%'t use %qs as a call-saved register", name); + error ("cannot use %qs as a call-saved register", name); break; case 1: - error ("can%'t use %qs as a call-used register", name); + error ("cannot use %qs as a call-used register", name); break; default: @@ -733,7 +660,7 @@ switch (call_used) { case 1: - error ("can%'t use %qs as a fixed register", name); + error ("cannot use %qs as a fixed register", name); break; case 0: @@ -749,10 +676,11 @@ else { fixed_regs[i] = fixed; - call_used_regs[i] = call_used; #ifdef CALL_REALLY_USED_REGISTERS if (fixed == 0) - call_really_used_regs[i] = call_used; + call_used_regs[i] = call_used; +#else + call_used_regs[i] = call_used; #endif } } @@ -803,7 +731,8 @@ if (i != STACK_POINTER_REGNUM) { SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); + for (unsigned int j = 0; j < NUM_ABI_IDS; ++j) + function_abis[j].add_full_reg_clobber (i); } /* If already fixed, nothing else to do. */ @@ -811,13 +740,8 @@ return; fixed_regs[i] = call_used_regs[i] = 1; -#ifdef CALL_REALLY_USED_REGISTERS - call_really_used_regs[i] = 1; -#endif SET_HARD_REG_BIT (fixed_reg_set, i); - SET_HARD_REG_BIT (call_used_reg_set, i); - SET_HARD_REG_BIT (call_fixed_reg_set, i); reinit_regs (); } @@ -1101,10 +1025,6 @@ reg_scan_mark_refs (XEXP (XEXP (x, 0), 0), insn); break; - case CLOBBER_HIGH: - gcc_assert (!(MEM_P (XEXP (x, 0)))); - break; - case SET: /* Count a set of the destination if it is a register. */ for (dest = SET_DEST (x); @@ -1316,14 +1236,12 @@ } if (valid_mode_changes[regno]) - AND_HARD_REG_SET (*valid_mode_changes[regno], - simplifiable_subregs (shape)); + *valid_mode_changes[regno] &= simplifiable_subregs (shape); else { valid_mode_changes[regno] = XOBNEW (&valid_mode_changes_obstack, HARD_REG_SET); - COPY_HARD_REG_SET (*valid_mode_changes[regno], - simplifiable_subregs (shape)); + *valid_mode_changes[regno] = simplifiable_subregs (shape); } }