OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / ra.h
index 52a1cc2..4fe80c8 100644 (file)
--- a/gcc/ra.h
+++ b/gcc/ra.h
@@ -32,6 +32,9 @@ struct allocno
   /* Number of calls crossed by each allocno.  */
   int calls_crossed;
 
+  /* Estimated frequency of crossing call by each allocno.  */
+  int freq_calls_crossed;
+
   /* Number of calls that might throw crossed by each allocno.  */
   int throwing_calls_crossed;
 
@@ -72,9 +75,14 @@ struct allocno
 
   HARD_REG_SET regs_someone_prefers;
 
+#ifdef EH_RETURN_DATA_REGNO
+  /* Set to true if allocno can't be allocated in an eh register.  */
+  unsigned int no_eh_reg:1;
+#endif
+
 #ifdef STACK_REGS
   /* Set to true if allocno can't be allocated in the stack register.  */
-  bool no_stack_reg;
+  unsigned int no_stack_reg:1;
 #endif
 };
 extern struct allocno *allocno;
@@ -85,49 +93,139 @@ extern struct allocno *allocno;
 
 extern int max_allocno;
 
-/* max_allocno by max_allocno array of bits, recording whether two
-   allocno's conflict (can't go in the same hardware register).
-
-   `conflicts' is symmetric after the call to mirror_conflicts.  */
-
-extern HOST_WIDE_INT *conflicts;
+/* max_allocno by max_allocno compressed triangular bit matrix,
+   recording whether two allocnos conflict (can't go in the same
+   hardware register).  */
 
-/* Number of ints required to hold max_allocno bits.
-   This is the length of a row in `conflicts'.  */
-
-extern int allocno_row_words;
+extern HOST_WIDEST_FAST_INT *conflicts;
 
 /* Indexed by (pseudo) reg number, gives the allocno, or -1
    for pseudo registers which are not to be allocated.  */
 
 extern int *reg_allocno;
 
+/* Precalculated partial bit number in the compressed triangular bit matrix.
+   For two allocnos, the final bit number is: partial_bitnum[LOW] + HIGH.  */
+
+extern HOST_WIDE_INT *partial_bitnum;
+
+/* Size in bits of the compressed triangular bit matrix.  */
+
+extern HOST_WIDE_INT max_bitnum;
+
+/* The pool to allocate the adjacency list elements from.  */
+
+extern alloc_pool adjacency_pool;
+
+/* The maximum number of neighbors stored in the neighbors vector before
+   we have to chain in another vector.  */
+
+#define ADJACENCY_VEC_LENGTH 30
+
+/* Conflict graph adjacency list.  */
+
+typedef struct adjacency_list_d
+{
+  int neighbors[ADJACENCY_VEC_LENGTH];
+  unsigned int index;
+  struct adjacency_list_d *next;
+} adjacency_t;
+
+extern adjacency_t **adjacency;
+
+/* Add NEIGHBOR to ALLOC_NO's adjacency list.  It is assumed the caller
+   has already determined that NEIGHBOR is not already neighbor by
+   checking the conflict bit matrix.  */
+
+static inline void
+add_neighbor (int alloc_no, int neighbor)
+{
+  adjacency_t *adjlist = adjacency[alloc_no];
+
+  if (adjlist == NULL || adjlist->index == ADJACENCY_VEC_LENGTH)
+    {
+      adjacency_t *new_adj = (adjacency_t *) pool_alloc (adjacency_pool);
+      new_adj->index = 0;
+      new_adj->next = adjlist;
+      adjlist = new_adj;
+      adjacency[alloc_no] = adjlist;
+    }
+
+  adjlist->neighbors[adjlist->index++] = neighbor;
+}
+
+/* Iterator for adjacency lists.  */
+
+typedef struct adjacency_iterator_d
+{
+  adjacency_t *vec;
+  unsigned int idx;
+} adjacency_iter;
+
+/* Initialize a single adjacency list iterator.  */
+
+static inline int
+adjacency_iter_init (adjacency_iter *ai, int allocno1)
+{
+  ai->vec = adjacency[allocno1];
+  ai->idx = 0;
+  return ai->vec != NULL;
+}
+
+/* Test whether we have visited all of the neighbors.  */
+
+static inline int
+adjacency_iter_done (adjacency_iter *ai)
+{
+  return ai->idx > ai->vec->index;
+}
+
+/* Advance to the next neighbor in AI.  */
+
+static inline int
+adjacency_iter_next (adjacency_iter *ai)
+{
+  unsigned int idx = ai->idx;
+  int neighbor = ai->vec->neighbors[idx++];
+  if (idx >= ai->vec->index && ai->vec->next != NULL)
+    {
+      ai->vec = ai->vec->next;
+      ai->idx = 0;
+    }
+  else
+    ai->idx = idx;
+  return neighbor;
+}
+
+/* Return the one basic block regno is used in.  If regno is used
+   in more than one basic block or if it is unknown which block it
+   is used in, return 0.  */
+
+static inline int
+regno_basic_block (int regno)
+{
+  int block = REG_BASIC_BLOCK (regno);
+  if (block < 0)
+    block = 0;
+  return block;
+}
+
 extern void global_conflicts (void);
 
 /* In global.c  */
 
-/* For any allocno set in ALLOCNO_SET, set ALLOCNO to that allocno,
-   and execute CODE.  */
-#define EXECUTE_IF_SET_IN_ALLOCNO_SET(ALLOCNO_SET, ALLOCNO, CODE)      \
-do {                                                                   \
-  int i_;                                                              \
-  int allocno_;                                                                \
-  HOST_WIDE_INT *p_ = (ALLOCNO_SET);                                   \
-                                                                       \
-  for (i_ = allocno_row_words - 1, allocno_ = 0; i_ >= 0;              \
-       i_--, allocno_ += HOST_BITS_PER_WIDE_INT)                       \
-    {                                                                  \
-      unsigned HOST_WIDE_INT word_ = (unsigned HOST_WIDE_INT) *p_++;   \
-                                                                       \
-      for ((ALLOCNO) = allocno_; word_; word_ >>= 1, (ALLOCNO)++)      \
-       {                                                               \
-         if (word_ & 1)                                                \
-           {CODE;}                                                     \
-       }                                                               \
-    }                                                                  \
-} while (0)
-
-extern void ra_init_live_subregs (bool, sbitmap *, int *, int, rtx reg);
+/* Macro to visit all of IN_ALLOCNO's neighbors.  Neighbors are
+   returned in OUT_ALLOCNO for each iteration of the loop.  */
+
+#define FOR_EACH_CONFLICT(IN_ALLOCNO, OUT_ALLOCNO, ITER)               \
+  if (!adjacency || !adjacency_iter_init (&(ITER), (IN_ALLOCNO)))      \
+    ;                                                                  \
+  else                                                                 \
+    for ((OUT_ALLOCNO) = adjacency_iter_next (&(ITER));                        \
+        !adjacency_iter_done (&(ITER));                                \
+        (OUT_ALLOCNO) = adjacency_iter_next (&(ITER)))
 
+extern void ra_init_live_subregs (bool, sbitmap *, int *, int, rtx);
+extern bool conflict_p (int, int);
 
 #endif /* GCC_RA_H */