LCOV - code coverage report
Current view: top level - gcc - hsa-common.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 2 94 2.1 %
Date: 2020-04-04 11:58:09 Functions: 0 0 -
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.0

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto --enable-host-shared. GCC test suite is run with the built compiler.