Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/panfrost/bifrost/compiler.h
4564 views
1
/*
2
* Copyright (C) 2020 Collabora Ltd.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
* SOFTWARE.
22
*
23
* Authors (Collabora):
24
* Alyssa Rosenzweig <[email protected]>
25
*/
26
27
#ifndef __BIFROST_COMPILER_H
28
#define __BIFROST_COMPILER_H
29
30
#include "bifrost.h"
31
#include "bi_opcodes.h"
32
#include "compiler/nir/nir.h"
33
#include "panfrost/util/pan_ir.h"
34
#include "util/u_math.h"
35
#include "util/half_float.h"
36
37
/* Swizzles across bytes in a 32-bit word. Expresses swz in the XML directly.
38
* To express widen, use the correpsonding replicated form, i.e. H01 = identity
39
* for widen = none, H00 for widen = h0, B1111 for widen = b1. For lane, also
40
* use the replicated form (interpretation is governed by the opcode). For
41
* 8-bit lanes with two channels, use replicated forms for replicated forms
42
* (TODO: what about others?). For 8-bit lanes with four channels using
43
* matching form (TODO: what about others?).
44
*/
45
46
enum bi_swizzle {
47
/* 16-bit swizzle ordering deliberate for fast compute */
48
BI_SWIZZLE_H00 = 0, /* = B0101 */
49
BI_SWIZZLE_H01 = 1, /* = B0123 = W0 */
50
BI_SWIZZLE_H10 = 2, /* = B2301 */
51
BI_SWIZZLE_H11 = 3, /* = B2323 */
52
53
/* replication order should be maintained for fast compute */
54
BI_SWIZZLE_B0000 = 4, /* single channel (replicate) */
55
BI_SWIZZLE_B1111 = 5,
56
BI_SWIZZLE_B2222 = 6,
57
BI_SWIZZLE_B3333 = 7,
58
59
/* totally special for explicit pattern matching */
60
BI_SWIZZLE_B0011 = 8, /* +SWZ.v4i8 */
61
BI_SWIZZLE_B2233 = 9, /* +SWZ.v4i8 */
62
BI_SWIZZLE_B1032 = 10, /* +SWZ.v4i8 */
63
BI_SWIZZLE_B3210 = 11, /* +SWZ.v4i8 */
64
65
BI_SWIZZLE_B0022 = 12, /* for b02 lanes */
66
};
67
68
enum bi_index_type {
69
BI_INDEX_NULL = 0,
70
BI_INDEX_NORMAL = 1,
71
BI_INDEX_REGISTER = 2,
72
BI_INDEX_CONSTANT = 3,
73
BI_INDEX_PASS = 4,
74
BI_INDEX_FAU = 5
75
};
76
77
typedef struct {
78
uint32_t value;
79
80
/* modifiers, should only be set if applicable for a given instruction.
81
* For *IDP.v4i8, abs plays the role of sign. For bitwise ops where
82
* applicable, neg plays the role of not */
83
bool abs : 1;
84
bool neg : 1;
85
86
/* For a source, the swizzle. For a destination, acts a bit like a
87
* write mask. Identity for the full 32-bit, H00 for only caring about
88
* the lower half, other values unused. */
89
enum bi_swizzle swizzle : 4;
90
uint32_t offset : 2;
91
bool reg : 1;
92
enum bi_index_type type : 3;
93
} bi_index;
94
95
static inline bi_index
96
bi_get_index(unsigned value, bool is_reg, unsigned offset)
97
{
98
return (bi_index) {
99
.type = BI_INDEX_NORMAL,
100
.value = value,
101
.swizzle = BI_SWIZZLE_H01,
102
.offset = offset,
103
.reg = is_reg,
104
};
105
}
106
107
static inline bi_index
108
bi_register(unsigned reg)
109
{
110
assert(reg < 64);
111
112
return (bi_index) {
113
.type = BI_INDEX_REGISTER,
114
.swizzle = BI_SWIZZLE_H01,
115
.value = reg
116
};
117
}
118
119
static inline bi_index
120
bi_imm_u32(uint32_t imm)
121
{
122
return (bi_index) {
123
.type = BI_INDEX_CONSTANT,
124
.swizzle = BI_SWIZZLE_H01,
125
.value = imm
126
};
127
}
128
129
static inline bi_index
130
bi_imm_f32(float imm)
131
{
132
return bi_imm_u32(fui(imm));
133
}
134
135
static inline bi_index
136
bi_null()
137
{
138
return (bi_index) { .type = BI_INDEX_NULL };
139
}
140
141
static inline bi_index
142
bi_zero()
143
{
144
return bi_imm_u32(0);
145
}
146
147
static inline bi_index
148
bi_passthrough(enum bifrost_packed_src value)
149
{
150
return (bi_index) {
151
.type = BI_INDEX_PASS,
152
.swizzle = BI_SWIZZLE_H01,
153
.value = value
154
};
155
}
156
157
/* Read back power-efficent garbage, TODO maybe merge with null? */
158
static inline bi_index
159
bi_dontcare()
160
{
161
return bi_passthrough(BIFROST_SRC_FAU_HI);
162
}
163
164
/* Extracts a word from a vectored index */
165
static inline bi_index
166
bi_word(bi_index idx, unsigned component)
167
{
168
idx.offset += component;
169
return idx;
170
}
171
172
/* Helps construct swizzles */
173
static inline bi_index
174
bi_swz_16(bi_index idx, bool x, bool y)
175
{
176
assert(idx.swizzle == BI_SWIZZLE_H01);
177
idx.swizzle = BI_SWIZZLE_H00 | (x << 1) | y;
178
return idx;
179
}
180
181
static inline bi_index
182
bi_half(bi_index idx, bool upper)
183
{
184
return bi_swz_16(idx, upper, upper);
185
}
186
187
static inline bi_index
188
bi_byte(bi_index idx, unsigned lane)
189
{
190
assert(idx.swizzle == BI_SWIZZLE_H01);
191
assert(lane < 4);
192
idx.swizzle = BI_SWIZZLE_B0000 + lane;
193
return idx;
194
}
195
196
static inline bi_index
197
bi_abs(bi_index idx)
198
{
199
idx.abs = true;
200
return idx;
201
}
202
203
static inline bi_index
204
bi_neg(bi_index idx)
205
{
206
idx.neg ^= true;
207
return idx;
208
}
209
210
/* Additive identity in IEEE 754 arithmetic */
211
static inline bi_index
212
bi_negzero()
213
{
214
return bi_neg(bi_zero());
215
}
216
217
/* Replaces an index, preserving any modifiers */
218
219
static inline bi_index
220
bi_replace_index(bi_index old, bi_index replacement)
221
{
222
replacement.abs = old.abs;
223
replacement.neg = old.neg;
224
replacement.swizzle = old.swizzle;
225
return replacement;
226
}
227
228
/* For bitwise instructions */
229
#define bi_not(x) bi_neg(x)
230
231
static inline bi_index
232
bi_imm_u8(uint8_t imm)
233
{
234
return bi_byte(bi_imm_u32(imm), 0);
235
}
236
237
static inline bi_index
238
bi_imm_u16(uint16_t imm)
239
{
240
return bi_half(bi_imm_u32(imm), false);
241
}
242
243
static inline bi_index
244
bi_imm_uintN(uint32_t imm, unsigned sz)
245
{
246
assert(sz == 8 || sz == 16 || sz == 32);
247
return (sz == 8) ? bi_imm_u8(imm) :
248
(sz == 16) ? bi_imm_u16(imm) :
249
bi_imm_u32(imm);
250
}
251
252
static inline bi_index
253
bi_imm_f16(float imm)
254
{
255
return bi_imm_u16(_mesa_float_to_half(imm));
256
}
257
258
static inline bool
259
bi_is_null(bi_index idx)
260
{
261
return idx.type == BI_INDEX_NULL;
262
}
263
264
static inline bool
265
bi_is_ssa(bi_index idx)
266
{
267
return idx.type == BI_INDEX_NORMAL && !idx.reg;
268
}
269
270
/* Compares equivalence as references. Does not compare offsets, swizzles, or
271
* modifiers. In other words, this forms bi_index equivalence classes by
272
* partitioning memory. E.g. -abs(foo[1].yx) == foo.xy but foo != bar */
273
274
static inline bool
275
bi_is_equiv(bi_index left, bi_index right)
276
{
277
return (left.type == right.type) &&
278
(left.reg == right.reg) &&
279
(left.value == right.value);
280
}
281
282
/* A stronger equivalence relation that requires the indices access the
283
* same offset, useful for RA/scheduling to see what registers will
284
* correspond to */
285
286
static inline bool
287
bi_is_word_equiv(bi_index left, bi_index right)
288
{
289
return bi_is_equiv(left, right) && left.offset == right.offset;
290
}
291
292
#define BI_MAX_DESTS 2
293
#define BI_MAX_SRCS 4
294
295
typedef struct {
296
/* Must be first */
297
struct list_head link;
298
299
/* Link for the use chain */
300
struct list_head use;
301
302
enum bi_opcode op;
303
304
/* Data flow */
305
bi_index dest[BI_MAX_DESTS];
306
bi_index src[BI_MAX_SRCS];
307
308
/* For a branch */
309
struct bi_block *branch_target;
310
311
/* These don't fit neatly with anything else.. */
312
enum bi_register_format register_format;
313
enum bi_vecsize vecsize;
314
315
/* Can we spill the value written here? Used to prevent
316
* useless double fills */
317
bool no_spill;
318
319
/* Override table, inducing a DTSEL_IMM pair if nonzero */
320
enum bi_table table;
321
322
/* Everything after this MUST NOT be accessed directly, since
323
* interpretation depends on opcodes */
324
325
/* Destination modifiers */
326
union {
327
enum bi_clamp clamp;
328
bool saturate;
329
bool not_result;
330
unsigned dest_mod;
331
};
332
333
/* Immediates. All seen alone in an instruction, except for varying/texture
334
* which are specified jointly for VARTEX */
335
union {
336
uint32_t shift;
337
uint32_t fill;
338
uint32_t index;
339
uint32_t attribute_index;
340
341
struct {
342
uint32_t varying_index;
343
uint32_t sampler_index;
344
uint32_t texture_index;
345
};
346
347
/* TEXC, ATOM_CX: # of staging registers used */
348
uint32_t sr_count;
349
};
350
351
/* Modifiers specific to particular instructions are thrown in a union */
352
union {
353
enum bi_adj adj; /* FEXP_TABLE.u4 */
354
enum bi_atom_opc atom_opc; /* atomics */
355
enum bi_func func; /* FPOW_SC_DET */
356
enum bi_function function; /* LD_VAR_FLAT */
357
enum bi_mux mux; /* MUX */
358
enum bi_sem sem; /* FMAX, FMIN */
359
enum bi_source source; /* LD_GCLK */
360
bool scale; /* VN_ASST2, FSINCOS_OFFSET */
361
bool offset; /* FSIN_TABLE, FOCS_TABLE */
362
bool mask; /* CLZ */
363
bool threads; /* IMULD, IMOV_FMA */
364
bool combine; /* BRANCHC */
365
bool format; /* LEA_TEX */
366
367
struct {
368
enum bi_special special; /* FADD_RSCALE, FMA_RSCALE */
369
enum bi_round round; /* FMA, converts, FADD, _RSCALE, etc */
370
};
371
372
struct {
373
enum bi_result_type result_type; /* FCMP, ICMP */
374
enum bi_cmpf cmpf; /* CSEL, FCMP, ICMP, BRANCH */
375
};
376
377
struct {
378
enum bi_stack_mode stack_mode; /* JUMP_EX */
379
bool test_mode;
380
};
381
382
struct {
383
enum bi_seg seg; /* LOAD, STORE, SEG_ADD, SEG_SUB */
384
bool preserve_null; /* SEG_ADD, SEG_SUB */
385
enum bi_extend extend; /* LOAD, IMUL */
386
};
387
388
struct {
389
enum bi_sample sample; /* VAR_TEX, LD_VAR */
390
enum bi_update update; /* VAR_TEX, LD_VAR */
391
enum bi_varying_name varying_name; /* LD_VAR_SPECIAL */
392
bool skip; /* VAR_TEX, TEXS, TEXC */
393
bool lod_mode; /* VAR_TEX, TEXS, implicitly for TEXC */
394
};
395
396
/* Maximum size, for hashing */
397
unsigned flags[5];
398
399
struct {
400
enum bi_subgroup subgroup; /* WMASK, CLPER */
401
enum bi_inactive_result inactive_result; /* CLPER */
402
enum bi_lane_op lane_op; /* CLPER */
403
};
404
405
struct {
406
bool z; /* ZS_EMIT */
407
bool stencil; /* ZS_EMIT */
408
};
409
410
struct {
411
bool h; /* VN_ASST1.f16 */
412
bool l; /* VN_ASST1.f16 */
413
};
414
415
struct {
416
bool bytes2; /* RROT_DOUBLE, FRSHIFT_DOUBLE */
417
bool result_word;
418
};
419
420
struct {
421
bool sqrt; /* FREXPM */
422
bool log; /* FREXPM */
423
};
424
425
struct {
426
enum bi_mode mode; /* FLOG_TABLE */
427
enum bi_precision precision; /* FLOG_TABLE */
428
bool divzero; /* FRSQ_APPROX, FRSQ */
429
};
430
};
431
} bi_instr;
432
433
/* Represents the assignment of slots for a given bi_tuple */
434
435
typedef struct {
436
/* Register to assign to each slot */
437
unsigned slot[4];
438
439
/* Read slots can be disabled */
440
bool enabled[2];
441
442
/* Configuration for slots 2/3 */
443
struct bifrost_reg_ctrl_23 slot23;
444
445
/* Fast-Access-Uniform RAM index */
446
uint8_t fau_idx;
447
448
/* Whether writes are actually for the last instruction */
449
bool first_instruction;
450
} bi_registers;
451
452
/* A bi_tuple contains two paired instruction pointers. If a slot is unfilled,
453
* leave it NULL; the emitter will fill in a nop. Instructions reference
454
* registers via slots which are assigned per tuple.
455
*/
456
457
typedef struct {
458
uint8_t fau_idx;
459
bi_registers regs;
460
bi_instr *fma;
461
bi_instr *add;
462
} bi_tuple;
463
464
struct bi_block;
465
466
typedef struct {
467
struct list_head link;
468
469
/* Link back up for branch calculations */
470
struct bi_block *block;
471
472
/* Architectural limit of 8 tuples/clause */
473
unsigned tuple_count;
474
bi_tuple tuples[8];
475
476
/* For scoreboarding -- the clause ID (this is not globally unique!)
477
* and its dependencies in terms of other clauses, computed during
478
* scheduling and used when emitting code. Dependencies expressed as a
479
* bitfield matching the hardware, except shifted by a clause (the
480
* shift back to the ISA's off-by-one encoding is worked out when
481
* emitting clauses) */
482
unsigned scoreboard_id;
483
uint8_t dependencies;
484
485
/* See ISA header for description */
486
enum bifrost_flow flow_control;
487
488
/* Can we prefetch the next clause? Usually it makes sense, except for
489
* clauses ending in unconditional branches */
490
bool next_clause_prefetch;
491
492
/* Assigned data register */
493
unsigned staging_register;
494
495
/* Corresponds to the usual bit but shifted by a clause */
496
bool staging_barrier;
497
498
/* Constants read by this clause. ISA limit. Must satisfy:
499
*
500
* constant_count + tuple_count <= 13
501
*
502
* Also implicitly constant_count <= tuple_count since a tuple only
503
* reads a single constant.
504
*/
505
uint64_t constants[8];
506
unsigned constant_count;
507
508
/* Index of a constant to be PC-relative */
509
unsigned pcrel_idx;
510
511
/* Branches encode a constant offset relative to the program counter
512
* with some magic flags. By convention, if there is a branch, its
513
* constant will be last. Set this flag to indicate this is required.
514
*/
515
bool branch_constant;
516
517
/* Unique in a clause */
518
enum bifrost_message_type message_type;
519
bi_instr *message;
520
521
/* Discard helper threads */
522
bool td;
523
} bi_clause;
524
525
typedef struct bi_block {
526
pan_block base; /* must be first */
527
528
/* If true, uses clauses; if false, uses instructions */
529
bool scheduled;
530
struct list_head clauses; /* list of bi_clause */
531
532
/* Post-RA liveness */
533
uint64_t reg_live_in, reg_live_out;
534
535
/* Flags available for pass-internal use */
536
uint8_t pass_flags;
537
} bi_block;
538
539
typedef struct {
540
const struct panfrost_compile_inputs *inputs;
541
nir_shader *nir;
542
struct pan_shader_info *info;
543
gl_shader_stage stage;
544
struct list_head blocks; /* list of bi_block */
545
struct hash_table_u64 *sysval_to_id;
546
uint32_t quirks;
547
unsigned arch;
548
549
/* During NIR->BIR */
550
bi_block *current_block;
551
bi_block *after_block;
552
bi_block *break_block;
553
bi_block *continue_block;
554
bool emitted_atest;
555
556
/* For creating temporaries */
557
unsigned ssa_alloc;
558
unsigned reg_alloc;
559
560
/* Analysis results */
561
bool has_liveness;
562
563
/* Mask of UBOs that need to be uploaded */
564
uint32_t ubo_mask;
565
566
/* Stats for shader-db */
567
unsigned instruction_count;
568
unsigned loop_count;
569
unsigned spills;
570
unsigned fills;
571
} bi_context;
572
573
static inline void
574
bi_remove_instruction(bi_instr *ins)
575
{
576
list_del(&ins->link);
577
}
578
579
enum bir_fau {
580
BIR_FAU_ZERO = 0,
581
BIR_FAU_LANE_ID = 1,
582
BIR_FAU_WRAP_ID = 2,
583
BIR_FAU_CORE_ID = 3,
584
BIR_FAU_FB_EXTENT = 4,
585
BIR_FAU_ATEST_PARAM = 5,
586
BIR_FAU_SAMPLE_POS_ARRAY = 6,
587
BIR_FAU_BLEND_0 = 8,
588
/* blend descs 1 - 7 */
589
BIR_FAU_TYPE_MASK = 15,
590
BIR_FAU_UNIFORM = (1 << 7),
591
BIR_FAU_HI = (1 << 8),
592
};
593
594
static inline bi_index
595
bi_fau(enum bir_fau value, bool hi)
596
{
597
return (bi_index) {
598
.type = BI_INDEX_FAU,
599
.value = value,
600
.swizzle = BI_SWIZZLE_H01,
601
.offset = hi ? 1 : 0
602
};
603
}
604
605
static inline unsigned
606
bi_max_temp(bi_context *ctx)
607
{
608
return (MAX2(ctx->reg_alloc, ctx->ssa_alloc) + 2) << 1;
609
}
610
611
static inline bi_index
612
bi_temp(bi_context *ctx)
613
{
614
return bi_get_index(ctx->ssa_alloc++, false, 0);
615
}
616
617
static inline bi_index
618
bi_temp_reg(bi_context *ctx)
619
{
620
return bi_get_index(ctx->reg_alloc++, true, 0);
621
}
622
623
/* Inline constants automatically, will be lowered out by bi_lower_fau where a
624
* constant is not allowed. load_const_to_scalar gaurantees that this makes
625
* sense */
626
627
static inline bi_index
628
bi_src_index(nir_src *src)
629
{
630
if (nir_src_is_const(*src) && nir_src_bit_size(*src) <= 32)
631
return bi_imm_u32(nir_src_as_uint(*src));
632
else if (src->is_ssa)
633
return bi_get_index(src->ssa->index, false, 0);
634
else {
635
assert(!src->reg.indirect);
636
return bi_get_index(src->reg.reg->index, true, 0);
637
}
638
}
639
640
static inline bi_index
641
bi_dest_index(nir_dest *dst)
642
{
643
if (dst->is_ssa)
644
return bi_get_index(dst->ssa.index, false, 0);
645
else {
646
assert(!dst->reg.indirect);
647
return bi_get_index(dst->reg.reg->index, true, 0);
648
}
649
}
650
651
static inline unsigned
652
bi_get_node(bi_index index)
653
{
654
if (bi_is_null(index) || index.type != BI_INDEX_NORMAL)
655
return ~0;
656
else
657
return (index.value << 1) | index.reg;
658
}
659
660
static inline bi_index
661
bi_node_to_index(unsigned node, unsigned node_count)
662
{
663
assert(node < node_count);
664
assert(node_count < ~0);
665
666
return bi_get_index(node >> 1, node & PAN_IS_REG, 0);
667
}
668
669
/* Iterators for Bifrost IR */
670
671
#define bi_foreach_block(ctx, v) \
672
list_for_each_entry(pan_block, v, &ctx->blocks, link)
673
674
#define bi_foreach_block_rev(ctx, v) \
675
list_for_each_entry_rev(pan_block, v, &ctx->blocks, link)
676
677
#define bi_foreach_block_from(ctx, from, v) \
678
list_for_each_entry_from(pan_block, v, from, &ctx->blocks, link)
679
680
#define bi_foreach_block_from_rev(ctx, from, v) \
681
list_for_each_entry_from_rev(pan_block, v, from, &ctx->blocks, link)
682
683
#define bi_foreach_instr_in_block(block, v) \
684
list_for_each_entry(bi_instr, v, &(block)->base.instructions, link)
685
686
#define bi_foreach_instr_in_block_rev(block, v) \
687
list_for_each_entry_rev(bi_instr, v, &(block)->base.instructions, link)
688
689
#define bi_foreach_instr_in_block_safe(block, v) \
690
list_for_each_entry_safe(bi_instr, v, &(block)->base.instructions, link)
691
692
#define bi_foreach_instr_in_block_safe_rev(block, v) \
693
list_for_each_entry_safe_rev(bi_instr, v, &(block)->base.instructions, link)
694
695
#define bi_foreach_instr_in_block_from(block, v, from) \
696
list_for_each_entry_from(bi_instr, v, from, &(block)->base.instructions, link)
697
698
#define bi_foreach_instr_in_block_from_rev(block, v, from) \
699
list_for_each_entry_from_rev(bi_instr, v, from, &(block)->base.instructions, link)
700
701
#define bi_foreach_clause_in_block(block, v) \
702
list_for_each_entry(bi_clause, v, &(block)->clauses, link)
703
704
#define bi_foreach_clause_in_block_rev(block, v) \
705
list_for_each_entry_rev(bi_clause, v, &(block)->clauses, link)
706
707
#define bi_foreach_clause_in_block_safe(block, v) \
708
list_for_each_entry_safe(bi_clause, v, &(block)->clauses, link)
709
710
#define bi_foreach_clause_in_block_from(block, v, from) \
711
list_for_each_entry_from(bi_clause, v, from, &(block)->clauses, link)
712
713
#define bi_foreach_clause_in_block_from_rev(block, v, from) \
714
list_for_each_entry_from_rev(bi_clause, v, from, &(block)->clauses, link)
715
716
#define bi_foreach_instr_global(ctx, v) \
717
bi_foreach_block(ctx, v_block) \
718
bi_foreach_instr_in_block((bi_block *) v_block, v)
719
720
#define bi_foreach_instr_global_rev(ctx, v) \
721
bi_foreach_block_rev(ctx, v_block) \
722
bi_foreach_instr_in_block_rev((bi_block *) v_block, v)
723
724
#define bi_foreach_instr_global_safe(ctx, v) \
725
bi_foreach_block(ctx, v_block) \
726
bi_foreach_instr_in_block_safe((bi_block *) v_block, v)
727
728
#define bi_foreach_instr_global_rev_safe(ctx, v) \
729
bi_foreach_block_rev(ctx, v_block) \
730
bi_foreach_instr_in_block_rev_safe((bi_block *) v_block, v)
731
732
#define bi_foreach_instr_in_tuple(tuple, v) \
733
for (bi_instr *v = (tuple)->fma ?: (tuple)->add; \
734
v != NULL; \
735
v = (v == (tuple)->add) ? NULL : (tuple)->add)
736
737
/* Based on set_foreach, expanded with automatic type casts */
738
739
#define bi_foreach_predecessor(blk, v) \
740
struct set_entry *_entry_##v; \
741
bi_block *v; \
742
for (_entry_##v = _mesa_set_next_entry(blk->base.predecessors, NULL), \
743
v = (bi_block *) (_entry_##v ? _entry_##v->key : NULL); \
744
_entry_##v != NULL; \
745
_entry_##v = _mesa_set_next_entry(blk->base.predecessors, _entry_##v), \
746
v = (bi_block *) (_entry_##v ? _entry_##v->key : NULL))
747
748
#define bi_foreach_src(ins, v) \
749
for (unsigned v = 0; v < ARRAY_SIZE(ins->src); ++v)
750
751
#define bi_foreach_dest(ins, v) \
752
for (unsigned v = 0; v < ARRAY_SIZE(ins->dest); ++v)
753
754
#define bi_foreach_instr_and_src_in_tuple(tuple, ins, s) \
755
bi_foreach_instr_in_tuple(tuple, ins) \
756
bi_foreach_src(ins, s)
757
758
static inline bi_instr *
759
bi_prev_op(bi_instr *ins)
760
{
761
return list_last_entry(&(ins->link), bi_instr, link);
762
}
763
764
static inline bi_instr *
765
bi_next_op(bi_instr *ins)
766
{
767
return list_first_entry(&(ins->link), bi_instr, link);
768
}
769
770
static inline pan_block *
771
pan_next_block(pan_block *block)
772
{
773
return list_first_entry(&(block->link), pan_block, link);
774
}
775
776
/* BIR manipulation */
777
778
bool bi_has_arg(bi_instr *ins, bi_index arg);
779
unsigned bi_count_read_registers(bi_instr *ins, unsigned src);
780
unsigned bi_count_write_registers(bi_instr *ins, unsigned dest);
781
bool bi_is_regfmt_16(enum bi_register_format fmt);
782
unsigned bi_writemask(bi_instr *ins, unsigned dest);
783
bi_clause * bi_next_clause(bi_context *ctx, pan_block *block, bi_clause *clause);
784
bool bi_side_effects(enum bi_opcode op);
785
786
void bi_print_instr(bi_instr *I, FILE *fp);
787
void bi_print_slots(bi_registers *regs, FILE *fp);
788
void bi_print_tuple(bi_tuple *tuple, FILE *fp);
789
void bi_print_clause(bi_clause *clause, FILE *fp);
790
void bi_print_block(bi_block *block, FILE *fp);
791
void bi_print_shader(bi_context *ctx, FILE *fp);
792
793
/* BIR passes */
794
795
void bi_analyze_helper_terminate(bi_context *ctx);
796
void bi_analyze_helper_requirements(bi_context *ctx);
797
void bi_opt_copy_prop(bi_context *ctx);
798
void bi_opt_cse(bi_context *ctx);
799
void bi_opt_mod_prop_forward(bi_context *ctx);
800
void bi_opt_mod_prop_backward(bi_context *ctx);
801
void bi_opt_dead_code_eliminate(bi_context *ctx);
802
void bi_opt_dce_post_ra(bi_context *ctx);
803
void bi_opt_push_ubo(bi_context *ctx);
804
void bi_opt_constant_fold(bi_context *ctx);
805
void bi_lower_swizzle(bi_context *ctx);
806
void bi_lower_fau(bi_context *ctx);
807
void bi_schedule(bi_context *ctx);
808
void bi_assign_scoreboard(bi_context *ctx);
809
void bi_register_allocate(bi_context *ctx);
810
811
/* Test suite */
812
int bi_test_scheduler(void);
813
int bi_test_packing(void);
814
int bi_test_packing_formats(void);
815
816
/* Liveness */
817
818
void bi_compute_liveness(bi_context *ctx);
819
void bi_liveness_ins_update(uint16_t *live, bi_instr *ins, unsigned max);
820
void bi_invalidate_liveness(bi_context *ctx);
821
822
void bi_postra_liveness(bi_context *ctx);
823
uint64_t bi_postra_liveness_ins(uint64_t live, bi_instr *ins);
824
825
/* Layout */
826
827
bool bi_can_insert_tuple(bi_clause *clause, bool constant);
828
unsigned bi_clause_quadwords(bi_clause *clause);
829
signed bi_block_offset(bi_context *ctx, bi_clause *start, bi_block *target);
830
bool bi_ec0_packed(unsigned tuple_count);
831
832
/* Check if there are no more instructions starting with a given block, this
833
* needs to recurse in case a shader ends with multiple empty blocks */
834
835
static inline bool
836
bi_is_terminal_block(bi_block *block)
837
{
838
return (block == NULL) ||
839
(list_is_empty(&block->base.instructions) &&
840
bi_is_terminal_block((bi_block *) block->base.successors[0]) &&
841
bi_is_terminal_block((bi_block *) block->base.successors[1]));
842
}
843
844
/* Code emit */
845
846
/* Returns the size of the final clause */
847
unsigned bi_pack(bi_context *ctx, struct util_dynarray *emission);
848
849
struct bi_packed_tuple {
850
uint64_t lo;
851
uint64_t hi;
852
};
853
854
void
855
bi_pack_format(struct util_dynarray *emission,
856
unsigned index,
857
struct bi_packed_tuple *tuples,
858
ASSERTED unsigned tuple_count,
859
uint64_t header, uint64_t ec0,
860
unsigned m0, bool z);
861
862
unsigned bi_pack_fma(bi_instr *I,
863
enum bifrost_packed_src src0,
864
enum bifrost_packed_src src1,
865
enum bifrost_packed_src src2,
866
enum bifrost_packed_src src3);
867
unsigned bi_pack_add(bi_instr *I,
868
enum bifrost_packed_src src0,
869
enum bifrost_packed_src src1,
870
enum bifrost_packed_src src2,
871
enum bifrost_packed_src src3);
872
873
/* Like in NIR, for use with the builder */
874
875
enum bi_cursor_option {
876
bi_cursor_after_block,
877
bi_cursor_before_instr,
878
bi_cursor_after_instr
879
};
880
881
typedef struct {
882
enum bi_cursor_option option;
883
884
union {
885
bi_block *block;
886
bi_instr *instr;
887
};
888
} bi_cursor;
889
890
static inline bi_cursor
891
bi_after_block(bi_block *block)
892
{
893
return (bi_cursor) {
894
.option = bi_cursor_after_block,
895
.block = block
896
};
897
}
898
899
static inline bi_cursor
900
bi_before_instr(bi_instr *instr)
901
{
902
return (bi_cursor) {
903
.option = bi_cursor_before_instr,
904
.instr = instr
905
};
906
}
907
908
static inline bi_cursor
909
bi_after_instr(bi_instr *instr)
910
{
911
return (bi_cursor) {
912
.option = bi_cursor_after_instr,
913
.instr = instr
914
};
915
}
916
917
/* Invariant: a tuple must be nonempty UNLESS it is the last tuple of a clause,
918
* in which case there must exist a nonempty penultimate tuple */
919
920
ATTRIBUTE_RETURNS_NONNULL static inline bi_instr *
921
bi_first_instr_in_tuple(bi_tuple *tuple)
922
{
923
bi_instr *instr = tuple->fma ?: tuple->add;
924
assert(instr != NULL);
925
return instr;
926
}
927
928
ATTRIBUTE_RETURNS_NONNULL static inline bi_instr *
929
bi_first_instr_in_clause(bi_clause *clause)
930
{
931
return bi_first_instr_in_tuple(&clause->tuples[0]);
932
}
933
934
ATTRIBUTE_RETURNS_NONNULL static inline bi_instr *
935
bi_last_instr_in_clause(bi_clause *clause)
936
{
937
bi_tuple tuple = clause->tuples[clause->tuple_count - 1];
938
bi_instr *instr = tuple.add ?: tuple.fma;
939
940
if (!instr) {
941
assert(clause->tuple_count >= 2);
942
tuple = clause->tuples[clause->tuple_count - 2];
943
instr = tuple.add ?: tuple.fma;
944
}
945
946
assert(instr != NULL);
947
return instr;
948
}
949
950
/* Implemented by expanding bi_foreach_instr_in_block_from(_rev) with the start
951
* (end) of the clause and adding a condition for the clause boundary */
952
953
#define bi_foreach_instr_in_clause(block, clause, pos) \
954
for (bi_instr *pos = LIST_ENTRY(bi_instr, bi_first_instr_in_clause(clause), link); \
955
(&pos->link != &(block)->base.instructions) \
956
&& (pos != bi_next_op(bi_last_instr_in_clause(clause))); \
957
pos = LIST_ENTRY(bi_instr, pos->link.next, link))
958
959
#define bi_foreach_instr_in_clause_rev(block, clause, pos) \
960
for (bi_instr *pos = LIST_ENTRY(bi_instr, bi_last_instr_in_clause(clause), link); \
961
(&pos->link != &(block)->base.instructions) \
962
&& pos != bi_prev_op(bi_first_instr_in_clause(clause)); \
963
pos = LIST_ENTRY(bi_instr, pos->link.prev, link))
964
965
static inline bi_cursor
966
bi_before_clause(bi_clause *clause)
967
{
968
return bi_before_instr(bi_first_instr_in_clause(clause));
969
}
970
971
static inline bi_cursor
972
bi_before_tuple(bi_tuple *tuple)
973
{
974
return bi_before_instr(bi_first_instr_in_tuple(tuple));
975
}
976
977
static inline bi_cursor
978
bi_after_clause(bi_clause *clause)
979
{
980
return bi_after_instr(bi_last_instr_in_clause(clause));
981
}
982
983
/* IR builder in terms of cursor infrastructure */
984
985
typedef struct {
986
bi_context *shader;
987
bi_cursor cursor;
988
} bi_builder;
989
990
static inline bi_builder
991
bi_init_builder(bi_context *ctx, bi_cursor cursor)
992
{
993
return (bi_builder) {
994
.shader = ctx,
995
.cursor = cursor
996
};
997
}
998
999
/* Insert an instruction at the cursor and move the cursor */
1000
1001
static inline void
1002
bi_builder_insert(bi_cursor *cursor, bi_instr *I)
1003
{
1004
switch (cursor->option) {
1005
case bi_cursor_after_instr:
1006
list_add(&I->link, &cursor->instr->link);
1007
cursor->instr = I;
1008
return;
1009
1010
case bi_cursor_after_block:
1011
list_addtail(&I->link, &cursor->block->base.instructions);
1012
cursor->option = bi_cursor_after_instr;
1013
cursor->instr = I;
1014
return;
1015
1016
case bi_cursor_before_instr:
1017
list_addtail(&I->link, &cursor->instr->link);
1018
cursor->option = bi_cursor_after_instr;
1019
cursor->instr = I;
1020
return;
1021
}
1022
1023
unreachable("Invalid cursor option");
1024
}
1025
1026
static inline unsigned
1027
bi_word_node(bi_index idx)
1028
{
1029
assert(idx.type == BI_INDEX_NORMAL && !idx.reg);
1030
return (idx.value << 2) | idx.offset;
1031
}
1032
1033
/* NIR passes */
1034
1035
bool bi_lower_divergent_indirects(nir_shader *shader, unsigned lanes);
1036
1037
#endif
1038
1039