17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2010 Intel Corporation
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg * IN THE SOFTWARE.
227ec681f3Smrg *
237ec681f3Smrg * Authors:
247ec681f3Smrg *    Eric Anholt <eric@anholt.net>
257ec681f3Smrg *
267ec681f3Smrg */
277ec681f3Smrg
287ec681f3Smrg#ifndef REGISTER_ALLOCATE_INTERNAL_H
297ec681f3Smrg#define REGISTER_ALLOCATE_INTERNAL_H
307ec681f3Smrg
317ec681f3Smrg#include <stdbool.h>
327ec681f3Smrg#include "util/bitset.h"
337ec681f3Smrg#include "util/u_dynarray.h"
347ec681f3Smrg
357ec681f3Smrg#ifdef __cplusplus
367ec681f3Smrgextern "C" {
377ec681f3Smrg
387ec681f3Smrg#define class klass
397ec681f3Smrg#endif
407ec681f3Smrg
417ec681f3Smrgstruct ra_reg {
427ec681f3Smrg   BITSET_WORD *conflicts;
437ec681f3Smrg   struct util_dynarray conflict_list;
447ec681f3Smrg};
457ec681f3Smrg
467ec681f3Smrgstruct ra_regs {
477ec681f3Smrg   struct ra_reg *regs;
487ec681f3Smrg   unsigned int count;
497ec681f3Smrg
507ec681f3Smrg   struct ra_class **classes;
517ec681f3Smrg   unsigned int class_count;
527ec681f3Smrg
537ec681f3Smrg   bool round_robin;
547ec681f3Smrg};
557ec681f3Smrg
567ec681f3Smrgstruct ra_class {
577ec681f3Smrg   struct ra_regs *regset;
587ec681f3Smrg
597ec681f3Smrg   /**
607ec681f3Smrg    * Bitset indicating which registers belong to this class.
617ec681f3Smrg    *
627ec681f3Smrg    * (If bit N is set, then register N belongs to this class.)
637ec681f3Smrg    */
647ec681f3Smrg   BITSET_WORD *regs;
657ec681f3Smrg
667ec681f3Smrg   /**
677ec681f3Smrg    * Number of regs after each bit in *regs that are also conflicted by an
687ec681f3Smrg    * allocation to that reg for this class.
697ec681f3Smrg    */
707ec681f3Smrg   int contig_len;
717ec681f3Smrg
727ec681f3Smrg   /**
737ec681f3Smrg    * p(B) in Runeson/Nyström paper.
747ec681f3Smrg    *
757ec681f3Smrg    * This is "how many regs are in the set."
767ec681f3Smrg    */
777ec681f3Smrg   unsigned int p;
787ec681f3Smrg
797ec681f3Smrg   /**
807ec681f3Smrg    * q(B,C) (indexed by C, B is this register class) in
817ec681f3Smrg    * Runeson/Nyström paper.  This is "how many registers of B could
827ec681f3Smrg    * the worst choice register from C conflict with".
837ec681f3Smrg    */
847ec681f3Smrg   unsigned int *q;
857ec681f3Smrg
867ec681f3Smrg   int index;
877ec681f3Smrg};
887ec681f3Smrg
897ec681f3Smrgstruct ra_node {
907ec681f3Smrg   /** @{
917ec681f3Smrg    *
927ec681f3Smrg    * List of which nodes this node interferes with.  This should be
937ec681f3Smrg    * symmetric with the other node.
947ec681f3Smrg    */
957ec681f3Smrg   BITSET_WORD *adjacency;
967ec681f3Smrg
977ec681f3Smrg   struct util_dynarray adjacency_list;
987ec681f3Smrg   /** @} */
997ec681f3Smrg
1007ec681f3Smrg   unsigned int class;
1017ec681f3Smrg
1027ec681f3Smrg   /* Client-assigned register, if assigned, or NO_REG. */
1037ec681f3Smrg   unsigned int forced_reg;
1047ec681f3Smrg
1057ec681f3Smrg   /* Register, if assigned, or NO_REG. */
1067ec681f3Smrg   unsigned int reg;
1077ec681f3Smrg
1087ec681f3Smrg   /**
1097ec681f3Smrg    * The q total, as defined in the Runeson/Nyström paper, for all the
1107ec681f3Smrg    * interfering nodes not in the stack.
1117ec681f3Smrg    */
1127ec681f3Smrg   unsigned int q_total;
1137ec681f3Smrg
1147ec681f3Smrg   /* For an implementation that needs register spilling, this is the
1157ec681f3Smrg    * approximate cost of spilling this node.
1167ec681f3Smrg    */
1177ec681f3Smrg   float spill_cost;
1187ec681f3Smrg
1197ec681f3Smrg   /* Temporary data for the algorithm to scratch around in */
1207ec681f3Smrg   struct {
1217ec681f3Smrg      /**
1227ec681f3Smrg       * Temporary version of q_total which we decrement as things are placed
1237ec681f3Smrg       * into the stack.
1247ec681f3Smrg       */
1257ec681f3Smrg      unsigned int q_total;
1267ec681f3Smrg   } tmp;
1277ec681f3Smrg};
1287ec681f3Smrg
1297ec681f3Smrgstruct ra_graph {
1307ec681f3Smrg   struct ra_regs *regs;
1317ec681f3Smrg   /**
1327ec681f3Smrg    * the variables that need register allocation.
1337ec681f3Smrg    */
1347ec681f3Smrg   struct ra_node *nodes;
1357ec681f3Smrg   unsigned int count; /**< count of nodes. */
1367ec681f3Smrg
1377ec681f3Smrg   unsigned int alloc; /**< count of nodes allocated. */
1387ec681f3Smrg
1397ec681f3Smrg   ra_select_reg_callback select_reg_callback;
1407ec681f3Smrg   void *select_reg_callback_data;
1417ec681f3Smrg
1427ec681f3Smrg   /* Temporary data for the algorithm to scratch around in */
1437ec681f3Smrg   struct {
1447ec681f3Smrg      unsigned int *stack;
1457ec681f3Smrg      unsigned int stack_count;
1467ec681f3Smrg
1477ec681f3Smrg      /** Bit-set indicating, for each register, if it's in the stack */
1487ec681f3Smrg      BITSET_WORD *in_stack;
1497ec681f3Smrg
1507ec681f3Smrg      /** Bit-set indicating, for each register, if it pre-assigned */
1517ec681f3Smrg      BITSET_WORD *reg_assigned;
1527ec681f3Smrg
1537ec681f3Smrg      /** Bit-set indicating, for each register, the value of the pq test */
1547ec681f3Smrg      BITSET_WORD *pq_test;
1557ec681f3Smrg
1567ec681f3Smrg      /** For each BITSET_WORD, the minimum q value or ~0 if unknown */
1577ec681f3Smrg      unsigned int *min_q_total;
1587ec681f3Smrg
1597ec681f3Smrg      /*
1607ec681f3Smrg       * * For each BITSET_WORD, the node with the minimum q_total if
1617ec681f3Smrg       * min_q_total[i] != ~0.
1627ec681f3Smrg       */
1637ec681f3Smrg      unsigned int *min_q_node;
1647ec681f3Smrg
1657ec681f3Smrg      /**
1667ec681f3Smrg       * Tracks the start of the set of optimistically-colored registers in the
1677ec681f3Smrg       * stack.
1687ec681f3Smrg       */
1697ec681f3Smrg      unsigned int stack_optimistic_start;
1707ec681f3Smrg   } tmp;
1717ec681f3Smrg};
1727ec681f3Smrg
1737ec681f3Smrgbool ra_class_allocations_conflict(struct ra_class *c1, unsigned int r1,
1747ec681f3Smrg                                   struct ra_class *c2, unsigned int r2);
1757ec681f3Smrg
1767ec681f3Smrg#ifdef __cplusplus
1777ec681f3Smrg} /* extern "C" */
1787ec681f3Smrg
1797ec681f3Smrg#undef class
1807ec681f3Smrg#endif
1817ec681f3Smrg
1827ec681f3Smrg#endif /* REGISTER_ALLOCATE_INTERNAL_H  */
183