diff gcc/hard-reg-set.h @ 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/hard-reg-set.h	Thu Oct 25 07:37:49 2018 +0900
+++ b/gcc/hard-reg-set.h	Thu Feb 13 11:34:05 2020 +0900
@@ -1,5 +1,5 @@
 /* Sets (bit vectors) of hard registers, and operations on them.
-   Copyright (C) 1987-2018 Free Software Foundation, Inc.
+   Copyright (C) 1987-2020 Free Software Foundation, Inc.
 
 This file is part of GCC
 
@@ -20,6 +20,8 @@
 #ifndef GCC_HARD_REG_SET_H
 #define GCC_HARD_REG_SET_H
 
+#include "array-traits.h"
+
 /* Define the type of a set of hard registers.  */
 
 /* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which
@@ -42,14 +44,88 @@
 
 #if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT
 
-#define HARD_REG_SET HARD_REG_ELT_TYPE
+typedef HARD_REG_ELT_TYPE HARD_REG_SET;
+typedef const HARD_REG_SET const_hard_reg_set;
 
 #else
 
 #define HARD_REG_SET_LONGS \
  ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1)	\
   / HOST_BITS_PER_WIDEST_FAST_INT)
-typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS];
+
+struct HARD_REG_SET
+{
+  HARD_REG_SET
+  operator~ () const
+  {
+    HARD_REG_SET res;
+    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
+      res.elts[i] = ~elts[i];
+    return res;
+  }
+
+  HARD_REG_SET
+  operator& (const HARD_REG_SET &other) const
+  {
+    HARD_REG_SET res;
+    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
+      res.elts[i] = elts[i] & other.elts[i];
+    return res;
+  }
+
+  HARD_REG_SET &
+  operator&= (const HARD_REG_SET &other)
+  {
+    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
+      elts[i] &= other.elts[i];
+    return *this;
+  }
+
+  HARD_REG_SET
+  operator| (const HARD_REG_SET &other) const
+  {
+    HARD_REG_SET res;
+    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
+      res.elts[i] = elts[i] | other.elts[i];
+    return res;
+  }
+
+  HARD_REG_SET &
+  operator|= (const HARD_REG_SET &other)
+  {
+    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
+      elts[i] |= other.elts[i];
+    return *this;
+  }
+
+  bool
+  operator== (const HARD_REG_SET &other) const
+  {
+    HARD_REG_ELT_TYPE bad = 0;
+    for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i)
+      bad |= (elts[i] ^ other.elts[i]);
+    return bad == 0;
+  }
+
+  bool
+  operator!= (const HARD_REG_SET &other) const
+  {
+    return !operator== (other);
+  }
+
+  HARD_REG_ELT_TYPE elts[HARD_REG_SET_LONGS];
+};
+typedef const HARD_REG_SET &const_hard_reg_set;
+
+template<>
+struct array_traits<HARD_REG_SET>
+{
+  typedef HARD_REG_ELT_TYPE element_type;
+  static const bool has_constant_size = true;
+  static const size_t constant_size = HARD_REG_SET_LONGS;
+  static const element_type *base (const HARD_REG_SET &x) { return x.elts; }
+  static size_t size (const HARD_REG_SET &) { return HARD_REG_SET_LONGS; }
+};
 
 #endif
 
@@ -77,28 +153,15 @@
    CLEAR_HARD_REG_SET and SET_HARD_REG_SET.
    These take just one argument.
 
-   Also define macros for copying hard reg sets:
-   COPY_HARD_REG_SET and COMPL_HARD_REG_SET.
-   These take two arguments TO and FROM; they read from FROM
-   and store into TO.  COMPL_HARD_REG_SET complements each bit.
-
-   Also define macros for combining hard reg sets:
-   IOR_HARD_REG_SET and AND_HARD_REG_SET.
-   These take two arguments TO and FROM; they read from FROM
-   and combine bitwise into TO.  Define also two variants
-   IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET
-   which use the complement of the set FROM.
-
    Also define:
 
    hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y.
-   hard_reg_set_equal_p (X, Y), which returns true if X and Y are equal.
    hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect.
    hard_reg_set_empty_p (X), which returns true if X is empty.  */
 
 #define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
 
-#ifdef HARD_REG_SET
+#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT
 
 #define SET_HARD_REG_BIT(SET, BIT)  \
  ((SET) |= HARD_CONST (1) << (BIT))
@@ -110,404 +173,87 @@
 #define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
 #define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))
 
-#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM))
-#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM))
-
-#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM))
-#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM))
-#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM))
-#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM))
-
 static inline bool
-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
+hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y)
 {
   return (x & ~y) == HARD_CONST (0);
 }
 
 static inline bool
-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
-{
-  return x == y;
-}
-
-static inline bool
-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
+hard_reg_set_intersect_p (const_hard_reg_set x, const_hard_reg_set y)
 {
   return (x & y) != HARD_CONST (0);
 }
 
 static inline bool
-hard_reg_set_empty_p (const HARD_REG_SET x)
+hard_reg_set_empty_p (const_hard_reg_set x)
 {
   return x == HARD_CONST (0);
 }
 
 #else
 
-#define SET_HARD_REG_BIT(SET, BIT)		\
-  ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]	\
-   |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))
-
-#define CLEAR_HARD_REG_BIT(SET, BIT)		\
-  ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]	\
-   &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))
-
-#define TEST_HARD_REG_BIT(SET, BIT)		\
-  (!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]	\
-      & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))))
-
-#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT
-#define CLEAR_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     scan_tp_[0] = 0;						\
-     scan_tp_[1] = 0; } while (0)
-
-#define SET_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     scan_tp_[0] = -1;						\
-     scan_tp_[1] = -1; } while (0)
-
-#define COPY_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] = scan_fp_[0];					\
-     scan_tp_[1] = scan_fp_[1]; } while (0)
-
-#define COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] = ~ scan_fp_[0];				\
-     scan_tp_[1] = ~ scan_fp_[1]; } while (0)
-
-#define AND_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] &= scan_fp_[0];				\
-     scan_tp_[1] &= scan_fp_[1]; } while (0)
-
-#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] &= ~ scan_fp_[0];				\
-     scan_tp_[1] &= ~ scan_fp_[1]; } while (0)
-
-#define IOR_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] |= scan_fp_[0];				\
-     scan_tp_[1] |= scan_fp_[1]; } while (0)
-
-#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] |= ~ scan_fp_[0];				\
-     scan_tp_[1] |= ~ scan_fp_[1]; } while (0)
-
-static inline bool
-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
+inline void
+SET_HARD_REG_BIT (HARD_REG_SET &set, unsigned int bit)
 {
-  return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0;
+  set.elts[bit / UHOST_BITS_PER_WIDE_INT]
+    |= HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT);
 }
 
-static inline bool
-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
+inline void
+CLEAR_HARD_REG_BIT (HARD_REG_SET &set, unsigned int bit)
 {
-  return x[0] == y[0] && x[1] == y[1];
-}
-
-static inline bool
-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
-{
-  return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0;
+  set.elts[bit / UHOST_BITS_PER_WIDE_INT]
+    &= ~(HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT));
 }
 
-static inline bool
-hard_reg_set_empty_p (const HARD_REG_SET x)
+inline bool
+TEST_HARD_REG_BIT (const_hard_reg_set set, unsigned int bit)
 {
-  return x[0] == 0 && x[1] == 0;
+  return (set.elts[bit / UHOST_BITS_PER_WIDE_INT]
+	  & (HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT)));
 }
 
-#else
-#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT
-#define CLEAR_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     scan_tp_[0] = 0;						\
-     scan_tp_[1] = 0;						\
-     scan_tp_[2] = 0; } while (0)
-
-#define SET_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     scan_tp_[0] = -1;						\
-     scan_tp_[1] = -1;						\
-     scan_tp_[2] = -1; } while (0)
-
-#define COPY_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] = scan_fp_[0];					\
-     scan_tp_[1] = scan_fp_[1];					\
-     scan_tp_[2] = scan_fp_[2]; } while (0)
-
-#define COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] = ~ scan_fp_[0];				\
-     scan_tp_[1] = ~ scan_fp_[1];				\
-     scan_tp_[2] = ~ scan_fp_[2]; } while (0)
-
-#define AND_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] &= scan_fp_[0];				\
-     scan_tp_[1] &= scan_fp_[1];				\
-     scan_tp_[2] &= scan_fp_[2]; } while (0)
-
-#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] &= ~ scan_fp_[0];				\
-     scan_tp_[1] &= ~ scan_fp_[1];				\
-     scan_tp_[2] &= ~ scan_fp_[2]; } while (0)
-
-#define IOR_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] |= scan_fp_[0];				\
-     scan_tp_[1] |= scan_fp_[1];				\
-     scan_tp_[2] |= scan_fp_[2]; } while (0)
-
-#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] |= ~ scan_fp_[0];				\
-     scan_tp_[1] |= ~ scan_fp_[1];				\
-     scan_tp_[2] |= ~ scan_fp_[2]; } while (0)
-
-static inline bool
-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
+inline void
+CLEAR_HARD_REG_SET (HARD_REG_SET &set)
 {
-  return ((x[0] & ~y[0]) == 0
-	  && (x[1] & ~y[1]) == 0
-	  && (x[2] & ~y[2]) == 0);
+  for (unsigned int i = 0; i < ARRAY_SIZE (set.elts); ++i)
+    set.elts[i] = 0;
 }
 
-static inline bool
-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
+inline void
+SET_HARD_REG_SET (HARD_REG_SET &set)
 {
-  return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
-}
-
-static inline bool
-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
-{
-  return ((x[0] & y[0]) != 0
-	  || (x[1] & y[1]) != 0
-	  || (x[2] & y[2]) != 0);
+  for (unsigned int i = 0; i < ARRAY_SIZE (set.elts); ++i)
+    set.elts[i] = -1;
 }
 
 static inline bool
-hard_reg_set_empty_p (const HARD_REG_SET x)
+hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y)
 {
-  return x[0] == 0 && x[1] == 0 && x[2] == 0;
-}
-
-#else
-#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT
-#define CLEAR_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     scan_tp_[0] = 0;						\
-     scan_tp_[1] = 0;						\
-     scan_tp_[2] = 0;						\
-     scan_tp_[3] = 0; } while (0)
-
-#define SET_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     scan_tp_[0] = -1;						\
-     scan_tp_[1] = -1;						\
-     scan_tp_[2] = -1;						\
-     scan_tp_[3] = -1; } while (0)
-
-#define COPY_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] = scan_fp_[0];					\
-     scan_tp_[1] = scan_fp_[1];					\
-     scan_tp_[2] = scan_fp_[2];					\
-     scan_tp_[3] = scan_fp_[3]; } while (0)
-
-#define COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] = ~ scan_fp_[0];				\
-     scan_tp_[1] = ~ scan_fp_[1];				\
-     scan_tp_[2] = ~ scan_fp_[2];				\
-     scan_tp_[3] = ~ scan_fp_[3]; } while (0)
-
-#define AND_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] &= scan_fp_[0];				\
-     scan_tp_[1] &= scan_fp_[1];				\
-     scan_tp_[2] &= scan_fp_[2];				\
-     scan_tp_[3] &= scan_fp_[3]; } while (0)
-
-#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] &= ~ scan_fp_[0];				\
-     scan_tp_[1] &= ~ scan_fp_[1];				\
-     scan_tp_[2] &= ~ scan_fp_[2];				\
-     scan_tp_[3] &= ~ scan_fp_[3]; } while (0)
-
-#define IOR_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] |= scan_fp_[0];				\
-     scan_tp_[1] |= scan_fp_[1];				\
-     scan_tp_[2] |= scan_fp_[2];				\
-     scan_tp_[3] |= scan_fp_[3]; } while (0)
-
-#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     scan_tp_[0] |= ~ scan_fp_[0];				\
-     scan_tp_[1] |= ~ scan_fp_[1];				\
-     scan_tp_[2] |= ~ scan_fp_[2];				\
-     scan_tp_[3] |= ~ scan_fp_[3]; } while (0)
-
-static inline bool
-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
-{
-  return ((x[0] & ~y[0]) == 0
-	  && (x[1] & ~y[1]) == 0
-	  && (x[2] & ~y[2]) == 0
-	  && (x[3] & ~y[3]) == 0);
-}
-
-static inline bool
-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
-{
-  return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3];
-}
-
-static inline bool
-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
-{
-  return ((x[0] & y[0]) != 0
-	  || (x[1] & y[1]) != 0
-	  || (x[2] & y[2]) != 0
-	  || (x[3] & y[3]) != 0);
+  HARD_REG_ELT_TYPE bad = 0;
+  for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i)
+    bad |= (x.elts[i] & ~y.elts[i]);
+  return bad == 0;
 }
 
 static inline bool
-hard_reg_set_empty_p (const HARD_REG_SET x)
+hard_reg_set_intersect_p (const_hard_reg_set x, const_hard_reg_set y)
 {
-  return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;
-}
-
-#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */
-
-#define CLEAR_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     int i;							\
-     for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
-       *scan_tp_++ = 0; } while (0)
-
-#define SET_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     int i;							\
-     for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
-       *scan_tp_++ = -1; } while (0)
-
-#define COPY_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     int i;							\
-     for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
-       *scan_tp_++ = *scan_fp_++; } while (0)
-
-#define COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     int i;							\
-     for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
-       *scan_tp_++ = ~ *scan_fp_++; } while (0)
-
-#define AND_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     int i;							\
-     for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
-       *scan_tp_++ &= *scan_fp_++; } while (0)
-
-#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     int i;							\
-     for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
-       *scan_tp_++ &= ~ *scan_fp_++; } while (0)
-
-#define IOR_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     int i;							\
-     for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
-       *scan_tp_++ |= *scan_fp_++; } while (0)
-
-#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\
-     const HARD_REG_ELT_TYPE *scan_fp_ = (FROM);		\
-     int i;							\
-     for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
-       *scan_tp_++ |= ~ *scan_fp_++; } while (0)
-
-static inline bool
-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
-{
-  int i;
-
-  for (i = 0; i < HARD_REG_SET_LONGS; i++)
-    if ((x[i] & ~y[i]) != 0)
-      return false;
-  return true;
+  HARD_REG_ELT_TYPE good = 0;
+  for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i)
+    good |= (x.elts[i] & y.elts[i]);
+  return good != 0;
 }
 
 static inline bool
-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
-{
-  int i;
-
-  for (i = 0; i < HARD_REG_SET_LONGS; i++)
-    if (x[i] != y[i])
-      return false;
-  return true;
-}
-
-static inline bool
-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
+hard_reg_set_empty_p (const_hard_reg_set x)
 {
-  int i;
-
-  for (i = 0; i < HARD_REG_SET_LONGS; i++)
-    if ((x[i] & y[i]) != 0)
-      return true;
-  return false;
+  HARD_REG_ELT_TYPE bad = 0;
+  for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i)
+    bad |= x.elts[i];
+  return bad == 0;
 }
-
-static inline bool
-hard_reg_set_empty_p (const HARD_REG_SET x)
-{
-  int i;
-
-  for (i = 0; i < HARD_REG_SET_LONGS; i++)
-    if (x[i] != 0)
-      return false;
-  return true;
-}
-
-#endif
-#endif
-#endif
 #endif
 
 /* Iterator for hard register sets.  */
@@ -515,7 +261,7 @@
 struct hard_reg_set_iterator
 {
   /* Pointer to the current element.  */
-  HARD_REG_ELT_TYPE *pelt;
+  const HARD_REG_ELT_TYPE *pelt;
 
   /* The length of the set.  */
   unsigned short length;
@@ -534,11 +280,11 @@
 /* The implementation of the iterator functions is fully analogous to
    the bitmap iterators.  */
 static inline void
-hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set,
+hard_reg_set_iter_init (hard_reg_set_iterator *iter, const_hard_reg_set set,
                         unsigned min, unsigned *regno)
 {
 #ifdef HARD_REG_SET_LONGS
-  iter->pelt = set;
+  iter->pelt = set.elts;
   iter->length = HARD_REG_SET_LONGS;
 #else
   iter->pelt = &set;
@@ -613,8 +359,8 @@
 
 extern char global_regs[FIRST_PSEUDO_REGISTER];
 
-struct simplifiable_subreg;
-struct subreg_shape;
+class simplifiable_subreg;
+class subreg_shape;
 
 struct simplifiable_subregs_hasher : nofree_ptr_hash <simplifiable_subreg>
 {
@@ -649,16 +395,15 @@
      a pseudo reg whose life crosses calls.  */
   char x_call_used_regs[FIRST_PSEUDO_REGISTER];
 
-  char x_call_really_used_regs[FIRST_PSEUDO_REGISTER];
-
-  /* The same info as a HARD_REG_SET.  */
-  HARD_REG_SET x_call_used_reg_set;
+  /* For targets that use reload rather than LRA, this is the set
+     of registers that we are able to save and restore around calls
+     (i.e. those for which we know a suitable mode and set of
+     load/store instructions exist).  For LRA targets it contains
+     all registers.
 
-  /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
-     a function value return register or TARGET_STRUCT_VALUE_RTX or
-     STATIC_CHAIN_REGNUM.  These are the registers that cannot hold quantities
-     across calls even if we are willing to save and restore them.  */
-  HARD_REG_SET x_call_fixed_reg_set;
+     This is legacy information and should be removed if all targets
+     switch to LRA.  */
+  HARD_REG_SET x_savable_regs;
 
   /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- but
      only if they are not merely part of that set because they are global
@@ -674,10 +419,6 @@
      with the local stack frame are safe, but scant others.  */
   HARD_REG_SET x_regs_invalidated_by_call;
 
-  /* Call used hard registers which can not be saved because there is no
-     insn for this.  */
-  HARD_REG_SET x_no_caller_save_reg_set;
-
   /* Table of register numbers in the order in which to try to use them.  */
   int x_reg_alloc_order[FIRST_PSEUDO_REGISTER];
 
@@ -730,18 +471,18 @@
   (this_target_hard_regs->x_fixed_reg_set)
 #define fixed_nonglobal_reg_set \
   (this_target_hard_regs->x_fixed_nonglobal_reg_set)
+#ifdef IN_TARGET_CODE
 #define call_used_regs \
   (this_target_hard_regs->x_call_used_regs)
-#define call_really_used_regs \
-  (this_target_hard_regs->x_call_really_used_regs)
-#define call_used_reg_set \
-  (this_target_hard_regs->x_call_used_reg_set)
-#define call_fixed_reg_set \
-  (this_target_hard_regs->x_call_fixed_reg_set)
+#endif
+#define savable_regs \
+  (this_target_hard_regs->x_savable_regs)
+#ifdef IN_TARGET_CODE
 #define regs_invalidated_by_call \
   (this_target_hard_regs->x_regs_invalidated_by_call)
-#define no_caller_save_reg_set \
-  (this_target_hard_regs->x_no_caller_save_reg_set)
+#define call_used_or_fixed_regs \
+  (regs_invalidated_by_call | fixed_reg_set)
+#endif
 #define reg_alloc_order \
   (this_target_hard_regs->x_reg_alloc_order)
 #define inv_reg_alloc_order \
@@ -770,4 +511,15 @@
 #define REG_CAN_CHANGE_MODE_P(REGN, FROM, TO)                          \
   (targetm.can_change_mode_class (FROM, TO, REGNO_REG_CLASS (REGN)))
 
+#ifdef IN_TARGET_CODE
+/* Return true if register REGNO is either fixed or call-used
+   (aka call-clobbered).  */
+
+inline bool
+call_used_or_fixed_reg_p (unsigned int regno)
+{
+  return fixed_regs[regno] || this_target_hard_regs->x_call_used_regs[regno];
+}
+#endif
+
 #endif /* ! GCC_HARD_REG_SET_H */