1 /*
2 * Copyright © 2024 Imagination Technologies Ltd.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 #ifndef PCO_INTERNAL_H
8 #define PCO_INTERNAL_H
9
10 /**
11 * \file pco_internal.h
12 *
13 * \brief PCO internal header.
14 */
15
16 #include "compiler/spirv/nir_spirv.h"
17 #include "hwdef/rogue_hw_utils.h"
18 #include "pco.h"
19 #include "pco_common.h"
20 #include "pco_data.h"
21 #include "pco_ops.h"
22 #include "spirv/nir_spirv.h"
23 #include "util/compiler.h"
24 #include "util/hash_table.h"
25 #include "util/macros.h"
26 #include "util/list.h"
27 #include "util/u_dynarray.h"
28 #include "util/u_math.h"
29
30 #include <assert.h>
31 #include <stdbool.h>
32 #include <stdint.h>
33
34 /** PCO compiler context. */
35 typedef struct _pco_ctx {
36 /** Device information. */
37 const struct pvr_device_info *dev_info;
38
39 /** Device-specific NIR options. */
40 nir_shader_compiler_options nir_options;
41
42 /** Device-specific SPIR-V to NIR options. */
43 struct spirv_to_nir_options spirv_options;
44 } pco_ctx;
45
46 void pco_setup_spirv_options(const struct pvr_device_info *dev_info,
47 struct spirv_to_nir_options *spirv_options);
48 void pco_setup_nir_options(const struct pvr_device_info *dev_info,
49 nir_shader_compiler_options *nir_options);
50
51 /* Debug. */
52 enum pco_debug {
53 PCO_DEBUG_VAL_SKIP = BITFIELD64_BIT(0),
54 PCO_DEBUG_REINDEX = BITFIELD64_BIT(1),
55 };
56
57 extern uint64_t pco_debug;
58
59 #define PCO_DEBUG(flag) unlikely(pco_debug &(PCO_DEBUG_##flag))
60
61 enum pco_debug_print {
62 PCO_DEBUG_PRINT_VS = BITFIELD64_BIT(0),
63 PCO_DEBUG_PRINT_FS = BITFIELD64_BIT(1),
64 PCO_DEBUG_PRINT_CS = BITFIELD64_BIT(2),
65 PCO_DEBUG_PRINT_ALL = PCO_DEBUG_PRINT_VS | PCO_DEBUG_PRINT_FS |
66 PCO_DEBUG_PRINT_CS,
67 PCO_DEBUG_PRINT_INTERNAL = BITFIELD64_BIT(3),
68 PCO_DEBUG_PRINT_PASSES = BITFIELD64_BIT(4),
69 PCO_DEBUG_PRINT_NIR = BITFIELD64_BIT(5),
70 PCO_DEBUG_PRINT_BINARY = BITFIELD64_BIT(6),
71 PCO_DEBUG_PRINT_VERBOSE = BITFIELD64_BIT(7),
72 PCO_DEBUG_PRINT_RA = BITFIELD64_BIT(8),
73 };
74
75 extern uint64_t pco_debug_print;
76
77 extern const char *pco_skip_passes;
78
79 #define PCO_DEBUG_PRINT(flag) \
80 unlikely(pco_debug_print &(PCO_DEBUG_PRINT_##flag))
81
82 extern bool pco_color;
83
84 void pco_debug_init(void);
85
86 typedef struct _pco_cf_node pco_cf_node;
87 typedef struct _pco_func pco_func;
88 typedef struct _pco_block pco_block;
89 typedef struct _pco_instr pco_instr;
90
91 #define PCO_REF_VAL_BITS (32U)
92
93 #define PCO_REF_IDX_NUM_BITS (2U)
94 #define PCO_REF_IDX_OFFSET_BITS (8U)
95 #define PCO_REF_IDX_PAD_BITS \
96 (PCO_REF_VAL_BITS - (PCO_REF_IDX_NUM_BITS + PCO_REF_IDX_OFFSET_BITS))
97
98 /** PCO reference index. */
99 typedef struct PACKED _pco_ref {
100 /** Reference value. */
101 union PACKED {
102 unsigned val : PCO_REF_VAL_BITS;
103
104 struct PACKED {
105 unsigned num : PCO_REF_IDX_NUM_BITS; /** Index register number. */
106 unsigned offset : PCO_REF_IDX_OFFSET_BITS; /** Offset. */
107 unsigned _pad : PCO_REF_IDX_PAD_BITS;
108 } idx_reg;
109 };
110
111 /** Source/destination modifiers. */
112 bool oneminus : 1;
113 bool clamp : 1;
114 bool flr : 1;
115 bool abs : 1;
116 bool neg : 1;
117 enum pco_elem elem : 4; /** .e0.e1.e2.e3 */
118
119 enum pco_dtype dtype : 2; /** Reference data-type. */
120 unsigned chans : 10; /** Number of channels (1-1024). */
121 enum pco_bits bits : 3; /** Bit width. */
122 enum pco_ref_type type : 3; /** Reference type. */
123 enum pco_reg_class reg_class : 4; /** Register class. */
124
125 unsigned _pad : 1;
126 } pco_ref;
127 static_assert(sizeof(pco_ref) == 8, "sizeof(pco_ref) != 8");
128
129 /** PCO phi source. */
130 typedef struct _pco_phi_src {
131 struct list_head link; /** Link in pco_instr::phi_srcs. */
132
133 pco_block *pred; /** Predecessor block. */
134 pco_ref ref; /** Source reference. */
135 } pco_phi_src;
136
137 /** PCO instruction group. */
138 typedef struct _pco_igrp {
139 struct list_head link; /** Link in pco_block::instrs. */
140 pco_block *parent_block; /** Basic block containing the igrp. */
141 pco_func *parent_func; /** Parent function. */
142
143 pco_instr *instrs[_PCO_OP_PHASE_COUNT]; /** Instruction/group list. */
144
145 /** Instruction group header. */
146 struct {
147 unsigned da;
148 unsigned length;
149 union {
150 enum pco_oporg oporg;
151 enum pco_opcnt opcnt;
152 };
153 bool olchk;
154 bool w1p;
155 bool w0p;
156 enum pco_cc cc;
157 enum pco_alutype alutype;
158 union {
159 struct {
160 bool end;
161 bool atom;
162 unsigned rpt;
163 };
164 struct {
165 unsigned miscctl;
166 enum pco_ctrlop ctrlop;
167 };
168 };
169 } hdr;
170
171 struct {
172 pco_ref s[ROGUE_MAX_ALU_INPUTS];
173 } srcs;
174
175 struct {
176 pco_ref is[ROGUE_MAX_ALU_INTERNAL_SOURCES];
177 } iss;
178
179 struct {
180 pco_ref w[ROGUE_MAX_ALU_OUTPUTS];
181 } dests;
182
183 struct {
184 enum pco_igrp_hdr_variant hdr;
185 union {
186 enum pco_main_variant main;
187 enum pco_backend_variant backend;
188 enum pco_bitwise_variant bitwise;
189 enum pco_ctrl_variant ctrl;
190 } instr[_PCO_OP_PHASE_COUNT];
191 enum pco_src_variant lower_src;
192 enum pco_src_variant upper_src;
193 enum pco_iss_variant iss;
194 enum pco_dst_variant dest;
195 } variant;
196
197 struct {
198 struct {
199 unsigned hdr;
200 unsigned lower_srcs;
201 unsigned upper_srcs;
202 unsigned iss;
203 unsigned dests;
204 unsigned instrs[_PCO_OP_PHASE_COUNT];
205 unsigned word_padding;
206 unsigned align_padding;
207 unsigned total;
208 } len;
209
210 unsigned offset;
211 } enc;
212
213 unsigned index; /** Igrp index. */
214 char *comment; /** Comment string. */
215
216 } pco_igrp;
217
218 /** PCO instruction. */
219 typedef struct _pco_instr {
220 union {
221 struct {
222 struct list_head link; /** Link in pco_block::instrs. */
223 pco_block *parent_block; /** Basic block containing the instruction. */
224 };
225
226 pco_igrp *parent_igrp; /** Igrp containing the instruction. */
227 };
228
229 pco_func *parent_func; /** Parent function. */
230
231 enum pco_op op;
232
233 unsigned num_dests;
234 pco_ref *dest;
235 unsigned num_srcs;
236 pco_ref *src;
237
238 union {
239 struct list_head phi_srcs;
240 pco_cf_node *target_cf_node;
241 };
242
243 /** Instruction flags/modifiers. */
244 uint32_t mod[_PCO_OP_MAX_MODS];
245
246 unsigned index; /** Instruction index. */
247 char *comment; /** Comment string. */
248 } pco_instr;
249
250 /** PCO control-flow node type. */
251 enum pco_cf_node_type {
252 PCO_CF_NODE_TYPE_BLOCK,
253 PCO_CF_NODE_TYPE_IF,
254 PCO_CF_NODE_TYPE_LOOP,
255 PCO_CF_NODE_TYPE_FUNC,
256 };
257
258 /** PCO control-flow node. */
259 typedef struct _pco_cf_node {
260 struct list_head link; /** Link in lists of pco_cf_nodes. */
261 enum pco_cf_node_type type; /** CF node type. */
262 struct _pco_cf_node *parent; /** Parent cf node. */
263 bool flag; /** Implementation-defined flag. */
264 } pco_cf_node;
265
266 /** PCO basic block. */
267 typedef struct _pco_block {
268 pco_cf_node cf_node; /** Control flow node. */
269 pco_func *parent_func; /** Parent function. */
270 struct list_head instrs; /** Instruction/group list. */
271 unsigned index; /** Block index. */
272 } pco_block;
273
274 /** PCO if cf construct. */
275 typedef struct _pco_if {
276 pco_cf_node cf_node; /** CF node. */
277 pco_func *parent_func; /** Parent function. */
278 pco_ref cond; /** If condition. */
279 struct list_head then_body; /** List of pco_cf_nodes for if body. */
280 struct list_head else_body; /** List of pco_cf_nodes for else body. */
281 unsigned index; /** If index. */
282 } pco_if;
283
284 /** PCO loop cf construct. */
285 typedef struct _pco_loop {
286 pco_cf_node cf_node; /** CF node. */
287 pco_func *parent_func; /** Parent function. */
288 struct list_head body; /** List of pco_cf_nodes for loop body. */
289 unsigned index; /** Loop index. */
290 } pco_loop;
291
292 #define VEC_USER_MULTI ((void *)(~0ULL))
293
294 /** PCO vector information. */
295 typedef struct _pco_vec_info {
296 pco_instr *instr; /** Vector producer. */
297 pco_instr **comps; /** Array of vector components. */
298 pco_instr *vec_user; /** Vector user, or none, or multi. */
299 } pco_vec_info;
300
301 /** PCO function. */
302 typedef struct _pco_func {
303 struct list_head link; /** Link in pco_shader::funcs. */
304 pco_cf_node cf_node; /** Control flow node. */
305
306 pco_shader *parent_shader; /** Shader containing the function. */
307
308 enum pco_func_type type; /** Function type. */
309 unsigned index; /** Function index. */
310 const char *name; /** Function name. */
311
312 struct list_head body; /** List of pco_cf_nodes for function body. */
313
314 unsigned num_params;
315 pco_ref *params;
316
317 struct hash_table_u64 *vec_infos;
318
319 unsigned next_ssa; /** Next SSA node index. */
320 unsigned next_instr; /** Next instruction index. */
321 unsigned next_igrp; /** Next igrp index. */
322 unsigned next_block; /** Next block index. */
323 unsigned next_if; /** Next if index. */
324 unsigned next_loop; /** Next loop index. */
325
326 unsigned temps; /** Number of temps allocated. */
327
328 unsigned enc_offset; /** Encoding offset. */
329 } pco_func;
330
331 /** PCO shader. */
332 typedef struct _pco_shader {
333 pco_ctx *ctx; /** Compiler context. */
334 nir_shader *nir; /** Source NIR shader. */
335
336 gl_shader_stage stage; /** Shader stage. */
337 const char *name; /** Shader name. */
338 bool is_internal; /** Whether this is an internal shader. */
339 bool is_grouped; /** Whether the shader uses igrps. */
340
341 struct list_head funcs; /** List of functions. */
342 unsigned next_func; /** Next function index. */
343
344 pco_data data; /** Shader data. */
345
346 struct {
347 struct util_dynarray buf; /** Shader binary. */
348
349 /** Binary patch info. */
350 unsigned num_patches;
351 struct {
352 unsigned offset;
353 } * patch;
354 } binary;
355 } pco_shader;
356
357 /** Op info. */
358 struct pco_op_info {
359 const char *str; /** Op name string. */
360 unsigned num_dests; /** Number of dests. */
361 unsigned num_srcs; /** Number of sources. */
362 uint64_t mods; /** Supported mods. */
363 uint8_t mod_map[_PCO_OP_MOD_COUNT]; /** Index into pco_instr::mod. */
364 uint64_t dest_mods[_PCO_OP_MAX_DESTS]; /** Supported dest mods. */
365 uint64_t src_mods[_PCO_OP_MAX_SRCS]; /** Supported source mods. */
366 enum pco_op_type type; /** Op type. */
367 bool has_target_cf_node; /** Set if op has a cf-node as a target. */
368 };
369 extern const struct pco_op_info pco_op_info[_PCO_OP_COUNT];
370
371 /** Op mod info. */
372 struct pco_op_mod_info {
373 bool print_early : 1; /** Set if printed before the op. */
374 bool is_bitset : 1; /** Set if type is an enum bitset. */
375 enum pco_mod_type type; /** Datatype. */
376 union {
377 const char *str; /** Mod name. */
378 const char **strs; /** Mod names (enums). */
379 };
380 uint32_t nzdefault; /** Default value if non-zero. */
381 };
382 extern const struct pco_op_mod_info pco_op_mod_info[_PCO_OP_MOD_COUNT];
383
384 /** Reference mod info. */
385 struct pco_ref_mod_info {
386 bool is_bitset : 1; /** Set if type is an enum bitset. */
387 enum pco_mod_type type; /** Datatype. */
388 union {
389 const char *str; /** Mod name. */
390 const char **strs; /** Mod names (enums). */
391 };
392 };
393 extern const struct pco_ref_mod_info pco_ref_mod_info[_PCO_REF_MOD_COUNT];
394
395 pco_shader *pco_shader_create(pco_ctx *ctx, nir_shader *nir, void *mem_ctx);
396 pco_func *pco_func_create(pco_shader *shader,
397 enum pco_func_type type,
398 unsigned num_params);
399 pco_block *pco_block_create(pco_func *func);
400 pco_if *pco_if_create(pco_func *func);
401 pco_loop *pco_loop_create(pco_func *func);
402 pco_instr *pco_instr_create(pco_func *func,
403 enum pco_op op,
404 unsigned num_dests,
405 unsigned num_srcs);
406 pco_igrp *pco_igrp_create(pco_func *func);
407
408 void pco_instr_delete(pco_instr *instr);
409
410 /* Cast helpers. */
411
412 /* CF nodes. */
413 #define PCO_DEFINE_CAST(name, in_type, out_type, field, type_field, type_value) \
414 static inline out_type *name(const in_type *parent) \
415 { \
416 assert(parent && parent->type_field == type_value); \
417 return list_entry(parent, out_type, field); \
418 }
419
PCO_DEFINE_CAST(pco_cf_node_as_block,pco_cf_node,pco_block,cf_node,type,PCO_CF_NODE_TYPE_BLOCK)420 PCO_DEFINE_CAST(pco_cf_node_as_block,
421 pco_cf_node,
422 pco_block,
423 cf_node,
424 type,
425 PCO_CF_NODE_TYPE_BLOCK)
426 PCO_DEFINE_CAST(pco_cf_node_as_if,
427 pco_cf_node,
428 pco_if,
429 cf_node,
430 type,
431 PCO_CF_NODE_TYPE_IF)
432 PCO_DEFINE_CAST(pco_cf_node_as_loop,
433 pco_cf_node,
434 pco_loop,
435 cf_node,
436 type,
437 PCO_CF_NODE_TYPE_LOOP)
438 PCO_DEFINE_CAST(pco_cf_node_as_func,
439 pco_cf_node,
440 pco_func,
441 cf_node,
442 type,
443 PCO_CF_NODE_TYPE_FUNC)
444
445 /* Iterators. */
446 #define pco_foreach_func_in_shader(func, shader) \
447 list_for_each_entry (pco_func, func, &(shader)->funcs, link)
448
449 #define pco_foreach_func_in_shader_rev(func, shader) \
450 list_for_each_entry_rev (pco_func, func, &(shader)->funcs, link)
451
452 #define pco_foreach_cf_node_in_if_then(cf_node, _if) \
453 list_for_each_entry (pco_cf_node, cf_node, &(_if)->then_body, link)
454
455 #define pco_foreach_cf_node_in_if_else(cf_node, _if) \
456 list_for_each_entry (pco_cf_node, cf_node, &(_if)->else_body, link)
457
458 #define pco_foreach_cf_node_in_loop(cf_node, loop) \
459 list_for_each_entry (pco_cf_node, cf_node, &(loop)->body, link)
460
461 #define pco_foreach_cf_node_in_func(cf_node, func) \
462 list_for_each_entry (pco_cf_node, cf_node, &(func)->body, link)
463
464 #define pco_foreach_block_in_func(block, func) \
465 for (pco_block *block = pco_func_first_block(func); block != NULL; \
466 block = pco_next_block(block))
467
468 #define pco_foreach_block_in_func_from(block, from) \
469 for (pco_block *block = from; block != NULL; block = pco_next_block(block))
470
471 #define pco_foreach_block_in_func_from_rev(block, from) \
472 for (pco_block *block = from; block != NULL; block = pco_prev_block(block))
473
474 #define pco_foreach_block_in_func_rev(block, func) \
475 for (pco_block *block = pco_func_last_block(func); block != NULL; \
476 block = pco_prev_block(block))
477
478 #define pco_foreach_instr_in_block(instr, block) \
479 assert(!block->parent_func->parent_shader->is_grouped); \
480 list_for_each_entry (pco_instr, instr, &(block)->instrs, link)
481
482 #define pco_foreach_instr_in_block_safe(instr, block) \
483 assert(!block->parent_func->parent_shader->is_grouped); \
484 list_for_each_entry_safe (pco_instr, instr, &(block)->instrs, link)
485
486 #define pco_foreach_instr_in_block_rev(instr, block) \
487 assert(!block->parent_func->parent_shader->is_grouped); \
488 list_for_each_entry_rev (pco_instr, instr, &(block)->instrs, link)
489
490 #define pco_foreach_instr_in_block_safe_rev(instr, block) \
491 assert(!block->parent_func->parent_shader->is_grouped); \
492 list_for_each_entry_safe_rev (pco_instr, instr, &(block)->instrs, link)
493
494 #define pco_foreach_igrp_in_block(igrp, block) \
495 assert(block->parent_func->parent_shader->is_grouped); \
496 list_for_each_entry (pco_igrp, igrp, &(block)->instrs, link)
497
498 #define pco_foreach_phi_src_in_instr(phi_src, instr) \
499 list_for_each_entry (pco_phi_src, phi_src, &(instr)->phi_srcs, link)
500
501 #define pco_foreach_instr_in_func(instr, func) \
502 assert(!func->parent_shader->is_grouped); \
503 pco_foreach_block_in_func (block, func) \
504 list_for_each_entry (pco_instr, instr, &(block)->instrs, link)
505
506 #define pco_foreach_instr_in_func_from(instr, from) \
507 assert(!from->parent_func->parent_shader->is_grouped); \
508 pco_foreach_block_in_func_from (block, from->parent_block) \
509 list_for_each_entry_from (pco_instr, instr, from, &(block)->instrs, link)
510
511 #define pco_foreach_instr_in_func_from_rev(instr, from) \
512 assert(!from->parent_func->parent_shader->is_grouped); \
513 pco_foreach_block_in_func_from_rev (block, from->parent_block) \
514 list_for_each_entry_from_rev (pco_instr, \
515 instr, \
516 from, \
517 &(block)->instrs, \
518 link)
519
520 #define pco_foreach_instr_in_func_safe(instr, func) \
521 assert(!func->parent_shader->is_grouped); \
522 pco_foreach_block_in_func (block, func) \
523 list_for_each_entry_safe (pco_instr, instr, &(block)->instrs, link)
524
525 #define pco_foreach_instr_in_func_rev(instr, func) \
526 assert(!func->parent_shader->is_grouped); \
527 pco_foreach_block_in_func_rev (block, func) \
528 list_for_each_entry_rev (pco_instr, instr, &(block)->instrs, link)
529
530 #define pco_foreach_instr_in_func_safe_rev(instr, func) \
531 assert(!func->parent_shader->is_grouped); \
532 pco_foreach_block_in_func_rev (block, func) \
533 list_for_each_entry_safe_rev (pco_instr, instr, &(block)->instrs, link)
534
535 #define pco_foreach_instr_dest(pdest, instr) \
536 for (pco_ref *pdest = &instr->dest[0]; \
537 pdest < &instr->dest[instr->num_dests]; \
538 ++pdest)
539
540 #define pco_foreach_instr_src(psrc, instr) \
541 for (pco_ref *psrc = &instr->src[0]; psrc < &instr->src[instr->num_srcs]; \
542 ++psrc)
543
544 #define pco_foreach_instr_dest_ssa(pdest, instr) \
545 pco_foreach_instr_dest (pdest, instr) \
546 if (pco_ref_is_ssa(*pdest))
547
548 #define pco_foreach_instr_src_ssa(psrc, instr) \
549 pco_foreach_instr_src (psrc, instr) \
550 if (pco_ref_is_ssa(*psrc))
551
552 #define pco_first_cf_node(body) list_first_entry(body, pco_cf_node, link)
553 #define pco_last_cf_node(body) list_last_entry(body, pco_cf_node, link)
554 #define pco_next_cf_node(cf_node) \
555 list_entry((cf_node)->link.next, pco_cf_node, link)
556 #define pco_prev_cf_node(cf_node) \
557 list_entry((cf_node)->link.prev, pco_cf_node, link)
558
559 /**
560 * \brief Returns whether the current cf node is (directly) in an else body.
561 *
562 * \param[in] cf_node The cf node.
563 * \return True if in the else body, else false if in the then body.
564 */
565 static inline bool pco_cf_node_in_if_else(pco_cf_node *cf_node)
566 {
567 assert(cf_node->parent->type == PCO_CF_NODE_TYPE_IF);
568 return cf_node->flag;
569 }
570
571 /**
572 * \brief Returns the preamble function of a PCO shader.
573 *
574 * \param[in] shader The PCO shader.
575 * \return The preamble function, or NULL if the shader has no preamble.
576 */
pco_preamble(pco_shader * shader)577 static inline pco_func *pco_preamble(pco_shader *shader)
578 {
579 if (list_is_empty(&shader->funcs))
580 return NULL;
581
582 pco_func *func = list_first_entry(&shader->funcs, pco_func, link);
583 if (func->type == PCO_FUNC_TYPE_PREAMBLE)
584 return func;
585
586 return NULL;
587 }
588
589 /**
590 * \brief Returns the entrypoint function of a PCO shader.
591 *
592 * \param[in] shader The PCO shader.
593 * \return The entrypoint function, or NULL if the shader has no entrypoint.
594 */
pco_entrypoint(pco_shader * shader)595 static inline pco_func *pco_entrypoint(pco_shader *shader)
596 {
597 if (list_is_empty(&shader->funcs))
598 return NULL;
599
600 /* Entrypoint will either be the first or second function in the shader,
601 * depending on whether or not there is a preamble.
602 */
603 pco_func *preamble = pco_preamble(shader);
604 pco_func *func = !preamble ? list_first_entry(&shader->funcs, pco_func, link)
605 : list_entry(preamble->link.next, pco_func, link);
606
607 if (func->type == PCO_FUNC_TYPE_ENTRYPOINT)
608 return func;
609
610 return NULL;
611 }
612
613 /**
614 * \brief Returns the variant of an instruction in an instruction group.
615 *
616 * \param[in] igrp The instruction group.
617 * \param[in] phase The instruction phase.
618 * \return The instruction variant.
619 */
pco_igrp_variant(const pco_igrp * igrp,enum pco_op_phase phase)620 static inline unsigned pco_igrp_variant(const pco_igrp *igrp,
621 enum pco_op_phase phase)
622 {
623 switch (igrp->hdr.alutype) {
624 case PCO_ALUTYPE_MAIN:
625 return phase == PCO_OP_PHASE_BACKEND ? igrp->variant.instr[phase].backend
626 : igrp->variant.instr[phase].main;
627
628 case PCO_ALUTYPE_BITWISE:
629 return igrp->variant.instr[phase].bitwise;
630
631 case PCO_ALUTYPE_CONTROL:
632 return igrp->variant.instr[phase].ctrl;
633
634 default:
635 break;
636 }
637
638 unreachable();
639 }
640
641 /* Motions. */
642 /**
643 * \brief Returns the first block in an if then body.
644 *
645 * \param[in] pif The if.
646 * \return The first block.
647 */
pco_if_then_first_block(pco_if * pif)648 static inline pco_block *pco_if_then_first_block(pco_if *pif)
649 {
650 assert(!list_is_empty(&pif->then_body));
651
652 pco_cf_node *cf_node = pco_first_cf_node(&pif->then_body);
653 return pco_cf_node_as_block(cf_node);
654 }
655
656 /**
657 * \brief Returns the last block in an if then body.
658 *
659 * \param[in] pif The if.
660 * \return The last block.
661 */
pco_if_then_last_block(pco_if * pif)662 static inline pco_block *pco_if_then_last_block(pco_if *pif)
663 {
664 assert(!list_is_empty(&pif->then_body));
665
666 pco_cf_node *cf_node = pco_last_cf_node(&pif->then_body);
667 return pco_cf_node_as_block(cf_node);
668 }
669
670 /**
671 * \brief Returns the first block in an else body.
672 *
673 * \param[in] pif The if.
674 * \return The first block.
675 */
pco_if_else_first_block(pco_if * pif)676 static inline pco_block *pco_if_else_first_block(pco_if *pif)
677 {
678 assert(!list_is_empty(&pif->else_body));
679
680 pco_cf_node *cf_node = pco_first_cf_node(&pif->else_body);
681 return pco_cf_node_as_block(cf_node);
682 }
683
684 /**
685 * \brief Returns the last block in an else body.
686 *
687 * \param[in] pif The if.
688 * \return The last block.
689 */
pco_if_else_last_block(pco_if * pif)690 static inline pco_block *pco_if_else_last_block(pco_if *pif)
691 {
692 assert(!list_is_empty(&pif->else_body));
693
694 pco_cf_node *cf_node = pco_last_cf_node(&pif->else_body);
695 return pco_cf_node_as_block(cf_node);
696 }
697
698 /**
699 * \brief Returns the first block in a loop.
700 *
701 * \param[in] loop The loop.
702 * \return The first block.
703 */
pco_loop_first_block(pco_loop * loop)704 static inline pco_block *pco_loop_first_block(pco_loop *loop)
705 {
706 assert(!list_is_empty(&loop->body));
707
708 pco_cf_node *cf_node = pco_first_cf_node(&loop->body);
709 return pco_cf_node_as_block(cf_node);
710 }
711
712 /**
713 * \brief Returns the last block in a loop.
714 *
715 * \param[in] loop The loop.
716 * \return The last block.
717 */
pco_loop_last_block(pco_loop * loop)718 static inline pco_block *pco_loop_last_block(pco_loop *loop)
719 {
720 assert(!list_is_empty(&loop->body));
721
722 pco_cf_node *cf_node = pco_last_cf_node(&loop->body);
723 return pco_cf_node_as_block(cf_node);
724 }
725
726 /**
727 * \brief Returns the first block in a function.
728 *
729 * \param[in] func The function.
730 * \return The first block.
731 */
pco_func_first_block(pco_func * func)732 static inline pco_block *pco_func_first_block(pco_func *func)
733 {
734 assert(!list_is_empty(&func->body));
735
736 pco_cf_node *cf_node = pco_first_cf_node(&func->body);
737 return pco_cf_node_as_block(cf_node);
738 }
739
740 /**
741 * \brief Returns the last block in a function.
742 *
743 * \param[in] func The function.
744 * \return The last block.
745 */
pco_func_last_block(pco_func * func)746 static inline pco_block *pco_func_last_block(pco_func *func)
747 {
748 assert(!list_is_empty(&func->body));
749
750 pco_cf_node *cf_node = pco_last_cf_node(&func->body);
751 return pco_cf_node_as_block(cf_node);
752 }
753
754 /**
755 * \brief Returns the first block in a control-flow node.
756 *
757 * \param[in] cf_node The control-flow node.
758 * \return The first block in the control-flow node.
759 */
pco_cf_node_first_block(pco_cf_node * cf_node)760 static inline pco_block *pco_cf_node_first_block(pco_cf_node *cf_node)
761 {
762 switch (cf_node->type) {
763 case PCO_CF_NODE_TYPE_BLOCK:
764 return pco_cf_node_as_block(cf_node);
765
766 case PCO_CF_NODE_TYPE_IF:
767 return pco_if_then_first_block(pco_cf_node_as_if(cf_node));
768
769 case PCO_CF_NODE_TYPE_LOOP:
770 return pco_loop_first_block(pco_cf_node_as_loop(cf_node));
771
772 case PCO_CF_NODE_TYPE_FUNC:
773 return pco_func_first_block(pco_cf_node_as_func(cf_node));
774
775 default:
776 break;
777 }
778
779 unreachable();
780 }
781
782 /**
783 * \brief Returns the last block in a control-flow node.
784 *
785 * \param[in] cf_node The control-flow node.
786 * \return The last block in the control-flow node.
787 */
pco_cf_node_last_block(pco_cf_node * cf_node)788 static inline pco_block *pco_cf_node_last_block(pco_cf_node *cf_node)
789 {
790 switch (cf_node->type) {
791 case PCO_CF_NODE_TYPE_BLOCK:
792 return pco_cf_node_as_block(cf_node);
793
794 case PCO_CF_NODE_TYPE_IF:
795 return pco_if_else_last_block(pco_cf_node_as_if(cf_node));
796
797 case PCO_CF_NODE_TYPE_LOOP:
798 return pco_loop_last_block(pco_cf_node_as_loop(cf_node));
799
800 case PCO_CF_NODE_TYPE_FUNC:
801 return pco_func_last_block(pco_cf_node_as_func(cf_node));
802
803 default:
804 break;
805 }
806
807 unreachable();
808 }
809
pco_parent_cf_node_body(pco_cf_node * cf_node)810 static inline struct list_head *pco_parent_cf_node_body(pco_cf_node *cf_node)
811 {
812 pco_cf_node *parent_cf_node = cf_node->parent;
813
814 switch (parent_cf_node->type) {
815 case PCO_CF_NODE_TYPE_IF:
816 return pco_cf_node_in_if_else(cf_node)
817 ? &pco_cf_node_as_if(parent_cf_node)->else_body
818 : &pco_cf_node_as_if(parent_cf_node)->then_body;
819
820 case PCO_CF_NODE_TYPE_LOOP:
821 return &pco_cf_node_as_loop(parent_cf_node)->body;
822
823 case PCO_CF_NODE_TYPE_FUNC:
824 return &pco_cf_node_as_func(parent_cf_node)->body;
825
826 default:
827 break;
828 }
829
830 unreachable();
831 }
832
833 /**
834 * \brief Returns the next block in the function.
835 *
836 * \param[in] block The current block.
837 * \return The next block, or NULL if we've reached the end of the function.
838 */
pco_next_block(pco_block * block)839 static inline pco_block *pco_next_block(pco_block *block)
840 {
841 if (!block)
842 return NULL;
843
844 pco_cf_node *cf_node = &block->cf_node;
845 pco_cf_node *last_cf_node =
846 pco_last_cf_node(pco_parent_cf_node_body(cf_node));
847
848 /* Not yet reached the end of the body, return the next cf node. */
849 if (cf_node != last_cf_node)
850 return pco_cf_node_first_block(pco_next_cf_node(cf_node));
851
852 /* Reached the end; go to the next block from the parent cf node. */
853 pco_cf_node *parent_cf_node = cf_node->parent;
854 switch (parent_cf_node->type) {
855 case PCO_CF_NODE_TYPE_IF:
856 /* If we're in the then body, go to the else body. */
857 if (!pco_cf_node_in_if_else(cf_node))
858 return pco_if_else_first_block(pco_cf_node_as_if(parent_cf_node));
859
860 /* Otherwise go to the next block from the parent's parent cf node. */
861 FALLTHROUGH;
862
863 case PCO_CF_NODE_TYPE_LOOP:
864 return pco_cf_node_first_block(pco_next_cf_node(parent_cf_node));
865
866 /* End of the function; return NULL. */
867 case PCO_CF_NODE_TYPE_FUNC:
868 return NULL;
869
870 default:
871 break;
872 }
873
874 unreachable();
875 }
876
877 /**
878 * \brief Returns the previous block in the function.
879 *
880 * \param[in] block The current block.
881 * \return The previous block, or NULL if we've reached the start of the
882 * function.
883 */
pco_prev_block(pco_block * block)884 static inline pco_block *pco_prev_block(pco_block *block)
885 {
886 if (!block)
887 return NULL;
888
889 pco_cf_node *cf_node = &block->cf_node;
890 pco_cf_node *first_cf_node =
891 pco_first_cf_node(pco_parent_cf_node_body(cf_node));
892
893 /* Not yet reached the start of the body, return the previous cf node. */
894 if (cf_node != first_cf_node)
895 return pco_cf_node_last_block(pco_prev_cf_node(cf_node));
896
897 /* Reached the start; go to the previous block from the parent cf node. */
898 pco_cf_node *parent_cf_node = cf_node->parent;
899 switch (parent_cf_node->type) {
900 case PCO_CF_NODE_TYPE_IF:
901 /* If we're in the else body, go to the then body. */
902 if (pco_cf_node_in_if_else(cf_node))
903 return pco_if_then_last_block(pco_cf_node_as_if(parent_cf_node));
904
905 /* Otherwise go to the previous block from the parent's parent cf node. */
906 FALLTHROUGH;
907
908 case PCO_CF_NODE_TYPE_LOOP:
909 return pco_cf_node_last_block(pco_prev_cf_node(parent_cf_node));
910
911 /* Start of the function; return NULL. */
912 case PCO_CF_NODE_TYPE_FUNC:
913 return NULL;
914
915 default:
916 break;
917 }
918
919 unreachable();
920 }
921
922 /**
923 * \brief Returns the first instruction in a block.
924 *
925 * \param[in] block The block.
926 * \return The first instruction, or NULL if the block is empty.
927 */
pco_first_instr(pco_block * block)928 static inline pco_instr *pco_first_instr(pco_block *block)
929 {
930 assert(!block->parent_func->parent_shader->is_grouped);
931 if (list_is_empty(&block->instrs))
932 return NULL;
933
934 return list_first_entry(&block->instrs, pco_instr, link);
935 }
936
937 /**
938 * \brief Returns the last instruction in a block.
939 *
940 * \param[in] block The block.
941 * \return The last instruction, or NULL if the block is empty.
942 */
pco_last_instr(pco_block * block)943 static inline pco_instr *pco_last_instr(pco_block *block)
944 {
945 assert(!block->parent_func->parent_shader->is_grouped);
946 if (list_is_empty(&block->instrs))
947 return NULL;
948
949 return list_last_entry(&block->instrs, pco_instr, link);
950 }
951
952 /**
953 * \brief Returns the next instruction.
954 *
955 * \param[in] instr The current instruction.
956 * \return The next instruction, or NULL if the end of the block has been
957 * reached.
958 */
pco_next_instr(pco_instr * instr)959 static inline pco_instr *pco_next_instr(pco_instr *instr)
960 {
961 assert(!instr->parent_func->parent_shader->is_grouped);
962 if (!instr || instr == pco_last_instr(instr->parent_block))
963 return NULL;
964
965 return list_entry(instr->link.next, pco_instr, link);
966 }
967
968 /**
969 * \brief Returns the previous instruction.
970 *
971 * \param[in] instr The current instruction.
972 * \return The previous instruction, or NULL if the start of the block has been
973 * reached.
974 */
pco_prev_instr(pco_instr * instr)975 static inline pco_instr *pco_prev_instr(pco_instr *instr)
976 {
977 assert(!instr->parent_func->parent_shader->is_grouped);
978 if (!instr || instr == pco_first_instr(instr->parent_block))
979 return NULL;
980
981 return list_entry(instr->link.prev, pco_instr, link);
982 }
983
984 /**
985 * \brief Returns the first instruction group in a block.
986 *
987 * \param[in] block The block.
988 * \return The first instruction group, or NULL if the block is empty.
989 */
pco_first_igrp(pco_block * block)990 static inline pco_igrp *pco_first_igrp(pco_block *block)
991 {
992 assert(block->parent_func->parent_shader->is_grouped);
993 if (list_is_empty(&block->instrs))
994 return NULL;
995
996 return list_first_entry(&block->instrs, pco_igrp, link);
997 }
998
999 /**
1000 * \brief Returns the last instruction group in a block.
1001 *
1002 * \param[in] block The block.
1003 * \return The last instruction group, or NULL if the block is empty.
1004 */
pco_last_igrp(pco_block * block)1005 static inline pco_igrp *pco_last_igrp(pco_block *block)
1006 {
1007 assert(block->parent_func->parent_shader->is_grouped);
1008 if (list_is_empty(&block->instrs))
1009 return NULL;
1010
1011 return list_last_entry(&block->instrs, pco_igrp, link);
1012 }
1013
1014 /**
1015 * \brief Returns the next instruction group.
1016 *
1017 * \param[in] igrp The current instruction group.
1018 * \return The next instruction group, or NULL if the end of the block has been
1019 * reached.
1020 */
pco_next_igrp(pco_igrp * igrp)1021 static inline pco_igrp *pco_next_igrp(pco_igrp *igrp)
1022 {
1023 assert(igrp->parent_func->parent_shader->is_grouped);
1024 if (!igrp || igrp == pco_last_igrp(igrp->parent_block))
1025 return NULL;
1026
1027 return list_entry(igrp->link.next, pco_igrp, link);
1028 }
1029
1030 /**
1031 * \brief Returns the previous instruction group.
1032 *
1033 * \param[in] igrp The current instruction group.
1034 * \return The previous instruction group, or NULL if the start of the block has
1035 * been reached.
1036 */
pco_prev_igrp(pco_igrp * igrp)1037 static inline pco_igrp *pco_prev_igrp(pco_igrp *igrp)
1038 {
1039 assert(igrp->parent_func->parent_shader->is_grouped);
1040 if (!igrp || igrp == pco_first_igrp(igrp->parent_block))
1041 return NULL;
1042
1043 return list_entry(igrp->link.prev, pco_igrp, link);
1044 }
1045
1046 /* Debug printing helpers. */
pco_should_print_nir(nir_shader * nir)1047 static inline bool pco_should_print_nir(nir_shader *nir)
1048 {
1049 if (!PCO_DEBUG_PRINT(NIR))
1050 return false;
1051
1052 if (nir->info.internal && !PCO_DEBUG_PRINT(INTERNAL))
1053 return false;
1054
1055 if (nir->info.stage == MESA_SHADER_VERTEX && !PCO_DEBUG_PRINT(VS))
1056 return false;
1057 else if (nir->info.stage == MESA_SHADER_FRAGMENT && !PCO_DEBUG_PRINT(FS))
1058 return false;
1059 else if (nir->info.stage == MESA_SHADER_COMPUTE && !PCO_DEBUG_PRINT(CS))
1060 return false;
1061
1062 return true;
1063 }
1064
pco_should_print_shader(pco_shader * shader)1065 static inline bool pco_should_print_shader(pco_shader *shader)
1066 {
1067 if (shader->is_internal && !PCO_DEBUG_PRINT(INTERNAL))
1068 return false;
1069
1070 if (shader->stage == MESA_SHADER_VERTEX && !PCO_DEBUG_PRINT(VS))
1071 return false;
1072 else if (shader->stage == MESA_SHADER_FRAGMENT && !PCO_DEBUG_PRINT(FS))
1073 return false;
1074 else if (shader->stage == MESA_SHADER_COMPUTE && !PCO_DEBUG_PRINT(CS))
1075 return false;
1076
1077 return true;
1078 }
1079
pco_should_print_shader_pass(pco_shader * shader)1080 static inline bool pco_should_print_shader_pass(pco_shader *shader)
1081 {
1082 if (!PCO_DEBUG_PRINT(PASSES))
1083 return false;
1084
1085 if (shader->is_internal && !PCO_DEBUG_PRINT(INTERNAL))
1086 return false;
1087
1088 if (shader->stage == MESA_SHADER_VERTEX && !PCO_DEBUG_PRINT(VS))
1089 return false;
1090 else if (shader->stage == MESA_SHADER_FRAGMENT && !PCO_DEBUG_PRINT(FS))
1091 return false;
1092 else if (shader->stage == MESA_SHADER_COMPUTE && !PCO_DEBUG_PRINT(CS))
1093 return false;
1094
1095 return true;
1096 }
1097
pco_should_print_binary(pco_shader * shader)1098 static inline bool pco_should_print_binary(pco_shader *shader)
1099 {
1100 if (!PCO_DEBUG_PRINT(BINARY))
1101 return false;
1102
1103 if (shader->is_internal && !PCO_DEBUG_PRINT(INTERNAL))
1104 return false;
1105
1106 if (shader->stage == MESA_SHADER_VERTEX && !PCO_DEBUG_PRINT(VS))
1107 return false;
1108 else if (shader->stage == MESA_SHADER_FRAGMENT && !PCO_DEBUG_PRINT(FS))
1109 return false;
1110 else if (shader->stage == MESA_SHADER_COMPUTE && !PCO_DEBUG_PRINT(CS))
1111 return false;
1112
1113 return true;
1114 }
1115
1116 /* PCO IR passes. */
1117 bool pco_const_imms(pco_shader *shader);
1118 bool pco_dce(pco_shader *shader);
1119 bool pco_end(pco_shader *shader);
1120 bool pco_group_instrs(pco_shader *shader);
1121 bool pco_index(pco_shader *shader, bool skip_ssa);
1122 bool pco_nir_pfo(nir_shader *nir, pco_fs_data *fs);
1123 bool pco_nir_pvi(nir_shader *nir, pco_vs_data *vs);
1124 bool pco_opt(pco_shader *shader);
1125 bool pco_ra(pco_shader *shader);
1126 bool pco_schedule(pco_shader *shader);
1127
1128 /**
1129 * \brief Returns the PCO bits for a bit size.
1130 *
1131 * \param[in] bits Reference.
1132 * \return PCO bits.
1133 */
pco_bits(unsigned bits)1134 static inline enum pco_bits pco_bits(unsigned bits)
1135 {
1136 switch (bits) {
1137 case 1:
1138 return PCO_BITS_1;
1139
1140 case 8:
1141 return PCO_BITS_8;
1142
1143 case 16:
1144 return PCO_BITS_16;
1145
1146 case 32:
1147 return PCO_BITS_32;
1148
1149 case 64:
1150 return PCO_BITS_64;
1151
1152 default:
1153 break;
1154 }
1155
1156 unreachable();
1157 }
1158
1159 /* PCO ref checkers. */
1160 /**
1161 * \brief Returns whether a reference is null.
1162 *
1163 * \param[in] ref PCO reference.
1164 * \return True if the reference is null.
1165 */
pco_ref_is_null(pco_ref ref)1166 static inline bool pco_ref_is_null(pco_ref ref)
1167 {
1168 return ref.type == PCO_REF_TYPE_NULL;
1169 }
1170
1171 /**
1172 * \brief Returns whether a reference is an SSA variable.
1173 *
1174 * \param[in] ref PCO reference.
1175 * \return True if the reference is an SSA variable.
1176 */
pco_ref_is_ssa(pco_ref ref)1177 static inline bool pco_ref_is_ssa(pco_ref ref)
1178 {
1179 return ref.type == PCO_REF_TYPE_SSA;
1180 }
1181
1182 /**
1183 * \brief Returns whether a reference is a register.
1184 *
1185 * \param[in] ref PCO reference.
1186 * \return True if the reference is a register.
1187 */
pco_ref_is_reg(pco_ref ref)1188 static inline bool pco_ref_is_reg(pco_ref ref)
1189 {
1190 return ref.type == PCO_REF_TYPE_REG;
1191 }
1192
1193 /**
1194 * \brief Returns whether a reference is an index register.
1195 *
1196 * \param[in] ref PCO reference.
1197 * \return True if the reference is an index register.
1198 */
pco_ref_is_idx_reg(pco_ref ref)1199 static inline bool pco_ref_is_idx_reg(pco_ref ref)
1200 {
1201 return ref.type == PCO_REF_TYPE_IDX_REG;
1202 }
1203
1204 /**
1205 * \brief Returns whether a reference is an immediate.
1206 *
1207 * \param[in] ref PCO reference.
1208 * \return True if the reference is an immediate.
1209 */
pco_ref_is_imm(pco_ref ref)1210 static inline bool pco_ref_is_imm(pco_ref ref)
1211 {
1212 return ref.type == PCO_REF_TYPE_IMM;
1213 }
1214
1215 /**
1216 * \brief Returns whether a reference is I/O.
1217 *
1218 * \param[in] ref PCO reference.
1219 * \return True if the reference is I/O.
1220 */
pco_ref_is_io(pco_ref ref)1221 static inline bool pco_ref_is_io(pco_ref ref)
1222 {
1223 return ref.type == PCO_REF_TYPE_IO;
1224 }
1225
1226 /**
1227 * \brief Returns whether a reference is a predicate.
1228 *
1229 * \param[in] ref PCO reference.
1230 * \return True if the reference is a predicate.
1231 */
pco_ref_is_pred(pco_ref ref)1232 static inline bool pco_ref_is_pred(pco_ref ref)
1233 {
1234 return ref.type == PCO_REF_TYPE_PRED;
1235 }
1236
1237 /**
1238 * \brief Returns whether a reference is a dependant read counter.
1239 *
1240 * \param[in] ref PCO reference.
1241 * \return True if the reference is a dependant read counter.
1242 */
pco_ref_is_drc(pco_ref ref)1243 static inline bool pco_ref_is_drc(pco_ref ref)
1244 {
1245 return ref.type == PCO_REF_TYPE_DRC;
1246 }
1247
1248 /**
1249 * \brief Returns whether a reference is scalar.
1250 *
1251 * \param[in] ref PCO reference.
1252 * \return True if the reference is scalar.
1253 */
pco_ref_is_scalar(pco_ref ref)1254 static inline bool pco_ref_is_scalar(pco_ref ref)
1255 {
1256 return !ref.chans;
1257 }
1258
1259 /* PCO ref getters. */
1260 /**
1261 * \brief Returns the pointee component of an indexed register reference.
1262 *
1263 * \param[in] ref Indexed register reference.
1264 * \return Pointee component of the indexed register reference.
1265 */
pco_ref_get_idx_pointee(pco_ref ref)1266 static inline pco_ref pco_ref_get_idx_pointee(pco_ref ref)
1267 {
1268 assert(pco_ref_is_idx_reg(ref));
1269
1270 pco_ref pointee = ref;
1271 pointee.val = ref.idx_reg.offset;
1272 pointee.type = PCO_REF_TYPE_REG;
1273
1274 return pointee;
1275 }
1276
1277 /**
1278 * \brief Returns the data type of a reference.
1279 *
1280 * \param[in] ref Reference.
1281 * \return Datatype.
1282 */
pco_ref_get_dtype(pco_ref ref)1283 static inline enum pco_dtype pco_ref_get_dtype(pco_ref ref)
1284 {
1285 return ref.dtype;
1286 }
1287
1288 /**
1289 * \brief Returns the number of channels for a reference type.
1290 *
1291 * \param[in] ref Reference.
1292 * \return Number of channels.
1293 */
pco_ref_get_chans(pco_ref ref)1294 static inline unsigned pco_ref_get_chans(pco_ref ref)
1295 {
1296 return ref.chans + 1;
1297 }
1298
1299 /**
1300 * \brief Returns the number of bits for a reference type.
1301 *
1302 * \param[in] ref Reference.
1303 * \return Number of bits.
1304 */
pco_ref_get_bits(pco_ref ref)1305 static inline unsigned pco_ref_get_bits(pco_ref ref)
1306 {
1307 switch (ref.bits) {
1308 case PCO_BITS_1:
1309 return 1;
1310
1311 case PCO_BITS_8:
1312 return 8;
1313
1314 case PCO_BITS_16:
1315 return 16;
1316
1317 case PCO_BITS_32:
1318 return 32;
1319
1320 case PCO_BITS_64:
1321 return 64;
1322
1323 default:
1324 break;
1325 }
1326
1327 unreachable();
1328 }
1329
1330 /**
1331 * \brief Returns the bit-sized value in an immediate reference.
1332 *
1333 * \param[in] ref Reference.
1334 * \return Immediate value.
1335 */
pco_ref_get_imm(pco_ref ref)1336 static inline uint64_t pco_ref_get_imm(pco_ref ref)
1337 {
1338 assert(pco_ref_is_imm(ref));
1339
1340 unsigned num_bits = pco_ref_get_bits(ref);
1341
1342 switch (ref.dtype) {
1343 case PCO_DTYPE_FLOAT:
1344 assert(num_bits == 32);
1345 FALLTHROUGH;
1346 case PCO_DTYPE_ANY:
1347 FALLTHROUGH;
1348 case PCO_DTYPE_UNSIGNED:
1349 return ref.val & BITFIELD_MASK(num_bits);
1350
1351 case PCO_DTYPE_SIGNED:
1352 return util_sign_extend(ref.val, num_bits);
1353
1354 default:
1355 break;
1356 }
1357
1358 unreachable();
1359 }
1360
1361 /**
1362 * \brief Returns the register class of a reference type.
1363 *
1364 * \param[in] ref Reference.
1365 * \return Register class.
1366 */
pco_ref_get_reg_class(pco_ref ref)1367 static inline enum pco_reg_class pco_ref_get_reg_class(pco_ref ref)
1368 {
1369 assert(pco_ref_is_reg(ref) || pco_ref_is_idx_reg(ref));
1370 return ref.reg_class;
1371 }
1372
1373 /**
1374 * \brief Returns the register index of a reference type.
1375 *
1376 * \param[in] ref Reference.
1377 * \return Register index.
1378 */
pco_ref_get_reg_index(pco_ref ref)1379 static inline unsigned pco_ref_get_reg_index(pco_ref ref)
1380 {
1381 assert(pco_ref_is_reg(ref) || pco_ref_is_idx_reg(ref));
1382
1383 unsigned index = pco_ref_is_idx_reg(ref) ? ref.idx_reg.offset : ref.val;
1384 assert(index < 256);
1385
1386 return index;
1387 }
1388
1389 /**
1390 * \brief Returns the register index control of a reference type.
1391 *
1392 * \param[in] ref Reference.
1393 * \return Register index control.
1394 */
pco_ref_get_reg_idx_ctrl(pco_ref ref)1395 static inline enum pco_idx_ctrl pco_ref_get_reg_idx_ctrl(pco_ref ref)
1396 {
1397 assert(pco_ref_is_reg(ref) || pco_ref_is_idx_reg(ref));
1398
1399 if (pco_ref_is_reg(ref))
1400 return PCO_IDX_CTRL_NONE;
1401
1402 return PCO_IDX_CTRL_IDX0 + ref.idx_reg.num;
1403 }
1404
1405 /**
1406 * \brief Returns the temp register index from its reference type.
1407 *
1408 * \param[in] ref Reference.
1409 * \return Temp index.
1410 */
pco_ref_get_temp(pco_ref ref)1411 static inline unsigned pco_ref_get_temp(pco_ref ref)
1412 {
1413 assert(pco_ref_is_reg(ref));
1414 assert(pco_ref_get_reg_class(ref) == PCO_REG_CLASS_TEMP);
1415
1416 return pco_ref_get_reg_index(ref);
1417 }
1418
1419 /**
1420 * \brief Returns the coefficient register index from its reference type.
1421 *
1422 * \param[in] ref Reference.
1423 * \return Coefficient index.
1424 */
pco_ref_get_coeff(pco_ref ref)1425 static inline unsigned pco_ref_get_coeff(pco_ref ref)
1426 {
1427 assert(pco_ref_is_reg(ref));
1428 assert(pco_ref_get_reg_class(ref) == PCO_REG_CLASS_COEFF);
1429
1430 return pco_ref_get_reg_index(ref);
1431 }
1432
1433 /**
1434 * \brief Returns the I/O from its reference type.
1435 *
1436 * \param[in] ref Reference.
1437 * \return I/O.
1438 */
pco_ref_get_io(pco_ref ref)1439 static inline enum pco_io pco_ref_get_io(pco_ref ref)
1440 {
1441 assert(pco_ref_is_io(ref));
1442 assert(ref.val < _PCO_IO_COUNT);
1443 return ref.val;
1444 }
1445
1446 /**
1447 * \brief Returns the predicate from its reference type.
1448 *
1449 * \param[in] ref Reference.
1450 * \return Predicate.
1451 */
pco_ref_get_pred(pco_ref ref)1452 static inline enum pco_pred pco_ref_get_pred(pco_ref ref)
1453 {
1454 assert(pco_ref_is_pred(ref));
1455 assert(ref.val < _PCO_PRED_COUNT);
1456 return ref.val;
1457 }
1458
1459 /**
1460 * \brief Returns the dependent read counter from its reference type.
1461 *
1462 * \param[in] ref Reference.
1463 * \return Dependent read counter.
1464 */
pco_ref_get_drc(pco_ref ref)1465 static inline enum pco_drc pco_ref_get_drc(pco_ref ref)
1466 {
1467 assert(pco_ref_is_drc(ref));
1468 assert(ref.val < _PCO_DRC_COUNT);
1469 return ref.val;
1470 }
1471
1472 /**
1473 * \brief Returns whether the reference has any mods set.
1474 *
1475 * \param[in] ref Reference.
1476 * \return True if any mods are set.
1477 */
pco_ref_has_mods_set(pco_ref ref)1478 static inline bool pco_ref_has_mods_set(pco_ref ref)
1479 {
1480 return ref.oneminus || ref.clamp || ref.abs || ref.neg || ref.flr ||
1481 (ref.elem != 0);
1482 }
1483
1484 /* PCO ref builders. */
1485 /**
1486 * \brief Builds and returns a null reference.
1487 *
1488 * \return NULL reference.
1489 */
pco_ref_null(void)1490 static inline pco_ref pco_ref_null(void)
1491 {
1492 return (pco_ref){
1493 .type = PCO_REF_TYPE_NULL,
1494 };
1495 }
1496
1497 /**
1498 * \brief Builds and returns an SSA reference.
1499 *
1500 * \return SSA reference.
1501 */
pco_ref_ssa(unsigned index,unsigned bits,unsigned chans)1502 static inline pco_ref pco_ref_ssa(unsigned index, unsigned bits, unsigned chans)
1503 {
1504 return (pco_ref){
1505 .val = index,
1506 .chans = chans - 1,
1507 .bits = pco_bits(bits),
1508 .type = PCO_REF_TYPE_SSA,
1509 };
1510 }
1511
1512 /**
1513 * \brief Builds and returns a new SSA reference.
1514 *
1515 * \param[in,out] func The function.
1516 * \param[in] bits Number of bits.
1517 * \param[in] chans Number of channels.
1518 * \return SSA reference.
1519 */
1520 static inline pco_ref
pco_ref_new_ssa(pco_func * func,unsigned bits,unsigned chans)1521 pco_ref_new_ssa(pco_func *func, unsigned bits, unsigned chans)
1522 {
1523 return (pco_ref){
1524 .val = func->next_ssa++,
1525 .chans = chans - 1,
1526 .bits = pco_bits(bits),
1527 .type = PCO_REF_TYPE_SSA,
1528 };
1529 }
1530
1531 /**
1532 * \brief Builds and returns a new 32x1 SSA reference.
1533 *
1534 * \param[in,out] func The function.
1535 * \return SSA reference.
1536 */
pco_ref_new_ssa32(pco_func * func)1537 static inline pco_ref pco_ref_new_ssa32(pco_func *func)
1538 {
1539 return pco_ref_new_ssa(func, 32, 1);
1540 }
1541
1542 /**
1543 * \brief Builds and returns a virtual register reference.
1544 *
1545 * \param[in] index Virtual register index.
1546 * \return Virtual register reference.
1547 */
pco_ref_vreg(unsigned index)1548 static inline pco_ref pco_ref_vreg(unsigned index)
1549 {
1550 return (pco_ref){
1551 .val = index,
1552 .bits = PCO_BITS_32,
1553 .type = PCO_REF_TYPE_REG,
1554 .reg_class = PCO_REG_CLASS_VIRT,
1555 };
1556 }
1557
1558 /**
1559 * \brief Builds and returns a scalar hardware register reference.
1560 *
1561 * \param[in] index Register index.
1562 * \param[in] reg_class Register class.
1563 * \return Hardware register reference.
1564 */
pco_ref_hwreg(unsigned index,enum pco_reg_class reg_class)1565 static inline pco_ref pco_ref_hwreg(unsigned index,
1566 enum pco_reg_class reg_class)
1567 {
1568 assert(index < 256);
1569 assert(reg_class != PCO_REG_CLASS_VIRT);
1570
1571 return (pco_ref){
1572 .val = index,
1573 .bits = PCO_BITS_32,
1574 .type = PCO_REF_TYPE_REG,
1575 .reg_class = reg_class,
1576 };
1577 }
1578
1579 /**
1580 * \brief Builds and returns a vector hardware register reference.
1581 *
1582 * \param[in] index Register index.
1583 * \param[in] reg_class Register class.
1584 * \param[in] chans Number of channels.
1585 * \return Hardware register reference.
1586 */
1587 static inline pco_ref
pco_ref_hwreg_vec(unsigned index,enum pco_reg_class reg_class,unsigned chans)1588 pco_ref_hwreg_vec(unsigned index, enum pco_reg_class reg_class, unsigned chans)
1589 {
1590 assert(index < 256);
1591 assert(reg_class != PCO_REG_CLASS_VIRT);
1592
1593 return (pco_ref){
1594 .val = index,
1595 .chans = chans - 1,
1596 .bits = PCO_BITS_32,
1597 .type = PCO_REF_TYPE_REG,
1598 .reg_class = reg_class,
1599 };
1600 }
1601
1602 /**
1603 * \brief Builds and returns an immediate reference.
1604 *
1605 * \param[in] val Immediate value.
1606 * \param[in] bits Immediate bit size.
1607 * \param[in] dtype Immediate datatype.
1608 * \return Immediate reference.
1609 */
1610 static inline pco_ref
pco_ref_imm(uint32_t val,enum pco_bits bits,enum pco_dtype dtype)1611 pco_ref_imm(uint32_t val, enum pco_bits bits, enum pco_dtype dtype)
1612 {
1613 return (pco_ref){
1614 .val = val,
1615 .dtype = dtype,
1616 .bits = bits,
1617 .type = PCO_REF_TYPE_IMM,
1618 };
1619 }
1620
1621 /**
1622 * \brief Builds and returns an 8-bit immediate reference.
1623 *
1624 * \param[in] val 8-bit immediate.
1625 * \return Immediate reference.
1626 */
pco_ref_imm8(uint8_t val)1627 static inline pco_ref pco_ref_imm8(uint8_t val)
1628 {
1629 return pco_ref_imm(val, PCO_BITS_8, PCO_DTYPE_UNSIGNED);
1630 }
1631
1632 /**
1633 * \brief Builds and returns a 16-bit immediate reference.
1634 *
1635 * \param[in] val 16-bit immediate.
1636 * \return Immediate reference.
1637 */
pco_ref_imm16(uint16_t val)1638 static inline pco_ref pco_ref_imm16(uint16_t val)
1639 {
1640 return pco_ref_imm(val, PCO_BITS_16, PCO_DTYPE_UNSIGNED);
1641 }
1642
1643 /**
1644 * \brief Builds and returns a 32-bit immediate reference.
1645 *
1646 * \param[in] val 32-bit immediate.
1647 * \return Immediate reference.
1648 */
pco_ref_imm32(uint32_t val)1649 static inline pco_ref pco_ref_imm32(uint32_t val)
1650 {
1651 return pco_ref_imm(val, PCO_BITS_32, PCO_DTYPE_UNSIGNED);
1652 }
1653
1654 /**
1655 * \brief Builds and returns an untyped 8-bit immediate reference.
1656 *
1657 * \param[in] val 8-bit immediate.
1658 * \return Immediate reference.
1659 */
pco_ref_val8(uint8_t val)1660 static inline pco_ref pco_ref_val8(uint8_t val)
1661 {
1662 return pco_ref_imm(val, PCO_BITS_8, PCO_DTYPE_ANY);
1663 }
1664
1665 /**
1666 * \brief Builds and returns an untyped 16-bit immediate reference.
1667 *
1668 * \param[in] val 16-bit immediate.
1669 * \return Immediate reference.
1670 */
pco_ref_val16(uint16_t val)1671 static inline pco_ref pco_ref_val16(uint16_t val)
1672 {
1673 return pco_ref_imm(val, PCO_BITS_16, PCO_DTYPE_ANY);
1674 }
1675
1676 /**
1677 * \brief Builds and returns an untyped 32-bit immediate reference.
1678 *
1679 * \param[in] val 32-bit immediate.
1680 * \return Immediate reference.
1681 */
pco_ref_val32(uint32_t val)1682 static inline pco_ref pco_ref_val32(uint32_t val)
1683 {
1684 return pco_ref_imm(val, PCO_BITS_32, PCO_DTYPE_UNSIGNED);
1685 }
1686
1687 /**
1688 * \brief Builds and returns an I/O reference.
1689 *
1690 * \param[in] io I/O.
1691 * \return I/O reference.
1692 */
pco_ref_io(enum pco_io io)1693 static inline pco_ref pco_ref_io(enum pco_io io)
1694 {
1695 return (pco_ref){
1696 .val = io,
1697 .type = PCO_REF_TYPE_IO,
1698 };
1699 }
1700
1701 /**
1702 * \brief Builds and returns a predicate reference.
1703 *
1704 * \param[in] pred predicate.
1705 * \return Predicate reference.
1706 */
pco_ref_pred(enum pco_pred pred)1707 static inline pco_ref pco_ref_pred(enum pco_pred pred)
1708 {
1709 return (pco_ref){
1710 .val = pred,
1711 .type = PCO_REF_TYPE_PRED,
1712 };
1713 }
1714
1715 /**
1716 * \brief Builds and returns a dependent read counter reference.
1717 *
1718 * \param[in] drc Dependent read counter.
1719 * \return Dependent read counter reference.
1720 */
pco_ref_drc(enum pco_drc drc)1721 static inline pco_ref pco_ref_drc(enum pco_drc drc)
1722 {
1723 return (pco_ref){
1724 .val = drc,
1725 .type = PCO_REF_TYPE_DRC,
1726 };
1727 }
1728
1729 /* PCO ref utils. */
1730 /**
1731 * \brief Transfers reference mods, optionally resetting them.
1732 *
1733 * \param[in,out] dest Reference to transfer mods to.
1734 * \param[in,out] source Reference to transfer mods from.
1735 * \param[in] reset Whether to reset the source mods.
1736 * \return I/O reference.
1737 */
pco_ref_xfer_mods(pco_ref * dest,pco_ref * source,bool reset)1738 static inline void pco_ref_xfer_mods(pco_ref *dest, pco_ref *source, bool reset)
1739 {
1740 dest->oneminus = source->oneminus;
1741 dest->clamp = source->clamp;
1742 dest->flr = source->flr;
1743 dest->abs = source->abs;
1744 dest->neg = source->neg;
1745 dest->elem = source->elem;
1746
1747 if (reset) {
1748 source->oneminus = false;
1749 source->clamp = false;
1750 source->flr = false;
1751 source->abs = false;
1752 source->neg = false;
1753 source->elem = 0;
1754 }
1755 }
1756
1757 /**
1758 * \brief Updates a reference to set the oneminus modifier.
1759 *
1760 * \param[in] ref Base reference.
1761 * \return Updated reference.
1762 */
pco_ref_oneminus(pco_ref ref)1763 static inline pco_ref pco_ref_oneminus(pco_ref ref)
1764 {
1765 ref.oneminus = true;
1766 return ref;
1767 }
1768
1769 /**
1770 * \brief Updates a reference to set the clamp modifier.
1771 *
1772 * \param[in] ref Base reference.
1773 * \return Updated reference.
1774 */
pco_ref_clamp(pco_ref ref)1775 static inline pco_ref pco_ref_clamp(pco_ref ref)
1776 {
1777 ref.clamp = true;
1778 return ref;
1779 }
1780
1781 /**
1782 * \brief Updates a reference to set the floor modifier.
1783 *
1784 * \param[in] ref Base reference.
1785 * \return Updated reference.
1786 */
pco_ref_flr(pco_ref ref)1787 static inline pco_ref pco_ref_flr(pco_ref ref)
1788 {
1789 ref.flr = true;
1790 ref.abs = false;
1791 ref.neg = false;
1792 return ref;
1793 }
1794
1795 /**
1796 * \brief Updates a reference to set the abs modifier.
1797 *
1798 * \param[in] ref Base reference.
1799 * \return Updated reference.
1800 */
pco_ref_abs(pco_ref ref)1801 static inline pco_ref pco_ref_abs(pco_ref ref)
1802 {
1803 ref.abs = true;
1804 ref.neg = false;
1805 return ref;
1806 }
1807
1808 /**
1809 * \brief Updates a reference to set the negate modifier.
1810 *
1811 * \param[in] ref Base reference.
1812 * \return Updated reference.
1813 */
pco_ref_neg(pco_ref ref)1814 static inline pco_ref pco_ref_neg(pco_ref ref)
1815 {
1816 ref.neg = !ref.neg;
1817 return ref;
1818 }
1819
1820 /**
1821 * \brief Updates a reference to set the element modifier.
1822 *
1823 * \param[in] ref Base reference.
1824 * \param[in] elem New element modifier.
1825 * \return Updated reference.
1826 */
pco_ref_elem(pco_ref ref,enum pco_elem elem)1827 static inline pco_ref pco_ref_elem(pco_ref ref, enum pco_elem elem)
1828 {
1829 ref.elem = elem;
1830 return ref;
1831 }
1832
1833 /**
1834 * \brief Updates a reference to set the number of channels.
1835 *
1836 * \param[in] ref Base reference.
1837 * \param[in] chans New number of channels.
1838 * \return Updated reference.
1839 */
pco_ref_chans(pco_ref ref,unsigned chans)1840 static inline pco_ref pco_ref_chans(pco_ref ref, unsigned chans)
1841 {
1842 ref.chans = chans - 1;
1843 return ref;
1844 }
1845
1846 /**
1847 * \brief Updates a reference value with the provided offset.
1848 *
1849 * \param[in] ref Base reference.
1850 * \param[in] offset Offset to apply.
1851 * \return Updated reference.
1852 */
pco_ref_offset(pco_ref ref,signed offset)1853 static inline pco_ref pco_ref_offset(pco_ref ref, signed offset)
1854 {
1855 int64_t val = pco_ref_is_idx_reg(ref) ? ref.idx_reg.offset : ref.val;
1856 val += offset;
1857
1858 if (pco_ref_is_idx_reg(ref)) {
1859 assert(util_last_bit64(val) <= PCO_REF_IDX_OFFSET_BITS);
1860 ref.idx_reg.offset = val;
1861 } else {
1862 assert(util_last_bit64(val) <= PCO_REF_VAL_BITS);
1863 ref.val = val;
1864 }
1865
1866 return ref;
1867 }
1868
1869 /**
1870 * \brief Checks whether two reference modifiers are the same.
1871 *
1872 * \param[in] ref0 First reference.
1873 * \param[in] ref1 Second reference.
1874 * \return True if both reference modifiers are the same.
1875 */
pco_ref_mods_are_equal(pco_ref ref0,pco_ref ref1)1876 static inline bool pco_ref_mods_are_equal(pco_ref ref0, pco_ref ref1)
1877 {
1878 return (ref0.oneminus == ref1.oneminus) && (ref0.clamp == ref1.clamp) &&
1879 (ref0.flr == ref1.flr) && (ref0.abs == ref1.abs) &&
1880 (ref0.neg == ref1.neg) && (ref0.elem == ref1.elem);
1881 }
1882
1883 /**
1884 * \brief Checks whether two references are the same.
1885 *
1886 * \param[in] ref0 First reference.
1887 * \param[in] ref1 Second reference.
1888 * \return True if both references are the same.
1889 */
1890 /* TODO: can this be simplified? */
pco_refs_are_equal(pco_ref ref0,pco_ref ref1)1891 static inline bool pco_refs_are_equal(pco_ref ref0, pco_ref ref1)
1892 {
1893 if (ref0.type != ref1.type)
1894 return false;
1895
1896 if (pco_ref_is_idx_reg(ref0)) {
1897 if ((ref0.idx_reg.num != ref1.idx_reg.num) ||
1898 (ref0.idx_reg.offset != ref1.idx_reg.offset)) {
1899 return false;
1900 }
1901 } else if (ref0.val != ref1.val) {
1902 return false;
1903 }
1904
1905 if (pco_ref_is_idx_reg(ref0) || pco_ref_is_reg(ref0))
1906 if (ref0.reg_class != ref1.reg_class)
1907 return false;
1908
1909 if (!pco_ref_mods_are_equal(ref0, ref1))
1910 return false;
1911
1912 if (ref0.chans != ref1.chans)
1913 return false;
1914
1915 if (pco_ref_get_dtype(ref0) != pco_ref_get_dtype(ref1))
1916 return false;
1917
1918 if (pco_ref_get_bits(ref0) != pco_ref_get_bits(ref1))
1919 return false;
1920
1921 return true;
1922 }
1923
1924 /**
1925 * \brief Returns whether none of the lower/upper sources in an instruction
1926 * group are set.
1927 *
1928 * \param[in] igrp The instruction group.
1929 * \param[in] upper True if checking the upper sources.
1930 * \return True if none of the lower/upper sources are set.
1931 */
pco_igrp_srcs_unset(pco_igrp * igrp,bool upper)1932 static inline bool pco_igrp_srcs_unset(pco_igrp *igrp, bool upper)
1933 {
1934 unsigned offset = upper ? ROGUE_ALU_INPUT_GROUP_SIZE : 0;
1935
1936 for (unsigned u = 0; u < ROGUE_ALU_INPUT_GROUP_SIZE; ++u)
1937 if (!pco_ref_is_null(igrp->srcs.s[u + offset]))
1938 return false;
1939
1940 return true;
1941 }
1942
1943 /**
1944 * \brief Returns whether none of the internal source selectors in an
1945 * instruction group are set.
1946 *
1947 * \param[in] igrp The instruction group.
1948 * \return True if none of the internal source selectors are set.
1949 */
pco_igrp_iss_unset(pco_igrp * igrp)1950 static inline bool pco_igrp_iss_unset(pco_igrp *igrp)
1951 {
1952 for (unsigned u = 0; u < ARRAY_SIZE(igrp->iss.is); ++u)
1953 if (!pco_ref_is_null(igrp->iss.is[u]))
1954 return false;
1955
1956 return true;
1957 }
1958
1959 /**
1960 * \brief Returns whether none of the destinations in an instruction group are
1961 * set.
1962 *
1963 * \param[in] igrp The instruction group.
1964 * \return True if none of the destinations are set.
1965 */
pco_igrp_dests_unset(pco_igrp * igrp)1966 static inline bool pco_igrp_dests_unset(pco_igrp *igrp)
1967 {
1968 for (unsigned u = 0; u < ARRAY_SIZE(igrp->dests.w); ++u)
1969 if (!pco_ref_is_null(igrp->dests.w[u]))
1970 return false;
1971
1972 return true;
1973 }
1974
1975 /**
1976 * \brief Iterates backwards to find the parent instruction of a source.
1977 *
1978 * \param[in] src The source whose parent is to be found.
1979 * \param[in] from The instruction to start iterating back from.
1980 * \return The parent instruction if found, else NULL.
1981 */
find_parent_instr_from(pco_ref src,pco_instr * from)1982 static inline pco_instr *find_parent_instr_from(pco_ref src, pco_instr *from)
1983 {
1984 pco_foreach_instr_in_func_from_rev (instr, from) {
1985 pco_foreach_instr_dest_ssa (pdest, instr) {
1986 if (pco_refs_are_equal(*pdest, src))
1987 return instr;
1988 }
1989 }
1990
1991 return NULL;
1992 }
1993
1994 /* Common hw constants. */
1995
1996 /** Integer/float zero. */
1997 #define pco_zero pco_ref_hwreg(0, PCO_REG_CLASS_CONST)
1998
1999 /** Integer one. */
2000 #define pco_one pco_ref_hwreg(1, PCO_REG_CLASS_CONST)
2001
2002 /** Integer -1/true/0xffffffff. */
2003 #define pco_true pco_ref_hwreg(143, PCO_REG_CLASS_CONST)
2004
2005 /** Float 1. */
2006 #define pco_fone pco_ref_hwreg(64, PCO_REG_CLASS_CONST)
2007
2008 /* Printing. */
2009 void pco_print_ref(pco_shader *shader, pco_ref ref);
2010 void pco_print_instr(pco_shader *shader, pco_instr *instr);
2011 void pco_print_igrp(pco_shader *shader, pco_igrp *igrp);
2012 void pco_print_cf_node_name(pco_shader *shader, pco_cf_node *cf_node);
2013 void pco_print_shader_info(pco_shader *shader);
2014
2015 #endif /* PCO_INTERNAL_H */
2016