1 /* 2 * Copyright (C) 2021 Alyssa Rosenzweig <alyssa (at) rosenzweig.io> 3 * Copyright (C) 2020 Collabora Ltd. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #ifndef __AGX_COMPILER_H 26 #define __AGX_COMPILER_H 27 28 #include "compiler/nir/nir.h" 29 #include "util/u_math.h" 30 #include "util/half_float.h" 31 #include "util/u_dynarray.h" 32 #include "agx_compile.h" 33 #include "agx_opcodes.h" 34 #include "agx_minifloat.h" 35 36 enum agx_dbg { 37 AGX_DBG_MSGS = BITFIELD_BIT(0), 38 AGX_DBG_SHADERS = BITFIELD_BIT(1), 39 AGX_DBG_SHADERDB = BITFIELD_BIT(2), 40 AGX_DBG_VERBOSE = BITFIELD_BIT(3), 41 AGX_DBG_INTERNAL = BITFIELD_BIT(4), 42 }; 43 44 extern int agx_debug; 45 46 /* r0-r127 inclusive, as pairs of 16-bits, gives 256 registers */ 47 #define AGX_NUM_REGS (256) 48 49 enum agx_index_type { 50 AGX_INDEX_NULL = 0, 51 AGX_INDEX_NORMAL = 1, 52 AGX_INDEX_IMMEDIATE = 2, 53 AGX_INDEX_UNIFORM = 3, 54 AGX_INDEX_REGISTER = 4, 55 AGX_INDEX_NIR_REGISTER = 5, 56 }; 57 58 enum agx_size { 59 AGX_SIZE_16 = 0, 60 AGX_SIZE_32 = 1, 61 AGX_SIZE_64 = 2 62 }; 63 64 typedef struct { 65 /* Sufficient for as many SSA values as we need. Immediates and uniforms fit in 16-bits */ 66 unsigned value : 22; 67 68 /* Indicates that this source kills the referenced value (because it is the 69 * last use in a block and the source is not live after the block). Set by 70 * liveness analysis. */ 71 bool kill : 1; 72 73 /* Cache hints */ 74 bool cache : 1; 75 bool discard : 1; 76 77 /* src - float modifiers */ 78 bool abs : 1; 79 bool neg : 1; 80 81 enum agx_size size : 2; 82 enum agx_index_type type : 3; 83 } agx_index; 84 85 static inline agx_index 86 agx_get_index(unsigned value, enum agx_size size) 87 { 88 return (agx_index) { 89 .type = AGX_INDEX_NORMAL, 90 .value = value, 91 .size = size 92 }; 93 } 94 95 static inline agx_index 96 agx_immediate(uint16_t imm) 97 { 98 return (agx_index) { 99 .type = AGX_INDEX_IMMEDIATE, 100 .value = imm, 101 .size = AGX_SIZE_32 102 }; 103 } 104 105 static inline agx_index 106 agx_immediate_f(float f) 107 { 108 assert(agx_minifloat_exact(f)); 109 return agx_immediate(agx_minifloat_encode(f)); 110 } 111 112 /* in half-words, specify r0h as 1, r1 as 2... */ 113 static inline agx_index 114 agx_register(uint8_t imm, enum agx_size size) 115 { 116 return (agx_index) { 117 .type = AGX_INDEX_REGISTER, 118 .value = imm, 119 .size = size 120 }; 121 } 122 123 static inline agx_index 124 agx_nir_register(unsigned imm, enum agx_size size) 125 { 126 return (agx_index) { 127 .type = AGX_INDEX_NIR_REGISTER, 128 .value = imm, 129 .size = size 130 }; 131 } 132 133 /* Also in half-words */ 134 static inline agx_index 135 agx_uniform(uint8_t imm, enum agx_size size) 136 { 137 return (agx_index) { 138 .type = AGX_INDEX_UNIFORM, 139 .value = imm, 140 .size = size 141 }; 142 } 143 144 static inline agx_index 145 agx_null() 146 { 147 return (agx_index) { .type = AGX_INDEX_NULL }; 148 } 149 150 static inline agx_index 151 agx_zero() 152 { 153 return agx_immediate(0); 154 } 155 156 /* IEEE 754 additive identity -0.0, stored as an 8-bit AGX minifloat: mantissa 157 * = exponent = 0, sign bit set */ 158 159 static inline agx_index 160 agx_negzero() 161 { 162 return agx_immediate(0x80); 163 } 164 165 static inline agx_index 166 agx_abs(agx_index idx) 167 { 168 idx.abs = true; 169 idx.neg = false; 170 return idx; 171 } 172 173 static inline agx_index 174 agx_neg(agx_index idx) 175 { 176 idx.neg ^= true; 177 return idx; 178 } 179 180 /* Replaces an index, preserving any modifiers */ 181 182 static inline agx_index 183 agx_replace_index(agx_index old, agx_index replacement) 184 { 185 replacement.abs = old.abs; 186 replacement.neg = old.neg; 187 return replacement; 188 } 189 190 static inline bool 191 agx_is_null(agx_index idx) 192 { 193 return idx.type == AGX_INDEX_NULL; 194 } 195 196 /* Compares equivalence as references */ 197 198 static inline bool 199 agx_is_equiv(agx_index left, agx_index right) 200 { 201 return (left.type == right.type) && (left.value == right.value); 202 } 203 204 #define AGX_MAX_DESTS 1 205 #define AGX_MAX_SRCS 5 206 207 enum agx_icond { 208 AGX_ICOND_UEQ = 0, 209 AGX_ICOND_ULT = 1, 210 AGX_ICOND_UGT = 2, 211 /* unknown */ 212 AGX_ICOND_SEQ = 4, 213 AGX_ICOND_SLT = 5, 214 AGX_ICOND_SGT = 6, 215 /* unknown */ 216 }; 217 218 enum agx_fcond { 219 AGX_FCOND_EQ = 0, 220 AGX_FCOND_LT = 1, 221 AGX_FCOND_GT = 2, 222 AGX_FCOND_LTN = 3, 223 /* unknown */ 224 AGX_FCOND_GE = 5, 225 AGX_FCOND_LE = 6, 226 AGX_FCOND_GTN = 7, 227 }; 228 229 enum agx_round { 230 AGX_ROUND_RTZ = 0, 231 AGX_ROUND_RTE = 1, 232 }; 233 234 enum agx_convert { 235 AGX_CONVERT_U8_TO_F = 0, 236 AGX_CONVERT_S8_TO_F = 1, 237 AGX_CONVERT_F_TO_U16 = 4, 238 AGX_CONVERT_F_TO_S16 = 5, 239 AGX_CONVERT_U16_TO_F = 6, 240 AGX_CONVERT_S16_TO_F = 7, 241 AGX_CONVERT_F_TO_U32 = 8, 242 AGX_CONVERT_F_TO_S32 = 9, 243 AGX_CONVERT_U32_TO_F = 10, 244 AGX_CONVERT_S32_TO_F = 11 245 }; 246 247 enum agx_lod_mode { 248 AGX_LOD_MODE_AUTO_LOD = 0, 249 AGX_LOD_MODE_LOD_MIN = 6, 250 AGX_LOD_GRAD = 8, 251 AGX_LOD_GRAD_MIN = 12 252 }; 253 254 enum agx_dim { 255 AGX_DIM_TEX_1D = 0, 256 AGX_DIM_TEX_1D_ARRAY = 1, 257 AGX_DIM_TEX_2D = 2, 258 AGX_DIM_TEX_2D_ARRAY = 3, 259 AGX_DIM_TEX_2D_MS = 4, 260 AGX_DIM_TEX_3D = 5, 261 AGX_DIM_TEX_CUBE = 6, 262 AGX_DIM_TEX_CUBE_ARRAY = 7 263 }; 264 265 /* Forward declare for branch target */ 266 struct agx_block; 267 268 typedef struct { 269 /* Must be first */ 270 struct list_head link; 271 272 enum agx_opcode op; 273 274 /* Data flow */ 275 agx_index dest[AGX_MAX_DESTS]; 276 agx_index src[AGX_MAX_SRCS]; 277 278 union { 279 uint32_t imm; 280 uint32_t writeout; 281 uint32_t truth_table; 282 uint32_t component; 283 uint32_t channels; 284 uint32_t bfi_mask; 285 enum agx_sr sr; 286 enum agx_icond icond; 287 enum agx_fcond fcond; 288 enum agx_format format; 289 enum agx_round round; 290 enum agx_lod_mode lod_mode; 291 struct agx_block *target; 292 }; 293 294 /* For load varying */ 295 bool perspective : 1; 296 297 /* Invert icond/fcond */ 298 bool invert_cond : 1; 299 300 /* TODO: Handle tex ops more efficient */ 301 enum agx_dim dim : 3; 302 303 /* Final st_vary op */ 304 bool last : 1; 305 306 /* Shift for a bitwise or memory op (conflicts with format for memory ops) */ 307 unsigned shift : 4; 308 309 /* Scoreboard index, 0 or 1. Leave as 0 for instructions that do not require 310 * scoreboarding (everything but memory load/store and texturing). */ 311 unsigned scoreboard : 1; 312 313 /* Number of nested control flow layers to jump by */ 314 unsigned nest : 2; 315 316 /* Output modifiers */ 317 bool saturate : 1; 318 unsigned mask : 4; 319 } agx_instr; 320 321 struct agx_block; 322 323 typedef struct agx_block { 324 /* Link to next block. Must be first */ 325 struct list_head link; 326 327 /* List of instructions emitted for the current block */ 328 struct list_head instructions; 329 330 /* Index of the block in source order */ 331 unsigned name; 332 333 /* Control flow graph */ 334 struct agx_block *successors[2]; 335 struct set *predecessors; 336 bool unconditional_jumps; 337 338 /* Liveness analysis results */ 339 BITSET_WORD *live_in; 340 BITSET_WORD *live_out; 341 342 /* Register allocation */ 343 BITSET_DECLARE(regs_out, AGX_NUM_REGS); 344 345 /* Offset of the block in the emitted binary */ 346 off_t offset; 347 348 /** Available for passes to use for metadata */ 349 uint8_t pass_flags; 350 } agx_block; 351 352 typedef struct { 353 nir_shader *nir; 354 gl_shader_stage stage; 355 struct list_head blocks; /* list of agx_block */ 356 struct agx_shader_info *out; 357 struct agx_shader_key *key; 358 359 /* Remapping table for varyings indexed by driver_location */ 360 unsigned varyings[AGX_MAX_VARYINGS]; 361 362 /* Handling phi nodes is still TODO while we bring up other parts of the 363 * driver. YOLO the mapping of nir_register to fixed hardware registers */ 364 unsigned *nir_regalloc; 365 366 /* We reserve the top (XXX: that hurts thread count) */ 367 unsigned max_register; 368 369 /* Place to start pushing new values */ 370 unsigned push_base; 371 372 /* For creating temporaries */ 373 unsigned alloc; 374 375 /* I don't really understand how writeout ops work yet */ 376 bool did_writeout; 377 378 /* Has r0l been zeroed yet due to control flow? */ 379 bool any_cf; 380 381 /** Computed metadata */ 382 bool has_liveness; 383 384 /* Number of nested control flow structures within the innermost loop. Since 385 * NIR is just loop and if-else, this is the number of nested if-else 386 * statements in the loop */ 387 unsigned loop_nesting; 388 389 /* During instruction selection, for inserting control flow */ 390 agx_block *current_block; 391 agx_block *continue_block; 392 agx_block *break_block; 393 agx_block *after_block; 394 395 /* Stats for shader-db */ 396 unsigned loop_count; 397 unsigned spills; 398 unsigned fills; 399 } agx_context; 400 401 static inline void 402 agx_remove_instruction(agx_instr *ins) 403 { 404 list_del(&ins->link); 405 } 406 407 static inline agx_index 408 agx_temp(agx_context *ctx, enum agx_size size) 409 { 410 return agx_get_index(ctx->alloc++, size); 411 } 412 413 static enum agx_size 414 agx_size_for_bits(unsigned bits) 415 { 416 switch (bits) { 417 case 1: 418 case 16: return AGX_SIZE_16; 419 case 32: return AGX_SIZE_32; 420 case 64: return AGX_SIZE_64; 421 default: unreachable("Invalid bitsize"); 422 } 423 } 424 425 static inline agx_index 426 agx_src_index(nir_src *src) 427 { 428 if (!src->is_ssa) { 429 return agx_nir_register(src->reg.reg->index, 430 agx_size_for_bits(nir_src_bit_size(*src))); 431 } 432 433 return agx_get_index(src->ssa->index, 434 agx_size_for_bits(nir_src_bit_size(*src))); 435 } 436 437 static inline agx_index 438 agx_dest_index(nir_dest *dst) 439 { 440 if (!dst->is_ssa) { 441 return agx_nir_register(dst->reg.reg->index, 442 agx_size_for_bits(nir_dest_bit_size(*dst))); 443 } 444 445 return agx_get_index(dst->ssa.index, 446 agx_size_for_bits(nir_dest_bit_size(*dst))); 447 } 448 449 /* Iterators for AGX IR */ 450 451 #define agx_foreach_block(ctx, v) \ 452 list_for_each_entry(agx_block, v, &ctx->blocks, link) 453 454 #define agx_foreach_block_rev(ctx, v) \ 455 list_for_each_entry_rev(agx_block, v, &ctx->blocks, link) 456 457 #define agx_foreach_block_from(ctx, from, v) \ 458 list_for_each_entry_from(agx_block, v, from, &ctx->blocks, link) 459 460 #define agx_foreach_block_from_rev(ctx, from, v) \ 461 list_for_each_entry_from_rev(agx_block, v, from, &ctx->blocks, link) 462 463 #define agx_foreach_instr_in_block(block, v) \ 464 list_for_each_entry(agx_instr, v, &(block)->instructions, link) 465 466 #define agx_foreach_instr_in_block_rev(block, v) \ 467 list_for_each_entry_rev(agx_instr, v, &(block)->instructions, link) 468 469 #define agx_foreach_instr_in_block_safe(block, v) \ 470 list_for_each_entry_safe(agx_instr, v, &(block)->instructions, link) 471 472 #define agx_foreach_instr_in_block_safe_rev(block, v) \ 473 list_for_each_entry_safe_rev(agx_instr, v, &(block)->instructions, link) 474 475 #define agx_foreach_instr_in_block_from(block, v, from) \ 476 list_for_each_entry_from(agx_instr, v, from, &(block)->instructions, link) 477 478 #define agx_foreach_instr_in_block_from_rev(block, v, from) \ 479 list_for_each_entry_from_rev(agx_instr, v, from, &(block)->instructions, link) 480 481 #define agx_foreach_instr_global(ctx, v) \ 482 agx_foreach_block(ctx, v_block) \ 483 agx_foreach_instr_in_block(v_block, v) 484 485 #define agx_foreach_instr_global_rev(ctx, v) \ 486 agx_foreach_block_rev(ctx, v_block) \ 487 agx_foreach_instr_in_block_rev(v_block, v) 488 489 #define agx_foreach_instr_global_safe(ctx, v) \ 490 agx_foreach_block(ctx, v_block) \ 491 agx_foreach_instr_in_block_safe(v_block, v) 492 493 #define agx_foreach_instr_global_safe_rev(ctx, v) \ 494 agx_foreach_block_rev(ctx, v_block) \ 495 agx_foreach_instr_in_block_safe_rev(v_block, v) 496 497 /* Based on set_foreach, expanded with automatic type casts */ 498 499 #define agx_foreach_successor(blk, v) \ 500 agx_block *v; \ 501 agx_block **_v; \ 502 for (_v = (agx_block **) &blk->successors[0], \ 503 v = *_v; \ 504 v != NULL && _v < (agx_block **) &blk->successors[2]; \ 505 _v++, v = *_v) \ 506 507 #define agx_foreach_predecessor(blk, v) \ 508 struct set_entry *_entry_##v; \ 509 agx_block *v; \ 510 for (_entry_##v = _mesa_set_next_entry(blk->predecessors, NULL), \ 511 v = (agx_block *) (_entry_##v ? _entry_##v->key : NULL); \ 512 _entry_##v != NULL; \ 513 _entry_##v = _mesa_set_next_entry(blk->predecessors, _entry_##v), \ 514 v = (agx_block *) (_entry_##v ? _entry_##v->key : NULL)) 515 516 #define agx_foreach_src(ins, v) \ 517 for (unsigned v = 0; v < ARRAY_SIZE(ins->src); ++v) 518 519 #define agx_foreach_dest(ins, v) \ 520 for (unsigned v = 0; v < ARRAY_SIZE(ins->dest); ++v) 521 522 static inline agx_instr * 523 agx_prev_op(agx_instr *ins) 524 { 525 return list_last_entry(&(ins->link), agx_instr, link); 526 } 527 528 static inline agx_instr * 529 agx_next_op(agx_instr *ins) 530 { 531 return list_first_entry(&(ins->link), agx_instr, link); 532 } 533 534 static inline agx_block * 535 agx_next_block(agx_block *block) 536 { 537 return list_first_entry(&(block->link), agx_block, link); 538 } 539 540 static inline agx_block * 541 agx_exit_block(agx_context *ctx) 542 { 543 agx_block *last = list_last_entry(&ctx->blocks, agx_block, link); 544 assert(!last->successors[0] && !last->successors[1]); 545 return last; 546 } 547 548 /* Like in NIR, for use with the builder */ 549 550 enum agx_cursor_option { 551 agx_cursor_after_block, 552 agx_cursor_before_instr, 553 agx_cursor_after_instr 554 }; 555 556 typedef struct { 557 enum agx_cursor_option option; 558 559 union { 560 agx_block *block; 561 agx_instr *instr; 562 }; 563 } agx_cursor; 564 565 static inline agx_cursor 566 agx_after_block(agx_block *block) 567 { 568 return (agx_cursor) { 569 .option = agx_cursor_after_block, 570 .block = block 571 }; 572 } 573 574 static inline agx_cursor 575 agx_before_instr(agx_instr *instr) 576 { 577 return (agx_cursor) { 578 .option = agx_cursor_before_instr, 579 .instr = instr 580 }; 581 } 582 583 static inline agx_cursor 584 agx_after_instr(agx_instr *instr) 585 { 586 return (agx_cursor) { 587 .option = agx_cursor_after_instr, 588 .instr = instr 589 }; 590 } 591 592 /* IR builder in terms of cursor infrastructure */ 593 594 typedef struct { 595 agx_context *shader; 596 agx_cursor cursor; 597 } agx_builder; 598 599 static inline agx_builder 600 agx_init_builder(agx_context *ctx, agx_cursor cursor) 601 { 602 return (agx_builder) { 603 .shader = ctx, 604 .cursor = cursor 605 }; 606 } 607 608 /* Insert an instruction at the cursor and move the cursor */ 609 610 static inline void 611 agx_builder_insert(agx_cursor *cursor, agx_instr *I) 612 { 613 switch (cursor->option) { 614 case agx_cursor_after_instr: 615 list_add(&I->link, &cursor->instr->link); 616 cursor->instr = I; 617 return; 618 619 case agx_cursor_after_block: 620 list_addtail(&I->link, &cursor->block->instructions); 621 cursor->option = agx_cursor_after_instr; 622 cursor->instr = I; 623 return; 624 625 case agx_cursor_before_instr: 626 list_addtail(&I->link, &cursor->instr->link); 627 cursor->option = agx_cursor_after_instr; 628 cursor->instr = I; 629 return; 630 } 631 632 unreachable("Invalid cursor option"); 633 } 634 635 /* Uniform file management */ 636 637 agx_index 638 agx_indexed_sysval(agx_context *ctx, enum agx_push_type type, enum agx_size size, 639 unsigned index, unsigned length); 640 641 /* Routines defined for AIR */ 642 643 void agx_print_instr(agx_instr *I, FILE *fp); 644 void agx_print_block(agx_block *block, FILE *fp); 645 void agx_print_shader(agx_context *ctx, FILE *fp); 646 void agx_optimizer(agx_context *ctx); 647 void agx_dce(agx_context *ctx); 648 void agx_ra(agx_context *ctx); 649 void agx_pack_binary(agx_context *ctx, struct util_dynarray *emission); 650 651 void agx_compute_liveness(agx_context *ctx); 652 void agx_liveness_ins_update(BITSET_WORD *live, agx_instr *I); 653 654 #endif 655