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);
     }
 }