xref: /aosp_15_r20/external/mesa3d/src/util/register_allocate.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2010 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  *
23*61046927SAndroid Build Coastguard Worker  * Authors:
24*61046927SAndroid Build Coastguard Worker  *    Eric Anholt <[email protected]>
25*61046927SAndroid Build Coastguard Worker  *
26*61046927SAndroid Build Coastguard Worker  */
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker #ifndef REGISTER_ALLOCATE_H
29*61046927SAndroid Build Coastguard Worker #define REGISTER_ALLOCATE_H
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
32*61046927SAndroid Build Coastguard Worker #include "util/bitset.h"
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
35*61046927SAndroid Build Coastguard Worker extern "C" {
36*61046927SAndroid Build Coastguard Worker #endif
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker struct ra_class;
40*61046927SAndroid Build Coastguard Worker struct ra_regs;
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker struct blob;
43*61046927SAndroid Build Coastguard Worker struct blob_reader;
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker /* @{
46*61046927SAndroid Build Coastguard Worker  * Register set setup.
47*61046927SAndroid Build Coastguard Worker  *
48*61046927SAndroid Build Coastguard Worker  * This should be done once at backend initializaion, as
49*61046927SAndroid Build Coastguard Worker  * ra_set_finalize is O(r^2*c^2).  The registers may be virtual
50*61046927SAndroid Build Coastguard Worker  * registers, such as aligned register pairs that conflict with the
51*61046927SAndroid Build Coastguard Worker  * two real registers from which they are composed.
52*61046927SAndroid Build Coastguard Worker  */
53*61046927SAndroid Build Coastguard Worker struct ra_regs *ra_alloc_reg_set(void *mem_ctx, unsigned int count,
54*61046927SAndroid Build Coastguard Worker                                  bool need_conflict_lists);
55*61046927SAndroid Build Coastguard Worker void ra_set_allocate_round_robin(struct ra_regs *regs);
56*61046927SAndroid Build Coastguard Worker struct ra_class *ra_alloc_reg_class(struct ra_regs *regs);
57*61046927SAndroid Build Coastguard Worker struct ra_class *ra_alloc_contig_reg_class(struct ra_regs *regs, int contig_len);
58*61046927SAndroid Build Coastguard Worker unsigned int ra_class_index(struct ra_class *c);
59*61046927SAndroid Build Coastguard Worker void ra_add_reg_conflict(struct ra_regs *regs,
60*61046927SAndroid Build Coastguard Worker                          unsigned int r1, unsigned int r2);
61*61046927SAndroid Build Coastguard Worker void ra_add_transitive_reg_conflict(struct ra_regs *regs,
62*61046927SAndroid Build Coastguard Worker                                     unsigned int base_reg, unsigned int reg);
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker void
65*61046927SAndroid Build Coastguard Worker ra_add_transitive_reg_pair_conflict(struct ra_regs *regs,
66*61046927SAndroid Build Coastguard Worker                                     unsigned int base_reg, unsigned int reg0, unsigned int reg1);
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker void ra_make_reg_conflicts_transitive(struct ra_regs *regs, unsigned int reg);
69*61046927SAndroid Build Coastguard Worker void ra_class_add_reg(struct ra_class *c, unsigned int reg);
70*61046927SAndroid Build Coastguard Worker struct ra_class *ra_get_class_from_index(struct ra_regs *regs, unsigned int c);
71*61046927SAndroid Build Coastguard Worker void ra_set_num_conflicts(struct ra_regs *regs, unsigned int class_a,
72*61046927SAndroid Build Coastguard Worker                           unsigned int class_b, unsigned int num_conflicts);
73*61046927SAndroid Build Coastguard Worker void ra_set_finalize(struct ra_regs *regs, unsigned int **conflicts);
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker void ra_set_serialize(const struct ra_regs *regs, struct blob *blob);
76*61046927SAndroid Build Coastguard Worker struct ra_regs *ra_set_deserialize(void *mem_ctx, struct blob_reader *blob);
77*61046927SAndroid Build Coastguard Worker /** @} */
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker /** @{ Interference graph setup.
80*61046927SAndroid Build Coastguard Worker  *
81*61046927SAndroid Build Coastguard Worker  * Each interference graph node is a virtual variable in the IL.  It
82*61046927SAndroid Build Coastguard Worker  * is up to the user to ra_set_node_class() for the virtual variable,
83*61046927SAndroid Build Coastguard Worker  * and compute live ranges and ra_node_interfere() between conflicting
84*61046927SAndroid Build Coastguard Worker  * live ranges. Note that an interference *must not* be added between
85*61046927SAndroid Build Coastguard Worker  * two nodes if their classes haven't been assigned yet. The user
86*61046927SAndroid Build Coastguard Worker  * should set the class of each node before building the interference
87*61046927SAndroid Build Coastguard Worker  * graph.
88*61046927SAndroid Build Coastguard Worker  */
89*61046927SAndroid Build Coastguard Worker struct ra_graph *ra_alloc_interference_graph(struct ra_regs *regs,
90*61046927SAndroid Build Coastguard Worker                                              unsigned int count);
91*61046927SAndroid Build Coastguard Worker void ra_resize_interference_graph(struct ra_graph *g, unsigned int count);
92*61046927SAndroid Build Coastguard Worker void ra_set_node_class(struct ra_graph *g, unsigned int n, struct ra_class *c);
93*61046927SAndroid Build Coastguard Worker struct ra_class *ra_get_node_class(struct ra_graph *g, unsigned int n);
94*61046927SAndroid Build Coastguard Worker unsigned int ra_add_node(struct ra_graph *g, struct ra_class *c);
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker /** @{ Register selection callback.
97*61046927SAndroid Build Coastguard Worker  *
98*61046927SAndroid Build Coastguard Worker  * The register allocator can use either one of two built-in register
99*61046927SAndroid Build Coastguard Worker  * selection behaviors (ie. lowest-available or round-robin), or the
100*61046927SAndroid Build Coastguard Worker  * user can implement it's own selection policy by setting an register
101*61046927SAndroid Build Coastguard Worker  * selection callback.  The parameters to the callback are:
102*61046927SAndroid Build Coastguard Worker  *
103*61046927SAndroid Build Coastguard Worker  *  - n       the graph node, ie. the virtual variable to select a
104*61046927SAndroid Build Coastguard Worker  *            register for
105*61046927SAndroid Build Coastguard Worker  *  - regs    bitset of available registers to choose; this bitset
106*61046927SAndroid Build Coastguard Worker  *            contains *all* registers, but registers of different
107*61046927SAndroid Build Coastguard Worker  *            classes will not have their corresponding bit set.
108*61046927SAndroid Build Coastguard Worker  *  - data    callback data specified in ra_set_select_reg_callback()
109*61046927SAndroid Build Coastguard Worker  */
110*61046927SAndroid Build Coastguard Worker typedef unsigned int (*ra_select_reg_callback)(
111*61046927SAndroid Build Coastguard Worker       unsigned int n,        /* virtual variable to choose a physical reg for */
112*61046927SAndroid Build Coastguard Worker       BITSET_WORD *regs,     /* available physical regs to choose from */
113*61046927SAndroid Build Coastguard Worker       void *data);
114*61046927SAndroid Build Coastguard Worker 
115*61046927SAndroid Build Coastguard Worker void ra_set_select_reg_callback(struct ra_graph *g,
116*61046927SAndroid Build Coastguard Worker                                 ra_select_reg_callback callback,
117*61046927SAndroid Build Coastguard Worker                                 void *data);
118*61046927SAndroid Build Coastguard Worker void ra_add_node_interference(struct ra_graph *g,
119*61046927SAndroid Build Coastguard Worker                               unsigned int n1, unsigned int n2);
120*61046927SAndroid Build Coastguard Worker void ra_reset_node_interference(struct ra_graph *g, unsigned int n);
121*61046927SAndroid Build Coastguard Worker /** @} */
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker /** @{ Graph-coloring register allocation */
124*61046927SAndroid Build Coastguard Worker bool ra_allocate(struct ra_graph *g);
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker #define NO_REG ~0U
127*61046927SAndroid Build Coastguard Worker /**
128*61046927SAndroid Build Coastguard Worker  * Returns NO_REG for a node that has not (yet) been assigned.
129*61046927SAndroid Build Coastguard Worker  */
130*61046927SAndroid Build Coastguard Worker unsigned int ra_get_node_reg(struct ra_graph *g, unsigned int n);
131*61046927SAndroid Build Coastguard Worker void ra_set_node_reg(struct ra_graph * g, unsigned int n, unsigned int reg);
132*61046927SAndroid Build Coastguard Worker void ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost);
133*61046927SAndroid Build Coastguard Worker int ra_get_best_spill_node(struct ra_graph *g);
134*61046927SAndroid Build Coastguard Worker /** @} */
135*61046927SAndroid Build Coastguard Worker 
136*61046927SAndroid Build Coastguard Worker float ra_debug_get_node_spill_cost(struct ra_graph *g, unsigned int n);
137*61046927SAndroid Build Coastguard Worker float ra_debug_get_spill_benefit(struct ra_graph *g, unsigned int n);
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
140*61046927SAndroid Build Coastguard Worker }  // extern "C"
141*61046927SAndroid Build Coastguard Worker #endif
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker #endif /* REGISTER_ALLOCATE_H */
144