1 /* HSAIL and BRIG related macros and definitions. 2 Copyright (C) 2013-2018 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GCC is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #ifndef HSA_H 21 #define HSA_H 22 23 #include "hsa-brig-format.h" 24 #include "is-a.h" 25 #include "predict.h" 26 #include "tree.h" 27 #include "vec.h" 28 #include "hash-table.h" 29 #include "basic-block.h" 30 #include "bitmap.h" 31 32 33 /* Return true if the compiler should produce HSAIL. */ 34 35 static inline bool 36 hsa_gen_requested_p (void) 37 { 38 #ifndef ENABLE_HSA 39 return false; 40 #endif 41 return !flag_disable_hsa; 42 } 43 44 /* Standard warning message if we failed to generate HSAIL for a function. */ 45 46 #define HSA_SORRY_MSG "could not emit HSAIL for the function" 47 48 class hsa_op_immed; 49 class hsa_op_cst_list; 50 class hsa_insn_basic; 51 class hsa_op_address; 52 class hsa_op_reg; 53 class hsa_bb; 54 55 /* Class representing an input argument, output argument (result) or a 56 variable, that will eventually end up being a symbol directive. */ 57 58 struct hsa_symbol 59 { 60 /* Constructor. */ 61 hsa_symbol (BrigType16_t type, BrigSegment8_t segment, 62 BrigLinkage8_t linkage, bool global_scope_p = false, 63 BrigAllocation allocation = BRIG_ALLOCATION_AUTOMATIC, 64 BrigAlignment8_t align = BRIG_ALIGNMENT_8); 65 66 /* Return total size of the symbol. */ 67 unsigned HOST_WIDE_INT total_byte_size (); 68 69 /* Fill in those values into the symbol according to DECL, which are 70 determined independently from whether it is parameter, result, 71 or a variable, local or global. */ 72 void fillup_for_decl (tree decl); 73 74 /* Pointer to the original tree, which is PARM_DECL for input parameters and 75 RESULT_DECL for the output parameters. Also can be CONST_DECL for Fortran 76 constants which need to be put into readonly segment. */ 77 tree m_decl; 78 79 /* Name of the symbol, that will be written into output and dumps. Can be 80 NULL, see name_number below. */ 81 const char *m_name; 82 83 /* If name is NULL, artificial name will be formed from the segment name and 84 this number. */ 85 int m_name_number; 86 87 /* Once written, this is the offset of the associated symbol directive. Zero 88 means the symbol has not been written yet. */ 89 unsigned m_directive_offset; 90 91 /* HSA type of the parameter. */ 92 BrigType16_t m_type; 93 94 /* The HSA segment this will eventually end up in. */ 95 BrigSegment8_t m_segment; 96 97 /* The HSA kind of linkage. */ 98 BrigLinkage8_t m_linkage; 99 100 /* Array dimension, if non-zero. */ 101 unsigned HOST_WIDE_INT m_dim; 102 103 /* Constant value, used for string constants. */ 104 hsa_op_immed *m_cst_value; 105 106 /* Is in global scope. */ 107 bool m_global_scope_p; 108 109 /* True if an error has been seen for the symbol. */ 110 bool m_seen_error; 111 112 /* Symbol allocation. */ 113 BrigAllocation m_allocation; 114 115 /* Flag used for global variables if a variable is already emitted or not. */ 116 bool m_emitted_to_brig; 117 118 /* Alignment of the symbol. */ 119 BrigAlignment8_t m_align; 120 121 private: 122 /* Default constructor. */ 123 hsa_symbol (); 124 }; 125 126 /* Abstract class for HSA instruction operands. */ 127 128 class hsa_op_base 129 { 130 public: 131 /* Next operand scheduled to be written when writing BRIG operand 132 section. */ 133 hsa_op_base *m_next; 134 135 /* Offset to which the associated operand structure will be written. Zero if 136 yet not scheduled for writing. */ 137 unsigned m_brig_op_offset; 138 139 /* The type of a particular operand. */ 140 BrigKind16_t m_kind; 141 142 protected: 143 hsa_op_base (BrigKind16_t k); 144 private: 145 /* Make the default constructor inaccessible. */ 146 hsa_op_base () {} 147 }; 148 149 /* Common abstract ancestor for operands which have a type. */ 150 151 class hsa_op_with_type : public hsa_op_base 152 { 153 public: 154 /* The type. */ 155 BrigType16_t m_type; 156 157 /* Convert an operand to a destination type DTYPE and attach insns 158 to HBB if needed. */ 159 hsa_op_with_type *get_in_type (BrigType16_t dtype, hsa_bb *hbb); 160 /* If this operand has integer type smaller than 32 bits, extend it to 32 161 bits, adding instructions to HBB if needed. */ 162 hsa_op_with_type *extend_int_to_32bit (hsa_bb *hbb); 163 164 protected: 165 hsa_op_with_type (BrigKind16_t k, BrigType16_t t); 166 private: 167 /* Make the default constructor inaccessible. */ 168 hsa_op_with_type () : hsa_op_base (BRIG_KIND_NONE) {} 169 }; 170 171 /* An immediate HSA operand. */ 172 173 class hsa_op_immed : public hsa_op_with_type 174 { 175 public: 176 hsa_op_immed (tree tree_val, bool min32int = true); 177 hsa_op_immed (HOST_WIDE_INT int_value, BrigType16_t type); 178 void *operator new (size_t); 179 ~hsa_op_immed (); 180 void set_type (BrigKind16_t t); 181 182 /* Function returns pointer to a buffer that contains binary representation 183 of the immeadiate value. The buffer has length of BRIG_SIZE and 184 a caller is responsible for deallocation of the buffer. */ 185 char *emit_to_buffer (unsigned *brig_size); 186 187 /* Value as represented by middle end. */ 188 tree m_tree_value; 189 190 /* Integer value representation. */ 191 HOST_WIDE_INT m_int_value; 192 193 private: 194 /* Make the default constructor inaccessible. */ 195 hsa_op_immed (); 196 /* All objects are deallocated by destroying their pool, so make delete 197 inaccessible too. */ 198 void operator delete (void *) {} 199 }; 200 201 /* Report whether or not P is a an immediate operand. */ 202 203 template <> 204 template <> 205 inline bool 206 is_a_helper <hsa_op_immed *>::test (hsa_op_base *p) 207 { 208 return p->m_kind == BRIG_KIND_OPERAND_CONSTANT_BYTES; 209 } 210 211 /* Likewise, but for a more specified base. */ 212 213 template <> 214 template <> 215 inline bool 216 is_a_helper <hsa_op_immed *>::test (hsa_op_with_type *p) 217 { 218 return p->m_kind == BRIG_KIND_OPERAND_CONSTANT_BYTES; 219 } 220 221 222 /* HSA register operand. */ 223 224 class hsa_op_reg : public hsa_op_with_type 225 { 226 friend class hsa_insn_basic; 227 friend class hsa_insn_phi; 228 public: 229 hsa_op_reg (BrigType16_t t); 230 void *operator new (size_t); 231 232 /* Verify register operand. */ 233 void verify_ssa (); 234 235 /* If NON-NULL, gimple SSA that we come from. NULL if none. */ 236 tree m_gimple_ssa; 237 238 /* Defining instruction while still in the SSA. */ 239 hsa_insn_basic *m_def_insn; 240 241 /* If the register allocator decides to spill the register, this is the 242 appropriate spill symbol. */ 243 hsa_symbol *m_spill_sym; 244 245 /* Number of this register structure in the order in which they were 246 allocated. */ 247 int m_order; 248 int m_lr_begin, m_lr_end; 249 250 /* Zero if the register is not yet allocated. After, allocation, this must 251 be 'c', 's', 'd' or 'q'. */ 252 char m_reg_class; 253 /* If allocated, the number of the HW register (within its HSA register 254 class). */ 255 char m_hard_num; 256 257 private: 258 /* Make the default constructor inaccessible. */ 259 hsa_op_reg () : hsa_op_with_type (BRIG_KIND_NONE, BRIG_TYPE_NONE) {} 260 /* All objects are deallocated by destroying their pool, so make delete 261 inaccessible too. */ 262 void operator delete (void *) {} 263 /* Set definition where the register is defined. */ 264 void set_definition (hsa_insn_basic *insn); 265 /* Uses of the value while still in SSA. */ 266 auto_vec <hsa_insn_basic *> m_uses; 267 }; 268 269 /* Report whether or not P is a register operand. */ 270 271 template <> 272 template <> 273 inline bool 274 is_a_helper <hsa_op_reg *>::test (hsa_op_base *p) 275 { 276 return p->m_kind == BRIG_KIND_OPERAND_REGISTER; 277 } 278 279 /* Report whether or not P is a register operand. */ 280 281 template <> 282 template <> 283 inline bool 284 is_a_helper <hsa_op_reg *>::test (hsa_op_with_type *p) 285 { 286 return p->m_kind == BRIG_KIND_OPERAND_REGISTER; 287 } 288 289 /* An address HSA operand. */ 290 291 class hsa_op_address : public hsa_op_base 292 { 293 public: 294 /* set up a new address operand consisting of base symbol SYM, register R and 295 immediate OFFSET. If the machine model is not large and offset is 64 bit, 296 the upper, 32 bits have to be zero. */ 297 hsa_op_address (hsa_symbol *sym, hsa_op_reg *reg, 298 HOST_WIDE_INT offset = 0); 299 300 void *operator new (size_t); 301 302 /* Set up a new address operand consisting of base symbol SYM and 303 immediate OFFSET. If the machine model is not large and offset is 64 bit, 304 the upper, 32 bits have to be zero. */ 305 hsa_op_address (hsa_symbol *sym, HOST_WIDE_INT offset = 0); 306 307 /* Set up a new address operand consisting of register R and 308 immediate OFFSET. If the machine model is not large and offset is 64 bit, 309 the upper, 32 bits have to be zero. */ 310 hsa_op_address (hsa_op_reg *reg, HOST_WIDE_INT offset = 0); 311 312 /* Symbol base of the address. Can be NULL if there is none. */ 313 hsa_symbol *m_symbol; 314 315 /* Register offset. Can be NULL if there is none. */ 316 hsa_op_reg *m_reg; 317 318 /* Immediate byte offset. */ 319 HOST_WIDE_INT m_imm_offset; 320 321 private: 322 /* Make the default constructor inaccessible. */ 323 hsa_op_address () : hsa_op_base (BRIG_KIND_NONE) {} 324 /* All objects are deallocated by destroying their pool, so make delete 325 inaccessible too. */ 326 void operator delete (void *) {} 327 }; 328 329 /* Report whether or not P is an address operand. */ 330 331 template <> 332 template <> 333 inline bool 334 is_a_helper <hsa_op_address *>::test (hsa_op_base *p) 335 { 336 return p->m_kind == BRIG_KIND_OPERAND_ADDRESS; 337 } 338 339 /* A reference to code HSA operand. It can be either reference 340 to a start of a BB or a start of a function. */ 341 342 class hsa_op_code_ref : public hsa_op_base 343 { 344 public: 345 hsa_op_code_ref (); 346 347 /* Offset in the code section that this refers to. */ 348 unsigned m_directive_offset; 349 }; 350 351 /* Report whether or not P is a code reference operand. */ 352 353 template <> 354 template <> 355 inline bool 356 is_a_helper <hsa_op_code_ref *>::test (hsa_op_base *p) 357 { 358 return p->m_kind == BRIG_KIND_OPERAND_CODE_REF; 359 } 360 361 /* Code list HSA operand. */ 362 363 class hsa_op_code_list: public hsa_op_base 364 { 365 public: 366 hsa_op_code_list (unsigned elements); 367 void *operator new (size_t); 368 369 /* Offset to variable-sized array in hsa_data section, where 370 are offsets to entries in the hsa_code section. */ 371 auto_vec<unsigned> m_offsets; 372 private: 373 /* Make the default constructor inaccessible. */ 374 hsa_op_code_list () : hsa_op_base (BRIG_KIND_NONE) {} 375 /* All objects are deallocated by destroying their pool, so make delete 376 inaccessible too. */ 377 void operator delete (void *) {} 378 }; 379 380 /* Report whether or not P is a code list operand. */ 381 382 template <> 383 template <> 384 inline bool 385 is_a_helper <hsa_op_code_list *>::test (hsa_op_base *p) 386 { 387 return p->m_kind == BRIG_KIND_OPERAND_CODE_LIST; 388 } 389 390 /* Operand list HSA operand. */ 391 392 class hsa_op_operand_list: public hsa_op_base 393 { 394 public: 395 hsa_op_operand_list (unsigned elements); 396 ~hsa_op_operand_list (); 397 void *operator new (size_t); 398 399 /* Offset to variable-sized array in hsa_data section, where 400 are offsets to entries in the hsa_code section. */ 401 auto_vec<unsigned> m_offsets; 402 private: 403 /* Make the default constructor inaccessible. */ 404 hsa_op_operand_list () : hsa_op_base (BRIG_KIND_NONE) {} 405 /* All objects are deallocated by destroying their pool, so make delete 406 inaccessible too. */ 407 void operator delete (void *) {} 408 }; 409 410 /* Report whether or not P is a code list operand. */ 411 412 template <> 413 template <> 414 inline bool 415 is_a_helper <hsa_op_operand_list *>::test (hsa_op_base *p) 416 { 417 return p->m_kind == BRIG_KIND_OPERAND_OPERAND_LIST; 418 } 419 420 /* Opcodes of instructions that are not part of HSA but that we use to 421 represent it nevertheless. */ 422 423 #define HSA_OPCODE_PHI (-1) 424 #define HSA_OPCODE_ARG_BLOCK (-2) 425 426 /* The number of operand pointers we can directly in an instruction. */ 427 #define HSA_BRIG_INT_STORAGE_OPERANDS 5 428 429 /* Class representing an HSA instruction. Unlike typical ancestors for 430 specialized classes, this one is also directly used for all instructions 431 that are then represented as BrigInstBasic. */ 432 433 class hsa_insn_basic 434 { 435 public: 436 hsa_insn_basic (unsigned nops, int opc); 437 hsa_insn_basic (unsigned nops, int opc, BrigType16_t t, 438 hsa_op_base *arg0 = NULL, 439 hsa_op_base *arg1 = NULL, 440 hsa_op_base *arg2 = NULL, 441 hsa_op_base *arg3 = NULL); 442 443 void *operator new (size_t); 444 void set_op (int index, hsa_op_base *op); 445 hsa_op_base *get_op (int index); 446 hsa_op_base **get_op_addr (int index); 447 unsigned int operand_count (); 448 void verify (); 449 unsigned input_count (); 450 unsigned num_used_ops (); 451 void set_output_in_type (hsa_op_reg *dest, unsigned op_index, hsa_bb *hbb); 452 bool op_output_p (unsigned opnum); 453 454 /* The previous and next instruction in the basic block. */ 455 hsa_insn_basic *m_prev, *m_next; 456 457 /* Basic block this instruction belongs to. */ 458 basic_block m_bb; 459 460 /* Operand code distinguishing different types of instructions. Eventually 461 these should only be BRIG_INST_* values from the BrigOpcode16_t range but 462 initially we use negative values for PHI nodes and such. */ 463 int m_opcode; 464 465 /* Linearized number assigned to the instruction by HSA RA. */ 466 int m_number; 467 468 /* Type of the destination of the operations. */ 469 BrigType16_t m_type; 470 471 /* BRIG offset of the instruction in code section. */ 472 unsigned int m_brig_offset; 473 474 private: 475 /* Make the default constructor inaccessible. */ 476 hsa_insn_basic () {} 477 /* All objects are deallocated by destroying their pool, so make delete 478 inaccessible too. */ 479 void operator delete (void *) {} 480 /* The individual operands. All instructions but PHI nodes have five or 481 fewer instructions and so will fit the internal storage. */ 482 /* TODO: Vast majority of instructions have three or fewer operands, so we 483 may actually try reducing it. */ 484 auto_vec<hsa_op_base *, HSA_BRIG_INT_STORAGE_OPERANDS> m_operands; 485 }; 486 487 /* Class representing a PHI node of the SSA form of HSA virtual 488 registers. */ 489 490 class hsa_insn_phi : public hsa_insn_basic 491 { 492 public: 493 hsa_insn_phi (unsigned nops, hsa_op_reg *dst); 494 495 /* Destination. */ 496 hsa_op_reg *m_dest; 497 498 private: 499 /* Make the default constructor inaccessible. */ 500 hsa_insn_phi () : hsa_insn_basic (1, HSA_OPCODE_PHI) {} 501 }; 502 503 /* Report whether or not P is a PHI node. */ 504 505 template <> 506 template <> 507 inline bool 508 is_a_helper <hsa_insn_phi *>::test (hsa_insn_basic *p) 509 { 510 return p->m_opcode == HSA_OPCODE_PHI; 511 } 512 513 /* HSA instruction for */ 514 class hsa_insn_br : public hsa_insn_basic 515 { 516 public: 517 hsa_insn_br (unsigned nops, int opc, BrigType16_t t, BrigWidth8_t width, 518 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL, 519 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL); 520 521 /* Number of work-items affected in the same way by the instruction. */ 522 BrigWidth8_t m_width; 523 524 private: 525 /* Make the default constructor inaccessible. */ 526 hsa_insn_br () : hsa_insn_basic (0, BRIG_OPCODE_BR) {} 527 }; 528 529 /* Return true if P is a branching/synchronization instruction. */ 530 531 template <> 532 template <> 533 inline bool 534 is_a_helper <hsa_insn_br *>::test (hsa_insn_basic *p) 535 { 536 return p->m_opcode == BRIG_OPCODE_BARRIER 537 || p->m_opcode == BRIG_OPCODE_BR; 538 } 539 540 /* HSA instruction for conditional branches. Structurally the same as 541 hsa_insn_br but we represent it specially because of inherent control 542 flow it represents. */ 543 544 class hsa_insn_cbr : public hsa_insn_br 545 { 546 public: 547 hsa_insn_cbr (hsa_op_reg *ctrl); 548 549 private: 550 /* Make the default constructor inaccessible. */ 551 hsa_insn_cbr () : hsa_insn_br (0, BRIG_OPCODE_CBR, BRIG_TYPE_B1, 552 BRIG_WIDTH_1) {} 553 }; 554 555 /* Report whether P is a contitional branching instruction. */ 556 557 template <> 558 template <> 559 inline bool 560 is_a_helper <hsa_insn_cbr *>::test (hsa_insn_basic *p) 561 { 562 return p->m_opcode == BRIG_OPCODE_CBR; 563 } 564 565 /* HSA instruction for switch branches. */ 566 567 class hsa_insn_sbr : public hsa_insn_basic 568 { 569 public: 570 hsa_insn_sbr (hsa_op_reg *index, unsigned jump_count); 571 572 /* Default destructor. */ 573 ~hsa_insn_sbr (); 574 575 void replace_all_labels (basic_block old_bb, basic_block new_bb); 576 577 /* Width as described in HSA documentation. */ 578 BrigWidth8_t m_width; 579 580 /* Jump table. */ 581 vec <basic_block> m_jump_table; 582 583 /* Code list for label references. */ 584 hsa_op_code_list *m_label_code_list; 585 586 private: 587 /* Make the default constructor inaccessible. */ 588 hsa_insn_sbr () : hsa_insn_basic (1, BRIG_OPCODE_SBR) {} 589 }; 590 591 /* Report whether P is a switch branching instruction. */ 592 593 template <> 594 template <> 595 inline bool 596 is_a_helper <hsa_insn_sbr *>::test (hsa_insn_basic *p) 597 { 598 return p->m_opcode == BRIG_OPCODE_SBR; 599 } 600 601 /* HSA instruction for comparisons. */ 602 603 class hsa_insn_cmp : public hsa_insn_basic 604 { 605 public: 606 hsa_insn_cmp (BrigCompareOperation8_t cmp, BrigType16_t t, 607 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL, 608 hsa_op_base *arg2 = NULL); 609 610 /* Source type should be derived from operand types. */ 611 612 /* The comparison operation. */ 613 BrigCompareOperation8_t m_compare; 614 615 /* TODO: Modifiers and packing control are missing but so are everywhere 616 else. */ 617 private: 618 /* Make the default constructor inaccessible. */ 619 hsa_insn_cmp () : hsa_insn_basic (1, BRIG_OPCODE_CMP) {} 620 }; 621 622 /* Report whether or not P is a comparison instruction. */ 623 624 template <> 625 template <> 626 inline bool 627 is_a_helper <hsa_insn_cmp *>::test (hsa_insn_basic *p) 628 { 629 return p->m_opcode == BRIG_OPCODE_CMP; 630 } 631 632 /* HSA instruction for memory operations. */ 633 634 class hsa_insn_mem : public hsa_insn_basic 635 { 636 public: 637 hsa_insn_mem (int opc, BrigType16_t t, hsa_op_base *arg0, hsa_op_base *arg1); 638 639 /* Set alignment to VALUE. */ 640 641 void set_align (BrigAlignment8_t value); 642 643 /* The segment is of the memory access is either the segment of the symbol in 644 the address operand or flat address is there is no symbol there. */ 645 646 /* Required alignment of the memory operation. */ 647 BrigAlignment8_t m_align; 648 649 /* HSA equiv class, basically an alias set number. */ 650 uint8_t m_equiv_class; 651 652 /* TODO: Add width modifier, perhaps also other things. */ 653 protected: 654 hsa_insn_mem (unsigned nops, int opc, BrigType16_t t, 655 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL, 656 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL); 657 658 private: 659 /* Make the default constructor inaccessible. */ 660 hsa_insn_mem () : hsa_insn_basic (1, BRIG_OPCODE_LD) {} 661 }; 662 663 /* Report whether or not P is a memory instruction. */ 664 665 template <> 666 template <> 667 inline bool 668 is_a_helper <hsa_insn_mem *>::test (hsa_insn_basic *p) 669 { 670 return (p->m_opcode == BRIG_OPCODE_LD 671 || p->m_opcode == BRIG_OPCODE_ST); 672 } 673 674 /* HSA instruction for atomic operations. */ 675 676 class hsa_insn_atomic : public hsa_insn_mem 677 { 678 public: 679 hsa_insn_atomic (int nops, int opc, enum BrigAtomicOperation aop, 680 BrigType16_t t, BrigMemoryOrder memorder, 681 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL, 682 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL); 683 684 /* The operation itself. */ 685 enum BrigAtomicOperation m_atomicop; 686 687 /* Things like acquire/release/aligned. */ 688 enum BrigMemoryOrder m_memoryorder; 689 690 /* Scope of the atomic operation. */ 691 enum BrigMemoryScope m_memoryscope; 692 693 private: 694 /* Make the default constructor inaccessible. */ 695 hsa_insn_atomic () : hsa_insn_mem (1, BRIG_KIND_NONE, BRIG_TYPE_NONE) {} 696 }; 697 698 /* Report whether or not P is an atomic instruction. */ 699 700 template <> 701 template <> 702 inline bool 703 is_a_helper <hsa_insn_atomic *>::test (hsa_insn_basic *p) 704 { 705 return (p->m_opcode == BRIG_OPCODE_ATOMIC 706 || p->m_opcode == BRIG_OPCODE_ATOMICNORET); 707 } 708 709 /* HSA instruction for signal operations. */ 710 711 class hsa_insn_signal : public hsa_insn_basic 712 { 713 public: 714 hsa_insn_signal (int nops, int opc, enum BrigAtomicOperation sop, 715 BrigType16_t t, BrigMemoryOrder memorder, 716 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL, 717 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL); 718 719 /* Things like acquire/release/aligned. */ 720 enum BrigMemoryOrder m_memory_order; 721 722 /* The operation itself. */ 723 enum BrigAtomicOperation m_signalop; 724 }; 725 726 /* Report whether or not P is a signal instruction. */ 727 728 template <> 729 template <> 730 inline bool 731 is_a_helper <hsa_insn_signal *>::test (hsa_insn_basic *p) 732 { 733 return (p->m_opcode == BRIG_OPCODE_SIGNAL 734 || p->m_opcode == BRIG_OPCODE_SIGNALNORET); 735 } 736 737 /* HSA instruction to convert between flat addressing and segments. */ 738 739 class hsa_insn_seg : public hsa_insn_basic 740 { 741 public: 742 hsa_insn_seg (int opc, BrigType16_t destt, BrigType16_t srct, 743 BrigSegment8_t seg, hsa_op_base *arg0, hsa_op_base *arg1); 744 745 /* Source type. Depends on the source addressing/segment. */ 746 BrigType16_t m_src_type; 747 /* The segment we are converting from or to. */ 748 BrigSegment8_t m_segment; 749 private: 750 /* Make the default constructor inaccessible. */ 751 hsa_insn_seg () : hsa_insn_basic (1, BRIG_OPCODE_STOF) {} 752 }; 753 754 /* Report whether or not P is a segment conversion instruction. */ 755 756 template <> 757 template <> 758 inline bool 759 is_a_helper <hsa_insn_seg *>::test (hsa_insn_basic *p) 760 { 761 return (p->m_opcode == BRIG_OPCODE_STOF 762 || p->m_opcode == BRIG_OPCODE_FTOS); 763 } 764 765 /* Class for internal functions for purpose of HSA emission. */ 766 767 class hsa_internal_fn 768 { 769 public: 770 hsa_internal_fn (enum internal_fn fn, unsigned type_bit_size): 771 m_fn (fn), m_type_bit_size (type_bit_size), m_offset (0) {} 772 773 hsa_internal_fn (const hsa_internal_fn *f): 774 m_fn (f->m_fn), m_type_bit_size (f->m_type_bit_size), 775 m_offset (f->m_offset) {} 776 777 /* Return arity of the internal function. */ 778 unsigned get_arity (); 779 780 /* Return BRIG type of N-th argument, if -1 is passed, return value type 781 is received. */ 782 BrigType16_t get_argument_type (int n); 783 784 /* Return function name. The memory must be released by a caller. */ 785 char *name (); 786 787 /* Internal function. */ 788 enum internal_fn m_fn; 789 790 /* Bit width of return type. */ 791 unsigned m_type_bit_size; 792 793 /* BRIG offset of declaration of the function. */ 794 BrigCodeOffset32_t m_offset; 795 }; 796 797 /* HSA instruction for function call. */ 798 799 class hsa_insn_call : public hsa_insn_basic 800 { 801 public: 802 hsa_insn_call (tree callee); 803 hsa_insn_call (hsa_internal_fn *fn); 804 805 /* Default destructor. */ 806 ~hsa_insn_call (); 807 808 /* Called function. */ 809 tree m_called_function; 810 811 /* Called internal function. */ 812 hsa_internal_fn *m_called_internal_fn; 813 814 /* Input formal arguments. */ 815 auto_vec <hsa_symbol *> m_input_args; 816 817 /* Input arguments store instructions. */ 818 auto_vec <hsa_insn_mem *> m_input_arg_insns; 819 820 /* Output argument, can be NULL for void functions. */ 821 hsa_symbol *m_output_arg; 822 823 /* Called function code reference. */ 824 hsa_op_code_ref m_func; 825 826 /* Code list for arguments of the function. */ 827 hsa_op_code_list *m_args_code_list; 828 829 /* Code list for result of the function. */ 830 hsa_op_code_list *m_result_code_list; 831 private: 832 /* Make the default constructor inaccessible. */ 833 hsa_insn_call () : hsa_insn_basic (0, BRIG_OPCODE_CALL) {} 834 }; 835 836 /* Report whether or not P is a call instruction. */ 837 838 template <> 839 template <> 840 inline bool 841 is_a_helper <hsa_insn_call *>::test (hsa_insn_basic *p) 842 { 843 return (p->m_opcode == BRIG_OPCODE_CALL); 844 } 845 846 /* HSA call instruction block encapsulates definition of arguments, 847 result type, corresponding loads and a possible store. 848 Moreover, it contains a single call instruction. 849 Emission of the instruction will produce multiple 850 HSAIL instructions. */ 851 852 class hsa_insn_arg_block : public hsa_insn_basic 853 { 854 public: 855 hsa_insn_arg_block (BrigKind brig_kind, hsa_insn_call * call); 856 857 /* Kind of argument block. */ 858 BrigKind m_kind; 859 860 /* Call instruction. */ 861 hsa_insn_call *m_call_insn; 862 }; 863 864 /* Report whether or not P is a call block instruction. */ 865 866 template <> 867 template <> 868 inline bool 869 is_a_helper <hsa_insn_arg_block *>::test (hsa_insn_basic *p) 870 { 871 return (p->m_opcode == HSA_OPCODE_ARG_BLOCK); 872 } 873 874 /* HSA comment instruction. */ 875 876 class hsa_insn_comment: public hsa_insn_basic 877 { 878 public: 879 /* Constructor of class representing the comment in HSAIL. */ 880 hsa_insn_comment (const char *s); 881 882 /* Default destructor. */ 883 ~hsa_insn_comment (); 884 885 char *m_comment; 886 }; 887 888 /* Report whether or not P is a call block instruction. */ 889 890 template <> 891 template <> 892 inline bool 893 is_a_helper <hsa_insn_comment *>::test (hsa_insn_basic *p) 894 { 895 return (p->m_opcode == BRIG_KIND_DIRECTIVE_COMMENT); 896 } 897 898 /* HSA queue instruction. */ 899 900 class hsa_insn_queue: public hsa_insn_basic 901 { 902 public: 903 hsa_insn_queue (int nops, int opcode, BrigSegment segment, 904 BrigMemoryOrder memory_order, 905 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL, 906 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL); 907 908 /* Destructor. */ 909 ~hsa_insn_queue (); 910 911 /* Segment used to refer to the queue. Must be global or flat. */ 912 BrigSegment m_segment; 913 /* Memory order used to specify synchronization. */ 914 BrigMemoryOrder m_memory_order; 915 }; 916 917 /* Report whether or not P is a queue instruction. */ 918 919 template <> 920 template <> 921 inline bool 922 is_a_helper <hsa_insn_queue *>::test (hsa_insn_basic *p) 923 { 924 return (p->m_opcode == BRIG_OPCODE_ADDQUEUEWRITEINDEX 925 || p->m_opcode == BRIG_OPCODE_CASQUEUEWRITEINDEX 926 || p->m_opcode == BRIG_OPCODE_LDQUEUEREADINDEX 927 || p->m_opcode == BRIG_OPCODE_LDQUEUEWRITEINDEX 928 || p->m_opcode == BRIG_OPCODE_STQUEUEREADINDEX 929 || p->m_opcode == BRIG_OPCODE_STQUEUEWRITEINDEX); 930 } 931 932 /* HSA source type instruction. */ 933 934 class hsa_insn_srctype: public hsa_insn_basic 935 { 936 public: 937 hsa_insn_srctype (int nops, BrigOpcode opcode, BrigType16_t destt, 938 BrigType16_t srct, hsa_op_base *arg0, hsa_op_base *arg1, 939 hsa_op_base *arg2); 940 941 /* Source type. */ 942 BrigType16_t m_source_type; 943 944 /* Destructor. */ 945 ~hsa_insn_srctype (); 946 }; 947 948 /* Report whether or not P is a source type instruction. */ 949 950 template <> 951 template <> 952 inline bool 953 is_a_helper <hsa_insn_srctype *>::test (hsa_insn_basic *p) 954 { 955 return (p->m_opcode == BRIG_OPCODE_POPCOUNT 956 || p->m_opcode == BRIG_OPCODE_FIRSTBIT 957 || p->m_opcode == BRIG_OPCODE_LASTBIT); 958 } 959 960 /* HSA packed instruction. */ 961 962 class hsa_insn_packed : public hsa_insn_srctype 963 { 964 public: 965 hsa_insn_packed (int nops, BrigOpcode opcode, BrigType16_t destt, 966 BrigType16_t srct, hsa_op_base *arg0, hsa_op_base *arg1, 967 hsa_op_base *arg2); 968 969 /* Operand list for an operand of the instruction. */ 970 hsa_op_operand_list *m_operand_list; 971 972 /* Destructor. */ 973 ~hsa_insn_packed (); 974 }; 975 976 /* Report whether or not P is a combine instruction. */ 977 978 template <> 979 template <> 980 inline bool 981 is_a_helper <hsa_insn_packed *>::test (hsa_insn_basic *p) 982 { 983 return (p->m_opcode == BRIG_OPCODE_COMBINE 984 || p->m_opcode == BRIG_OPCODE_EXPAND); 985 } 986 987 /* HSA convert instruction. */ 988 989 class hsa_insn_cvt: public hsa_insn_basic 990 { 991 public: 992 hsa_insn_cvt (hsa_op_with_type *dest, hsa_op_with_type *src); 993 }; 994 995 /* Report whether or not P is a convert instruction. */ 996 997 template <> 998 template <> 999 inline bool 1000 is_a_helper <hsa_insn_cvt *>::test (hsa_insn_basic *p) 1001 { 1002 return (p->m_opcode == BRIG_OPCODE_CVT); 1003 } 1004 1005 /* HSA alloca instruction. */ 1006 1007 class hsa_insn_alloca: public hsa_insn_basic 1008 { 1009 public: 1010 hsa_insn_alloca (hsa_op_with_type *dest, hsa_op_with_type *size, 1011 unsigned alignment = 0); 1012 1013 /* Required alignment of the allocation. */ 1014 BrigAlignment8_t m_align; 1015 }; 1016 1017 /* Report whether or not P is an alloca instruction. */ 1018 1019 template <> 1020 template <> 1021 inline bool 1022 is_a_helper <hsa_insn_alloca *>::test (hsa_insn_basic *p) 1023 { 1024 return (p->m_opcode == BRIG_OPCODE_ALLOCA); 1025 } 1026 1027 /* Basic block of HSA instructions. */ 1028 1029 class hsa_bb 1030 { 1031 public: 1032 hsa_bb (basic_block cfg_bb); 1033 hsa_bb (basic_block cfg_bb, int idx); 1034 1035 /* Append an instruction INSN into the basic block. */ 1036 void append_insn (hsa_insn_basic *insn); 1037 1038 /* Add a PHI instruction. */ 1039 void append_phi (hsa_insn_phi *phi); 1040 1041 /* The real CFG BB that this HBB belongs to. */ 1042 basic_block m_bb; 1043 1044 /* The operand that refers to the label to this BB. */ 1045 hsa_op_code_ref m_label_ref; 1046 1047 /* The first and last instruction. */ 1048 hsa_insn_basic *m_first_insn, *m_last_insn; 1049 /* The first and last phi node. */ 1050 hsa_insn_phi *m_first_phi, *m_last_phi; 1051 1052 /* Just a number to construct names from. */ 1053 int m_index; 1054 1055 auto_bitmap m_liveout, m_livein; 1056 private: 1057 /* Make the default constructor inaccessible. */ 1058 hsa_bb (); 1059 /* All objects are deallocated by destroying their pool, so make delete 1060 inaccessible too. */ 1061 void operator delete (void *) {} 1062 }; 1063 1064 /* Return the corresponding HSA basic block structure for the given control 1065 flow basic_block BB. */ 1066 1067 static inline hsa_bb * 1068 hsa_bb_for_bb (basic_block bb) 1069 { 1070 return (struct hsa_bb *) bb->aux; 1071 } 1072 1073 /* Class for hashing local hsa_symbols. */ 1074 1075 struct hsa_noop_symbol_hasher : nofree_ptr_hash <hsa_symbol> 1076 { 1077 static inline hashval_t hash (const value_type); 1078 static inline bool equal (const value_type, const compare_type); 1079 }; 1080 1081 /* Hash hsa_symbol. */ 1082 1083 inline hashval_t 1084 hsa_noop_symbol_hasher::hash (const value_type item) 1085 { 1086 return DECL_UID (item->m_decl); 1087 } 1088 1089 /* Return true if the DECL_UIDs of decls both symbols refer to are equal. */ 1090 1091 inline bool 1092 hsa_noop_symbol_hasher::equal (const value_type a, const compare_type b) 1093 { 1094 return (DECL_UID (a->m_decl) == DECL_UID (b->m_decl)); 1095 } 1096 1097 /* Structure that encapsulates intermediate representation of a HSA 1098 function. */ 1099 1100 class hsa_function_representation 1101 { 1102 public: 1103 hsa_function_representation (tree fdecl, bool kernel_p, 1104 unsigned ssa_names_count, 1105 bool modified_cfg = false); 1106 hsa_function_representation (hsa_internal_fn *fn); 1107 ~hsa_function_representation (); 1108 1109 /* Builds a shadow register that is utilized to a kernel dispatch. */ 1110 hsa_op_reg *get_shadow_reg (); 1111 1112 /* Return true if we are in a function that has kernel dispatch 1113 shadow register. */ 1114 bool has_shadow_reg_p (); 1115 1116 /* The entry/exit blocks don't contain incoming code, 1117 but the HSA generator might use them to put code into, 1118 so we need hsa_bb instances of them. */ 1119 void init_extra_bbs (); 1120 1121 /* Update CFG dominators if m_modified_cfg flag is set. */ 1122 void update_dominance (); 1123 1124 /* Return linkage of the representation. */ 1125 BrigLinkage8_t get_linkage (); 1126 1127 /* Create a private symbol of requested TYPE. */ 1128 hsa_symbol *create_hsa_temporary (BrigType16_t type); 1129 1130 /* Lookup or create a HSA pseudo register for a given gimple SSA name. */ 1131 hsa_op_reg *reg_for_gimple_ssa (tree ssa); 1132 1133 /* Name of the function. */ 1134 char *m_name; 1135 1136 /* Number of allocated register structures. */ 1137 int m_reg_count; 1138 1139 /* Input arguments. */ 1140 vec <hsa_symbol *> m_input_args; 1141 1142 /* Output argument or NULL if there is none. */ 1143 hsa_symbol *m_output_arg; 1144 1145 /* Hash table of local variable symbols. */ 1146 hash_table <hsa_noop_symbol_hasher> *m_local_symbols; 1147 1148 /* Hash map for string constants. */ 1149 hash_map <tree, hsa_symbol *> m_string_constants_map; 1150 1151 /* Vector of pointers to spill symbols. */ 1152 vec <struct hsa_symbol *> m_spill_symbols; 1153 1154 /* Vector of pointers to global variables and transformed string constants 1155 that are used by the function. */ 1156 vec <struct hsa_symbol *> m_global_symbols; 1157 1158 /* Private function artificial variables. */ 1159 vec <struct hsa_symbol *> m_private_variables; 1160 1161 /* Vector of called function declarations. */ 1162 vec <tree> m_called_functions; 1163 1164 /* Vector of used internal functions. */ 1165 vec <hsa_internal_fn *> m_called_internal_fns; 1166 1167 /* Number of HBB BBs. */ 1168 int m_hbb_count; 1169 1170 /* Whether or not we could check and enforce SSA properties. */ 1171 bool m_in_ssa; 1172 1173 /* True if the function is kernel function. */ 1174 bool m_kern_p; 1175 1176 /* True if the function representation is a declaration. */ 1177 bool m_declaration_p; 1178 1179 /* Function declaration tree. */ 1180 tree m_decl; 1181 1182 /* Internal function info is used for declarations of internal functions. */ 1183 hsa_internal_fn *m_internal_fn; 1184 1185 /* Runtime shadow register. */ 1186 hsa_op_reg *m_shadow_reg; 1187 1188 /* Number of kernel dispatched which take place in the function. */ 1189 unsigned m_kernel_dispatch_count; 1190 1191 /* If the function representation contains a kernel dispatch, 1192 OMP data size is necessary memory that is used for copying before 1193 a kernel dispatch. */ 1194 unsigned m_maximum_omp_data_size; 1195 1196 /* Return true if there's an HSA-specific warning already seen. */ 1197 bool m_seen_error; 1198 1199 /* Counter for temporary symbols created in the function representation. */ 1200 unsigned m_temp_symbol_count; 1201 1202 /* SSA names mapping. */ 1203 vec <hsa_op_reg *> m_ssa_map; 1204 1205 /* Flag whether a function needs update of dominators before RA. */ 1206 bool m_modified_cfg; 1207 }; 1208 1209 enum hsa_function_kind 1210 { 1211 HSA_NONE, 1212 HSA_KERNEL, 1213 HSA_FUNCTION 1214 }; 1215 1216 struct hsa_function_summary 1217 { 1218 /* Default constructor. */ 1219 hsa_function_summary (); 1220 1221 /* Kind of GPU/host function. */ 1222 hsa_function_kind m_kind; 1223 1224 /* Pointer to a cgraph node which is a HSA implementation of the function. 1225 In case of the function is a HSA function, the bound function points 1226 to the host function. */ 1227 cgraph_node *m_bound_function; 1228 1229 /* Identifies if the function is an HSA function or a host function. */ 1230 bool m_gpu_implementation_p; 1231 1232 /* True if the function is a gridified kernel. */ 1233 bool m_gridified_kernel_p; 1234 }; 1235 1236 inline 1237 hsa_function_summary::hsa_function_summary (): m_kind (HSA_NONE), 1238 m_bound_function (NULL), m_gpu_implementation_p (false) 1239 { 1240 } 1241 1242 /* Function summary for HSA functions. */ 1243 class hsa_summary_t: public function_summary <hsa_function_summary *> 1244 { 1245 public: 1246 hsa_summary_t (symbol_table *table): 1247 function_summary<hsa_function_summary *> (table) { } 1248 1249 /* Couple GPU and HOST as gpu-specific and host-specific implementation of 1250 the same function. KIND determines whether GPU is a host-invokable kernel 1251 or gpu-callable function and GRIDIFIED_KERNEL_P is set if the function was 1252 gridified in OMP. */ 1253 1254 void link_functions (cgraph_node *gpu, cgraph_node *host, 1255 hsa_function_kind kind, bool gridified_kernel_p); 1256 1257 private: 1258 void process_gpu_implementation_attributes (tree gdecl); 1259 }; 1260 1261 /* OMP simple builtin describes behavior that should be done for 1262 the routine. */ 1263 class omp_simple_builtin 1264 { 1265 public: 1266 omp_simple_builtin (const char *name, const char *warning_message, 1267 bool sorry, hsa_op_immed *return_value = NULL): 1268 m_name (name), m_warning_message (warning_message), m_sorry (sorry), 1269 m_return_value (return_value) 1270 {} 1271 1272 /* Generate HSAIL instructions for the builtin or produce warning message. */ 1273 void generate (gimple *stmt, hsa_bb *hbb); 1274 1275 /* Name of function. */ 1276 const char *m_name; 1277 1278 /* Warning message. */ 1279 const char *m_warning_message; 1280 1281 /* Flag if we should sorry after the warning message is printed. */ 1282 bool m_sorry; 1283 1284 /* Return value of the function. */ 1285 hsa_op_immed *m_return_value; 1286 1287 /* Emission function. */ 1288 void (*m_emit_func) (gimple *stmt, hsa_bb *); 1289 }; 1290 1291 /* Class for hashing hsa_internal_fn. */ 1292 1293 struct hsa_internal_fn_hasher: free_ptr_hash <hsa_internal_fn> 1294 { 1295 static inline hashval_t hash (const value_type); 1296 static inline bool equal (const value_type, const compare_type); 1297 }; 1298 1299 /* Hash hsa_symbol. */ 1300 1301 inline hashval_t 1302 hsa_internal_fn_hasher::hash (const value_type item) 1303 { 1304 return item->m_fn; 1305 } 1306 1307 /* Return true if the DECL_UIDs of decls both symbols refer to are equal. */ 1308 1309 inline bool 1310 hsa_internal_fn_hasher::equal (const value_type a, const compare_type b) 1311 { 1312 return a->m_fn == b->m_fn && a->m_type_bit_size == b->m_type_bit_size; 1313 } 1314 1315 /* in hsa-common.c */ 1316 extern struct hsa_function_representation *hsa_cfun; 1317 extern hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies; 1318 extern hsa_summary_t *hsa_summaries; 1319 extern hsa_symbol *hsa_num_threads; 1320 extern unsigned hsa_kernel_calls_counter; 1321 extern hash_set <tree> *hsa_failed_functions; 1322 extern hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols; 1323 1324 bool hsa_callable_function_p (tree fndecl); 1325 void hsa_init_compilation_unit_data (void); 1326 void hsa_deinit_compilation_unit_data (void); 1327 bool hsa_machine_large_p (void); 1328 bool hsa_full_profile_p (void); 1329 bool hsa_opcode_floating_bit_insn_p (BrigOpcode16_t); 1330 unsigned hsa_type_bit_size (BrigType16_t t); 1331 BrigType16_t hsa_bittype_for_bitsize (unsigned bitsize); 1332 BrigType16_t hsa_uint_for_bitsize (unsigned bitsize); 1333 BrigType16_t hsa_float_for_bitsize (unsigned bitsize); 1334 BrigType16_t hsa_bittype_for_type (BrigType16_t t); 1335 BrigType16_t hsa_unsigned_type_for_type (BrigType16_t t); 1336 bool hsa_type_packed_p (BrigType16_t type); 1337 bool hsa_type_float_p (BrigType16_t type); 1338 bool hsa_type_integer_p (BrigType16_t type); 1339 bool hsa_btype_p (BrigType16_t type); 1340 BrigAlignment8_t hsa_alignment_encoding (unsigned n); 1341 BrigAlignment8_t hsa_natural_alignment (BrigType16_t type); 1342 BrigAlignment8_t hsa_object_alignment (tree t); 1343 unsigned hsa_byte_alignment (BrigAlignment8_t alignment); 1344 void hsa_destroy_operand (hsa_op_base *op); 1345 void hsa_destroy_insn (hsa_insn_basic *insn); 1346 void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool); 1347 unsigned hsa_get_number_decl_kernel_mappings (void); 1348 tree hsa_get_decl_kernel_mapping_decl (unsigned i); 1349 char *hsa_get_decl_kernel_mapping_name (unsigned i); 1350 unsigned hsa_get_decl_kernel_mapping_omp_size (unsigned i); 1351 bool hsa_get_decl_kernel_mapping_gridified (unsigned i); 1352 void hsa_free_decl_kernel_mapping (void); 1353 tree *hsa_get_ctor_statements (void); 1354 tree *hsa_get_dtor_statements (void); 1355 tree *hsa_get_kernel_dispatch_type (void); 1356 void hsa_add_kernel_dependency (tree caller, const char *called_function); 1357 void hsa_sanitize_name (char *p); 1358 char *hsa_brig_function_name (const char *p); 1359 const char *hsa_get_declaration_name (tree decl); 1360 void hsa_register_kernel (cgraph_node *host); 1361 void hsa_register_kernel (cgraph_node *gpu, cgraph_node *host); 1362 bool hsa_seen_error (void); 1363 void hsa_fail_cfun (void); 1364 1365 /* In hsa-gen.c. */ 1366 void hsa_build_append_simple_mov (hsa_op_reg *, hsa_op_base *, hsa_bb *); 1367 hsa_symbol *hsa_get_spill_symbol (BrigType16_t); 1368 hsa_symbol *hsa_get_string_cst_symbol (BrigType16_t); 1369 hsa_op_reg *hsa_spill_in (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **); 1370 hsa_op_reg *hsa_spill_out (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **); 1371 hsa_bb *hsa_init_new_bb (basic_block); 1372 hsa_function_representation *hsa_generate_function_declaration (tree decl); 1373 hsa_function_representation *hsa_generate_internal_fn_decl (hsa_internal_fn *); 1374 tree hsa_get_host_function (tree decl); 1375 1376 /* In hsa-regalloc.c. */ 1377 void hsa_regalloc (void); 1378 1379 /* In hsa-brig.c. */ 1380 extern hash_table <hsa_internal_fn_hasher> *hsa_emitted_internal_decls; 1381 void hsa_brig_emit_function (void); 1382 void hsa_output_brig (void); 1383 unsigned hsa_get_imm_brig_type_len (BrigType16_t type); 1384 void hsa_brig_emit_omp_symbols (void); 1385 1386 /* In hsa-dump.c. */ 1387 const char *hsa_seg_name (BrigSegment8_t); 1388 void dump_hsa_insn (FILE *f, hsa_insn_basic *insn); 1389 void dump_hsa_bb (FILE *, hsa_bb *); 1390 void dump_hsa_cfun (FILE *); 1391 DEBUG_FUNCTION void debug_hsa_operand (hsa_op_base *opc); 1392 DEBUG_FUNCTION void debug_hsa_insn (hsa_insn_basic *insn); 1393 1394 union hsa_bytes 1395 { 1396 uint8_t b8; 1397 uint16_t b16; 1398 uint32_t b32; 1399 uint64_t b64; 1400 }; 1401 1402 /* Return true if a function DECL is an HSA implementation. */ 1403 1404 static inline bool 1405 hsa_gpu_implementation_p (tree decl) 1406 { 1407 if (hsa_summaries == NULL) 1408 return false; 1409 1410 hsa_function_summary *s = hsa_summaries->get (cgraph_node::get_create (decl)); 1411 1412 return s->m_gpu_implementation_p; 1413 } 1414 1415 #endif /* HSA_H */ 1416