f9c2155b7df18442f2d6ea346ac85b54e92caf74
[mesa.git] / src / freedreno / ir3 / ir3_ra.h
1 /*
2 * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 * Rob Clark <robclark@freedesktop.org>
25 */
26
27 #ifndef IR3_RA_H_
28 #define IR3_RA_H_
29
30 //#include "util/u_math.h"
31 //#include "util/register_allocate.h"
32 //#include "util/ralloc.h"
33 #include "util/bitset.h"
34
35 //#include "ir3.h"
36 //#include "ir3_compiler.h"
37
38
39 static const unsigned class_sizes[] = {
40 1, 2, 3, 4,
41 4 + 4, /* txd + 1d/2d */
42 4 + 6, /* txd + 3d */
43 };
44 #define class_count ARRAY_SIZE(class_sizes)
45
46 static const unsigned half_class_sizes[] = {
47 1, 2, 3, 4,
48 };
49 #define half_class_count ARRAY_SIZE(half_class_sizes)
50
51 /* seems to just be used for compute shaders? Seems like vec1 and vec3
52 * are sufficient (for now?)
53 */
54 static const unsigned high_class_sizes[] = {
55 1, 3,
56 };
57 #define high_class_count ARRAY_SIZE(high_class_sizes)
58
59 #define total_class_count (class_count + half_class_count + high_class_count)
60
61 /* Below a0.x are normal regs. RA doesn't need to assign a0.x/p0.x. */
62 #define NUM_REGS (4 * 48) /* r0 to r47 */
63 #define NUM_HIGH_REGS (4 * 8) /* r48 to r55 */
64 #define FIRST_HIGH_REG (4 * 48)
65 /* Number of virtual regs in a given class: */
66 #define CLASS_REGS(i) (NUM_REGS - (class_sizes[i] - 1))
67 #define HALF_CLASS_REGS(i) (NUM_REGS - (half_class_sizes[i] - 1))
68 #define HIGH_CLASS_REGS(i) (NUM_HIGH_REGS - (high_class_sizes[i] - 1))
69
70 #define HALF_OFFSET (class_count)
71 #define HIGH_OFFSET (class_count + half_class_count)
72
73 /* register-set, created one time, used for all shaders: */
74 struct ir3_ra_reg_set {
75 struct ra_regs *regs;
76 unsigned int classes[class_count];
77 unsigned int half_classes[half_class_count];
78 unsigned int high_classes[high_class_count];
79 /* maps flat virtual register space to base gpr: */
80 uint16_t *ra_reg_to_gpr;
81 /* maps cls,gpr to flat virtual register space: */
82 uint16_t **gpr_to_ra_reg;
83 };
84
85 /* additional block-data (per-block) */
86 struct ir3_ra_block_data {
87 BITSET_WORD *def; /* variables defined before used in block */
88 BITSET_WORD *use; /* variables used before defined in block */
89 BITSET_WORD *livein; /* which defs reach entry point of block */
90 BITSET_WORD *liveout; /* which defs reach exit point of block */
91 };
92
93 /* additional instruction-data (per-instruction) */
94 struct ir3_ra_instr_data {
95 /* cached instruction 'definer' info: */
96 struct ir3_instruction *defn;
97 int off, sz, cls;
98 };
99
100 /* register-assign context, per-shader */
101 struct ir3_ra_ctx {
102 struct ir3_shader_variant *v;
103 struct ir3 *ir;
104
105 struct ir3_ra_reg_set *set;
106 struct ra_graph *g;
107
108 /* Are we in the scalar assignment pass? In this pass, all larger-
109 * than-vec1 vales have already been assigned and pre-colored, so
110 * we only consider scalar values.
111 */
112 bool scalar_pass;
113
114 unsigned alloc_count;
115 /* one per class, plus one slot for arrays: */
116 unsigned class_alloc_count[total_class_count + 1];
117 unsigned class_base[total_class_count + 1];
118 unsigned instr_cnt;
119 unsigned *def, *use; /* def/use table */
120 struct ir3_ra_instr_data *instrd;
121
122 /* Mapping vreg name back to instruction, used select reg callback: */
123 struct hash_table *name_to_instr;
124
125 /* Tracking for max half/full register assigned. We don't need to
126 * track high registers.
127 *
128 * The feedback about registers used in first pass is used to choose
129 * a target register usage to round-robin between in the 2nd pass.
130 */
131 unsigned max_assigned;
132 unsigned max_half_assigned;
133
134 /* Tracking for select_reg callback */
135 unsigned start_search_reg;
136 unsigned max_target;
137 };
138
139 static inline int
140 ra_name(struct ir3_ra_ctx *ctx, struct ir3_ra_instr_data *id)
141 {
142 unsigned name;
143 debug_assert(id->cls >= 0);
144 debug_assert(id->cls < total_class_count); /* we shouldn't get arrays here.. */
145 name = ctx->class_base[id->cls] + id->defn->name;
146 debug_assert(name < ctx->alloc_count);
147 return name;
148 }
149
150 /* Get the scalar name of the n'th component of an instruction dst: */
151 static inline int
152 scalar_name(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr, unsigned n)
153 {
154 if (ctx->scalar_pass) {
155 if (instr->opc == OPC_META_SPLIT) {
156 debug_assert(n == 0); /* split results in a scalar */
157 struct ir3_instruction *src = instr->regs[1]->instr;
158 return scalar_name(ctx, src, instr->split.off);
159 } else if (instr->opc == OPC_META_COLLECT) {
160 debug_assert(n < (instr->regs_count + 1));
161 struct ir3_instruction *src = instr->regs[n + 1]->instr;
162 return scalar_name(ctx, src, 0);
163 }
164 } else {
165 debug_assert(n == 0);
166 }
167
168 return ra_name(ctx, &ctx->instrd[instr->ip]) + n;
169 }
170
171 static inline bool
172 writes_gpr(struct ir3_instruction *instr)
173 {
174 if (dest_regs(instr) == 0)
175 return false;
176 /* is dest a normal temp register: */
177 struct ir3_register *reg = instr->regs[0];
178 debug_assert(!(reg->flags & (IR3_REG_CONST | IR3_REG_IMMED)));
179 if ((reg->num == regid(REG_A0, 0)) ||
180 (reg->num == regid(REG_P0, 0)))
181 return false;
182 return true;
183 }
184
185 int ra_size_to_class(unsigned sz, bool half, bool high);
186
187 #endif /* IR3_RA_H_ */