util/ra: Add helpers for adding nodes to an interference graph
authorJason Ekstrand <jason@jlekstrand.net>
Thu, 9 May 2019 23:53:04 +0000 (18:53 -0500)
committerJason Ekstrand <jason@jlekstrand.net>
Tue, 14 May 2019 17:30:22 +0000 (12:30 -0500)
Reviewed-by: Eric Anholt <eric@anholt.net>
src/util/register_allocate.c
src/util/register_allocate.h

index 4ab0a50..8c10741 100644 (file)
@@ -157,6 +157,8 @@ struct ra_graph {
    struct ra_node *nodes;
    unsigned int count; /**< count of nodes. */
 
+   unsigned int alloc; /**< count of nodes allocated. */
+
    unsigned int *stack;
    unsigned int stack_count;
 
@@ -423,30 +425,33 @@ ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2)
    g->nodes[n1].adjacency_count++;
 }
 
-struct ra_graph *
-ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count)
+static void
+ra_realloc_interference_graph(struct ra_graph *g, unsigned int alloc)
 {
-   struct ra_graph *g;
-   unsigned int i;
-
-   g = rzalloc(NULL, struct ra_graph);
-   g->regs = regs;
-   g->nodes = rzalloc_array(g, struct ra_node, count);
-   g->count = count;
+   if (alloc <= g->alloc)
+      return;
 
-   g->stack = rzalloc_array(g, unsigned int, count);
-
-   int bitset_count = BITSET_WORDS(count);
-   g->in_stack = rzalloc_array(g, BITSET_WORD, bitset_count);
-
-   g->reg_assigned = rzalloc_array(g, BITSET_WORD, bitset_count);
-   g->pq_test = rzalloc_array(g, BITSET_WORD, bitset_count);
-   g->min_q_total = rzalloc_array(g, unsigned int, bitset_count);
-   g->min_q_node = rzalloc_array(g, unsigned int, bitset_count);
+   /* If we always have a whole number of BITSET_WORDs, it makes it much
+    * easier to memset the top of the growing bitsets.
+    */
+   assert(g->alloc % BITSET_WORDBITS == 0);
+   alloc = ALIGN(alloc, BITSET_WORDBITS);
+
+   g->nodes = reralloc(g, g->nodes, struct ra_node, alloc);
+
+   unsigned g_bitset_count = BITSET_WORDS(g->alloc);
+   unsigned bitset_count = BITSET_WORDS(alloc);
+   /* For nodes already in the graph, we just have to grow the adjacency set */
+   for (unsigned i = 0; i < g->alloc; i++) {
+      assert(g->nodes[i].adjacency != NULL);
+      g->nodes[i].adjacency = rerzalloc(g, g->nodes[i].adjacency, BITSET_WORD,
+                                        g_bitset_count, bitset_count);
+   }
 
-   for (i = 0; i < count; i++) {
+   /* For new nodes, we have to fully initialize them */
+   for (unsigned i = g->alloc; i < alloc; i++) {
+      memset(&g->nodes[i], 0, sizeof(g->nodes[i]));
       g->nodes[i].adjacency = rzalloc_array(g, BITSET_WORD, bitset_count);
-
       g->nodes[i].adjacency_list_size = 4;
       g->nodes[i].adjacency_list =
          ralloc_array(g, unsigned int, g->nodes[i].adjacency_list_size);
@@ -456,9 +461,43 @@ ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count)
       g->nodes[i].reg = NO_REG;
    }
 
+   g->stack = reralloc(g, g->stack, unsigned int, alloc);
+   g->in_stack = rerzalloc(g, g->in_stack, BITSET_WORD,
+                           g_bitset_count, bitset_count);
+
+   g->reg_assigned = rerzalloc(g, g->reg_assigned, BITSET_WORD,
+                               g_bitset_count, bitset_count);
+   g->pq_test = rerzalloc(g, g->pq_test, BITSET_WORD,
+                          g_bitset_count, bitset_count);
+   g->min_q_total = rerzalloc(g, g->min_q_total, unsigned int,
+                              g_bitset_count, bitset_count);
+   g->min_q_node = rerzalloc(g, g->min_q_node, unsigned int,
+                             g_bitset_count, bitset_count);
+
+   g->alloc = alloc;
+}
+
+struct ra_graph *
+ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count)
+{
+   struct ra_graph *g;
+
+   g = rzalloc(NULL, struct ra_graph);
+   g->regs = regs;
+   g->count = count;
+   ra_realloc_interference_graph(g, count);
+
    return g;
 }
 
+void
+ra_resize_interference_graph(struct ra_graph *g, unsigned int count)
+{
+   g->count = count;
+   if (count > g->alloc)
+      ra_realloc_interference_graph(g, g->alloc * 2);
+}
+
 void ra_set_select_reg_callback(struct ra_graph *g,
                                 unsigned int (*callback)(struct ra_graph *g,
                                                          BITSET_WORD *regs,
@@ -476,6 +515,17 @@ ra_set_node_class(struct ra_graph *g,
    g->nodes[n].class = class;
 }
 
+unsigned int
+ra_add_node(struct ra_graph *g, unsigned int class)
+{
+   unsigned int n = g->count;
+   ra_resize_interference_graph(g, g->count + 1);
+
+   ra_set_node_class(g, n, class);
+
+   return n;
+}
+
 void
 ra_add_node_interference(struct ra_graph *g,
                          unsigned int n1, unsigned int n2)
index d3448a1..834503e 100644 (file)
@@ -74,7 +74,9 @@ void ra_set_finalize(struct ra_regs *regs, unsigned int **conflicts);
  */
 struct ra_graph *ra_alloc_interference_graph(struct ra_regs *regs,
                                              unsigned int count);
+void ra_resize_interference_graph(struct ra_graph *g, unsigned int count);
 void ra_set_node_class(struct ra_graph *g, unsigned int n, unsigned int c);
+unsigned int ra_add_node(struct ra_graph *g, unsigned int c);
 void ra_set_select_reg_callback(struct ra_graph *g,
                                 unsigned int (*callback)(struct ra_graph *g,
                                                          BITSET_WORD *regs,