Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/lima/ir/pp/node.c
4574 views
1
/*
2
* Copyright (c) 2017 Lima Project
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, sub license,
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
12
* next paragraph) shall be included in all copies or substantial portions
13
* of the 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 NON-INFRINGEMENT. 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
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
* DEALINGS IN THE SOFTWARE.
22
*
23
*/
24
25
#include "util/u_math.h"
26
#include "util/ralloc.h"
27
#include "util/bitscan.h"
28
29
#include "ppir.h"
30
31
const ppir_op_info ppir_op_infos[] = {
32
[ppir_op_mov] = {
33
.name = "mov",
34
.slots = (int []) {
35
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_SCL_MUL,
36
PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_ALU_VEC_MUL,
37
PPIR_INSTR_SLOT_END
38
},
39
},
40
[ppir_op_abs] = {
41
.name = "abs",
42
},
43
[ppir_op_neg] = {
44
.name = "neg",
45
},
46
[ppir_op_sat] = {
47
.name = "sat",
48
},
49
[ppir_op_mul] = {
50
.name = "mul",
51
.slots = (int []) {
52
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
53
PPIR_INSTR_SLOT_END
54
},
55
},
56
[ppir_op_add] = {
57
.name = "add",
58
.slots = (int []) {
59
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
60
PPIR_INSTR_SLOT_END
61
},
62
},
63
[ppir_op_sum3] = {
64
.name = "sum3",
65
.slots = (int []) {
66
PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_END
67
},
68
},
69
[ppir_op_sum4] = {
70
.name = "sum4",
71
.slots = (int []) {
72
PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_END
73
},
74
},
75
[ppir_op_rsqrt] = {
76
.name = "rsqrt",
77
.slots = (int []) {
78
PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
79
},
80
},
81
[ppir_op_log2] = {
82
.name = "log2",
83
.slots = (int []) {
84
PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
85
},
86
},
87
[ppir_op_exp2] = {
88
.name = "exp2",
89
.slots = (int []) {
90
PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
91
},
92
},
93
[ppir_op_sqrt] = {
94
.name = "sqrt",
95
.slots = (int []) {
96
PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
97
},
98
},
99
[ppir_op_sin] = {
100
.name = "sin",
101
.slots = (int []) {
102
PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
103
},
104
},
105
[ppir_op_cos] = {
106
.name = "cos",
107
.slots = (int []) {
108
PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
109
},
110
},
111
[ppir_op_max] = {
112
.name = "max",
113
.slots = (int []) {
114
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_SCL_MUL,
115
PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_ALU_VEC_MUL,
116
PPIR_INSTR_SLOT_END
117
},
118
},
119
[ppir_op_min] = {
120
.name = "min",
121
.slots = (int []) {
122
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_SCL_MUL,
123
PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_ALU_VEC_MUL,
124
PPIR_INSTR_SLOT_END
125
},
126
},
127
[ppir_op_floor] = {
128
.name = "floor",
129
.slots = (int []) {
130
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
131
PPIR_INSTR_SLOT_END
132
},
133
},
134
[ppir_op_ceil] = {
135
.name = "ceil",
136
.slots = (int []) {
137
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
138
PPIR_INSTR_SLOT_END
139
},
140
},
141
[ppir_op_fract] = {
142
.name = "fract",
143
.slots = (int []) {
144
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
145
PPIR_INSTR_SLOT_END
146
},
147
},
148
[ppir_op_ddx] = {
149
.name = "ddx",
150
.slots = (int []) {
151
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
152
PPIR_INSTR_SLOT_END
153
},
154
},
155
[ppir_op_ddy] = {
156
.name = "ddy",
157
.slots = (int []) {
158
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
159
PPIR_INSTR_SLOT_END
160
},
161
},
162
[ppir_op_and] = {
163
.name = "and",
164
.slots = (int []) {
165
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
166
PPIR_INSTR_SLOT_END
167
},
168
},
169
[ppir_op_or] = {
170
.name = "or",
171
.slots = (int []) {
172
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
173
PPIR_INSTR_SLOT_END
174
},
175
},
176
[ppir_op_xor] = {
177
.name = "xor",
178
.slots = (int []) {
179
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
180
PPIR_INSTR_SLOT_END
181
},
182
},
183
[ppir_op_not] = {
184
.name = "not",
185
.slots = (int []) {
186
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
187
PPIR_INSTR_SLOT_END
188
},
189
},
190
[ppir_op_lt] = {
191
.name = "lt",
192
},
193
[ppir_op_le] = {
194
.name = "le",
195
},
196
[ppir_op_gt] = {
197
.name = "gt",
198
.slots = (int []) {
199
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_SCL_ADD,
200
PPIR_INSTR_SLOT_ALU_VEC_MUL, PPIR_INSTR_SLOT_ALU_VEC_ADD,
201
PPIR_INSTR_SLOT_END
202
},
203
},
204
[ppir_op_ge] = {
205
.name = "ge",
206
.slots = (int []) {
207
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_SCL_ADD,
208
PPIR_INSTR_SLOT_ALU_VEC_MUL, PPIR_INSTR_SLOT_ALU_VEC_ADD,
209
PPIR_INSTR_SLOT_END
210
},
211
},
212
[ppir_op_eq] = {
213
.name = "eq",
214
.slots = (int []) {
215
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_SCL_ADD,
216
PPIR_INSTR_SLOT_ALU_VEC_MUL, PPIR_INSTR_SLOT_ALU_VEC_ADD,
217
PPIR_INSTR_SLOT_END
218
},
219
},
220
[ppir_op_ne] = {
221
.name = "ne",
222
.slots = (int []) {
223
PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_SCL_ADD,
224
PPIR_INSTR_SLOT_ALU_VEC_MUL, PPIR_INSTR_SLOT_ALU_VEC_ADD,
225
PPIR_INSTR_SLOT_END
226
},
227
},
228
[ppir_op_select] = {
229
.name = "select",
230
.slots = (int []) {
231
PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
232
PPIR_INSTR_SLOT_END
233
},
234
},
235
[ppir_op_rcp] = {
236
.name = "rcp",
237
.slots = (int []) {
238
PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
239
},
240
},
241
[ppir_op_load_varying] = {
242
.name = "ld_var",
243
.type = ppir_node_type_load,
244
.slots = (int []) {
245
PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
246
},
247
},
248
[ppir_op_load_coords] = {
249
.name = "ld_coords",
250
.type = ppir_node_type_load,
251
.slots = (int []) {
252
PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
253
},
254
},
255
[ppir_op_load_coords_reg] = {
256
.name = "ld_coords_reg",
257
.type = ppir_node_type_load,
258
.slots = (int []) {
259
PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
260
},
261
},
262
[ppir_op_load_fragcoord] = {
263
.name = "ld_fragcoord",
264
.type = ppir_node_type_load,
265
.slots = (int []) {
266
PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
267
},
268
},
269
[ppir_op_load_pointcoord] = {
270
.name = "ld_pointcoord",
271
.type = ppir_node_type_load,
272
.slots = (int []) {
273
PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
274
},
275
},
276
[ppir_op_load_frontface] = {
277
.name = "ld_frontface",
278
.type = ppir_node_type_load,
279
.slots = (int []) {
280
PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
281
},
282
},
283
[ppir_op_load_uniform] = {
284
.name = "ld_uni",
285
.type = ppir_node_type_load,
286
.slots = (int []) {
287
PPIR_INSTR_SLOT_UNIFORM, PPIR_INSTR_SLOT_END
288
},
289
},
290
[ppir_op_load_texture] = {
291
.name = "ld_tex",
292
.type = ppir_node_type_load_texture,
293
.slots = (int []) {
294
PPIR_INSTR_SLOT_TEXLD, PPIR_INSTR_SLOT_END
295
},
296
},
297
[ppir_op_load_temp] = {
298
.name = "ld_temp",
299
.type = ppir_node_type_load,
300
.slots = (int []) {
301
PPIR_INSTR_SLOT_UNIFORM, PPIR_INSTR_SLOT_END
302
},
303
},
304
[ppir_op_const] = {
305
.name = "const",
306
.type = ppir_node_type_const,
307
},
308
[ppir_op_store_temp] = {
309
.name = "st_temp",
310
.type = ppir_node_type_store,
311
.slots = (int []) {
312
PPIR_INSTR_SLOT_STORE_TEMP, PPIR_INSTR_SLOT_END
313
},
314
},
315
[ppir_op_discard] = {
316
.name = "discard",
317
.type = ppir_node_type_discard,
318
.slots = (int []) {
319
PPIR_INSTR_SLOT_BRANCH, PPIR_INSTR_SLOT_END
320
},
321
},
322
[ppir_op_branch] = {
323
.name = "branch",
324
.type = ppir_node_type_branch,
325
.slots = (int []) {
326
PPIR_INSTR_SLOT_BRANCH, PPIR_INSTR_SLOT_END
327
},
328
},
329
[ppir_op_undef] = {
330
.name = "undef",
331
.type = ppir_node_type_alu,
332
.slots = (int []) {
333
},
334
},
335
[ppir_op_dummy] = {
336
.name = "dummy",
337
.type = ppir_node_type_alu,
338
.slots = (int []) {
339
},
340
},
341
};
342
343
void *ppir_node_create(ppir_block *block, ppir_op op, int index, unsigned mask)
344
{
345
ppir_compiler *comp = block->comp;
346
static const int node_size[] = {
347
[ppir_node_type_alu] = sizeof(ppir_alu_node),
348
[ppir_node_type_const] = sizeof(ppir_const_node),
349
[ppir_node_type_load] = sizeof(ppir_load_node),
350
[ppir_node_type_store] = sizeof(ppir_store_node),
351
[ppir_node_type_load_texture] = sizeof(ppir_load_texture_node),
352
[ppir_node_type_discard] = sizeof(ppir_discard_node),
353
[ppir_node_type_branch] = sizeof(ppir_branch_node),
354
};
355
356
ppir_node_type type = ppir_op_infos[op].type;
357
int size = node_size[type];
358
ppir_node *node = rzalloc_size(block, size);
359
if (!node)
360
return NULL;
361
362
list_inithead(&node->succ_list);
363
list_inithead(&node->pred_list);
364
365
if (index >= 0) {
366
if (mask) {
367
/* reg has 4 slots for each component write node */
368
while (mask)
369
comp->var_nodes[(index << 2) + comp->reg_base + u_bit_scan(&mask)] = node;
370
snprintf(node->name, sizeof(node->name), "reg%d", index);
371
} else {
372
comp->var_nodes[index] = node;
373
snprintf(node->name, sizeof(node->name), "ssa%d", index);
374
}
375
}
376
else
377
snprintf(node->name, sizeof(node->name), "new");
378
379
node->op = op;
380
node->type = type;
381
node->index = comp->cur_index++;
382
node->block = block;
383
384
return node;
385
}
386
387
void ppir_node_add_dep(ppir_node *succ, ppir_node *pred,
388
ppir_dep_type type)
389
{
390
/* don't add dep for two nodes from different block */
391
if (succ->block != pred->block) {
392
pred->succ_different_block = true;
393
return;
394
}
395
396
/* don't add duplicated dep */
397
ppir_node_foreach_pred(succ, dep) {
398
if (dep->pred == pred)
399
return;
400
}
401
402
ppir_dep *dep = ralloc(succ, ppir_dep);
403
dep->pred = pred;
404
dep->succ = succ;
405
dep->type = type;
406
list_addtail(&dep->pred_link, &succ->pred_list);
407
list_addtail(&dep->succ_link, &pred->succ_list);
408
}
409
410
void ppir_node_remove_dep(ppir_dep *dep)
411
{
412
list_del(&dep->succ_link);
413
list_del(&dep->pred_link);
414
ralloc_free(dep);
415
}
416
417
static void _ppir_node_replace_child(ppir_src *src, ppir_node *old_child, ppir_node *new_child)
418
{
419
ppir_dest *od = ppir_node_get_dest(old_child);
420
if (ppir_node_target_equal(src, od)) {
421
ppir_node_target_assign(src, new_child);
422
}
423
}
424
425
void ppir_node_replace_child(ppir_node *parent, ppir_node *old_child, ppir_node *new_child)
426
{
427
switch (parent->type) {
428
case ppir_node_type_alu:
429
{
430
ppir_alu_node *alu = ppir_node_to_alu(parent);
431
for (int i = 0; i < alu->num_src; i++)
432
_ppir_node_replace_child(alu->src + i, old_child, new_child);
433
break;
434
}
435
case ppir_node_type_branch:
436
{
437
ppir_branch_node *branch = ppir_node_to_branch(parent);
438
for (int i = 0; i < 2; i++)
439
_ppir_node_replace_child(branch->src + i, old_child, new_child);
440
break;
441
}
442
case ppir_node_type_load:
443
{
444
ppir_load_node *load = ppir_node_to_load(parent);
445
_ppir_node_replace_child(&load->src, old_child, new_child);
446
break;
447
}
448
case ppir_node_type_load_texture:
449
{
450
ppir_load_texture_node *load_texture = ppir_node_to_load_texture(parent);
451
for (int i = 0; i < load_texture->num_src; i++)
452
_ppir_node_replace_child(ppir_node_get_src(parent, i), old_child, new_child);
453
break;
454
}
455
case ppir_node_type_store:
456
{
457
ppir_store_node *store = ppir_node_to_store(parent);
458
_ppir_node_replace_child(&store->src, old_child, new_child);
459
break;
460
}
461
default:
462
ppir_debug("unknown node type in %s\n", __func__);
463
break;
464
}
465
}
466
467
void ppir_node_replace_pred(ppir_dep *dep, ppir_node *new_pred)
468
{
469
list_del(&dep->succ_link);
470
dep->pred = new_pred;
471
list_addtail(&dep->succ_link, &new_pred->succ_list);
472
}
473
474
ppir_dep *ppir_dep_for_pred(ppir_node *node, ppir_node *pred)
475
{
476
if (!pred)
477
return NULL;
478
479
if (node->block != pred->block)
480
return NULL;
481
482
ppir_node_foreach_pred(node, dep) {
483
if (dep->pred == pred)
484
return dep;
485
}
486
return NULL;
487
}
488
489
void ppir_node_replace_all_succ(ppir_node *dst, ppir_node *src)
490
{
491
ppir_node_foreach_succ_safe(src, dep) {
492
ppir_node_replace_pred(dep, dst);
493
ppir_node_replace_child(dep->succ, src, dst);
494
}
495
}
496
497
void ppir_node_delete(ppir_node *node)
498
{
499
ppir_node_foreach_succ_safe(node, dep)
500
ppir_node_remove_dep(dep);
501
502
ppir_node_foreach_pred_safe(node, dep)
503
ppir_node_remove_dep(dep);
504
505
list_del(&node->list);
506
ralloc_free(node);
507
}
508
509
static void ppir_node_print_dest(ppir_dest *dest)
510
{
511
switch (dest->type) {
512
case ppir_target_ssa:
513
printf("ssa%d", dest->ssa.index);
514
break;
515
case ppir_target_pipeline:
516
printf("pipeline %d", dest->pipeline);
517
break;
518
case ppir_target_register:
519
printf("reg %d", dest->reg->index);
520
break;
521
}
522
}
523
524
static void ppir_node_print_src(ppir_src *src)
525
{
526
switch (src->type) {
527
case ppir_target_ssa: {
528
if (src->node)
529
printf("ssa node %d", src->node->index);
530
else
531
printf("ssa idx %d", src->ssa ? src->ssa->index : -1);
532
break;
533
}
534
case ppir_target_pipeline:
535
if (src->node)
536
printf("pipeline %d node %d", src->pipeline, src->node->index);
537
else
538
printf("pipeline %d", src->pipeline);
539
break;
540
case ppir_target_register:
541
printf("reg %d", src->reg->index);
542
break;
543
}
544
}
545
546
static void ppir_node_print_node(ppir_node *node, int space)
547
{
548
for (int i = 0; i < space; i++)
549
printf(" ");
550
551
printf("%s%d: %s %s: ", node->printed && !ppir_node_is_leaf(node) ? "+" : "",
552
node->index, ppir_op_infos[node->op].name, node->name);
553
554
ppir_dest *dest = ppir_node_get_dest(node);
555
if (dest) {
556
printf("dest: ");
557
ppir_node_print_dest(dest);
558
}
559
560
if (ppir_node_get_src_num(node) > 0) {
561
printf(" src: ");
562
}
563
for (int i = 0; i < ppir_node_get_src_num(node); i++) {
564
ppir_node_print_src(ppir_node_get_src(node, i));
565
if (i != (ppir_node_get_src_num(node) - 1))
566
printf(", ");
567
}
568
printf("\n");
569
570
if (!node->printed) {
571
ppir_node_foreach_pred(node, dep) {
572
ppir_node *pred = dep->pred;
573
ppir_node_print_node(pred, space + 2);
574
}
575
576
node->printed = true;
577
}
578
}
579
580
void ppir_node_print_prog(ppir_compiler *comp)
581
{
582
if (!(lima_debug & LIMA_DEBUG_PP))
583
return;
584
585
list_for_each_entry(ppir_block, block, &comp->block_list, list) {
586
list_for_each_entry(ppir_node, node, &block->node_list, list) {
587
node->printed = false;
588
}
589
}
590
591
printf("========prog========\n");
592
list_for_each_entry(ppir_block, block, &comp->block_list, list) {
593
printf("-------block %3d-------\n", block->index);
594
list_for_each_entry(ppir_node, node, &block->node_list, list) {
595
if (ppir_node_is_root(node))
596
ppir_node_print_node(node, 0);
597
}
598
}
599
printf("====================\n");
600
}
601
602
static ppir_node *ppir_node_insert_mov_local(ppir_node *node)
603
{
604
ppir_node *move = ppir_node_create(node->block, ppir_op_mov, -1, 0);
605
if (unlikely(!move))
606
return NULL;
607
608
ppir_dest *dest = ppir_node_get_dest(node);
609
ppir_alu_node *alu = ppir_node_to_alu(move);
610
alu->dest = *dest;
611
alu->num_src = 1;
612
ppir_node_target_assign(alu->src, node);
613
614
for (int s = 0; s < 4; s++)
615
alu->src->swizzle[s] = s;
616
617
ppir_node_replace_all_succ(move, node);
618
ppir_node_add_dep(move, node, ppir_dep_src);
619
list_addtail(&move->list, &node->list);
620
621
if (node->is_end) {
622
node->is_end = false;
623
move->is_end = true;
624
}
625
626
return move;
627
}
628
629
ppir_node *ppir_node_insert_mov(ppir_node *old)
630
{
631
ppir_node *move = ppir_node_insert_mov_local(old);
632
ppir_compiler *comp = old->block->comp;
633
634
list_for_each_entry(ppir_block, block, &comp->block_list, list) {
635
if (old->block == block)
636
continue;
637
list_for_each_entry_safe(ppir_node, node, &block->node_list, list) {
638
for (int i = 0; i < ppir_node_get_src_num(node); i++){
639
ppir_src *src = ppir_node_get_src(node, i);
640
if (!src)
641
continue;
642
if (src->node == old)
643
ppir_node_target_assign(src, move);
644
}
645
}
646
}
647
648
return move;
649
}
650
651
bool ppir_node_has_single_src_succ(ppir_node *node)
652
{
653
if (ppir_node_has_single_succ(node) &&
654
list_first_entry(&node->succ_list,
655
ppir_dep, succ_link)->type == ppir_dep_src)
656
return true;
657
658
int cnt = 0;
659
ppir_node_foreach_succ(node, dep) {
660
if (dep->type != ppir_dep_src)
661
continue;
662
cnt++;
663
}
664
665
return cnt == 1;
666
}
667
668