• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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