/* HSAIL and BRIG related macros and definitions.
   Copyright (C) 2013-2018 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef HSA_H
#define HSA_H

#include "hsa-brig-format.h"
#include "is-a.h"
#include "predict.h"
#include "tree.h"
#include "vec.h"
#include "hash-table.h"
#include "basic-block.h"
#include "bitmap.h"


/* Return true if the compiler should produce HSAIL.  */

static inline bool
hsa_gen_requested_p (void)
{
#ifndef ENABLE_HSA
  return false;
#endif
  return !flag_disable_hsa;
}

/* Standard warning message if we failed to generate HSAIL for a function.  */

#define HSA_SORRY_MSG "could not emit HSAIL for the function"

class hsa_op_immed;
class hsa_op_cst_list;
class hsa_insn_basic;
class hsa_op_address;
class hsa_op_reg;
class hsa_bb;

/* Class representing an input argument, output argument (result) or a
   variable, that will eventually end up being a symbol directive.  */

struct hsa_symbol
{
  /* Constructor.  */
  hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
	      BrigLinkage8_t linkage, bool global_scope_p = false,
	      BrigAllocation allocation = BRIG_ALLOCATION_AUTOMATIC,
	      BrigAlignment8_t align = BRIG_ALIGNMENT_8);

  /* Return total size of the symbol.  */
  unsigned HOST_WIDE_INT total_byte_size ();

  /* Fill in those values into the symbol according to DECL, which are
     determined independently from whether it is parameter, result,
     or a variable, local or global.  */
  void fillup_for_decl (tree decl);

  /* Pointer to the original tree, which is PARM_DECL for input parameters and
     RESULT_DECL for the output parameters.  Also can be CONST_DECL for Fortran
     constants which need to be put into readonly segment.  */
  tree m_decl;

  /* Name of the symbol, that will be written into output and dumps.  Can be
     NULL, see name_number below.  */
  const char *m_name;

  /* If name is NULL, artificial name will be formed from the segment name and
     this number.  */
  int m_name_number;

  /* Once written, this is the offset of the associated symbol directive.  Zero
     means the symbol has not been written yet.  */
  unsigned m_directive_offset;

  /* HSA type of the parameter.  */
  BrigType16_t m_type;

  /* The HSA segment this will eventually end up in.  */
  BrigSegment8_t m_segment;

  /* The HSA kind of linkage.  */
  BrigLinkage8_t m_linkage;

  /* Array dimension, if non-zero.  */
  unsigned HOST_WIDE_INT m_dim;

  /* Constant value, used for string constants.  */
  hsa_op_immed *m_cst_value;

  /* Is in global scope.  */
  bool m_global_scope_p;

  /* True if an error has been seen for the symbol.  */
  bool m_seen_error;

  /* Symbol allocation.  */
  BrigAllocation m_allocation;

  /* Flag used for global variables if a variable is already emitted or not.  */
  bool m_emitted_to_brig;

  /* Alignment of the symbol.  */
  BrigAlignment8_t m_align;

private:
  /* Default constructor.  */
  hsa_symbol ();
};

/* Abstract class for HSA instruction operands.  */

class hsa_op_base
{
public:
  /* Next operand scheduled to be written when writing BRIG operand
     section.  */
  hsa_op_base *m_next;

  /* Offset to which the associated operand structure will be written.  Zero if
     yet not scheduled for writing.  */
  unsigned m_brig_op_offset;

  /* The type of a particular operand.  */
  BrigKind16_t m_kind;

protected:
  hsa_op_base (BrigKind16_t k);
private:
  /* Make the default constructor inaccessible.  */
  hsa_op_base () {}
};

/* Common abstract ancestor for operands which have a type.  */

class hsa_op_with_type : public hsa_op_base
{
public:
  /* The type.  */
  BrigType16_t m_type;

  /* Convert an operand to a destination type DTYPE and attach insns
     to HBB if needed.  */
  hsa_op_with_type *get_in_type (BrigType16_t dtype, hsa_bb *hbb);
  /* If this operand has integer type smaller than 32 bits, extend it to 32
     bits, adding instructions to HBB if needed.  */
  hsa_op_with_type *extend_int_to_32bit (hsa_bb *hbb);

protected:
  hsa_op_with_type (BrigKind16_t k, BrigType16_t t);
private:
  /* Make the default constructor inaccessible.  */
  hsa_op_with_type () : hsa_op_base (BRIG_KIND_NONE) {}
};

/* An immediate HSA operand.  */

class hsa_op_immed : public hsa_op_with_type
{
public:
  hsa_op_immed (tree tree_val, bool min32int = true);
  hsa_op_immed (HOST_WIDE_INT int_value, BrigType16_t type);
  void *operator new (size_t);
  ~hsa_op_immed ();
  void set_type (BrigKind16_t t);

  /* Function returns pointer to a buffer that contains binary representation
     of the immeadiate value.  The buffer has length of BRIG_SIZE and
     a caller is responsible for deallocation of the buffer.  */
  char *emit_to_buffer (unsigned *brig_size);

  /* Value as represented by middle end.  */
  tree m_tree_value;

  /* Integer value representation.  */
  HOST_WIDE_INT m_int_value;

private:
  /* Make the default constructor inaccessible.  */
  hsa_op_immed ();
  /* All objects are deallocated by destroying their pool, so make delete
     inaccessible too.  */
  void operator delete (void *) {}
};

/* Report whether or not P is a an immediate operand.  */

template <>
template <>
inline bool
is_a_helper <hsa_op_immed *>::test (hsa_op_base *p)
{
  return p->m_kind == BRIG_KIND_OPERAND_CONSTANT_BYTES;
}

/* Likewise, but for a more specified base. */

template <>
template <>
inline bool
is_a_helper <hsa_op_immed *>::test (hsa_op_with_type *p)
{
  return p->m_kind == BRIG_KIND_OPERAND_CONSTANT_BYTES;
}


/* HSA register operand.  */

class hsa_op_reg : public hsa_op_with_type
{
  friend class hsa_insn_basic;
  friend class hsa_insn_phi;
public:
  hsa_op_reg (BrigType16_t t);
  void *operator new (size_t);

  /* Verify register operand.  */
  void verify_ssa ();

  /* If NON-NULL, gimple SSA that we come from.  NULL if none.  */
  tree m_gimple_ssa;

  /* Defining instruction while still in the SSA.  */
  hsa_insn_basic *m_def_insn;

  /* If the register allocator decides to spill the register, this is the
     appropriate spill symbol.  */
  hsa_symbol *m_spill_sym;

  /* Number of this register structure in the order in which they were
     allocated.  */
  int m_order;
  int m_lr_begin, m_lr_end;

  /* Zero if the register is not yet allocated.  After, allocation, this must
     be 'c', 's', 'd' or 'q'.  */
  char m_reg_class;
  /* If allocated, the number of the HW register (within its HSA register
     class).  */
  char m_hard_num;

private:
  /* Make the default constructor inaccessible.  */
  hsa_op_reg () : hsa_op_with_type (BRIG_KIND_NONE, BRIG_TYPE_NONE) {}
  /* All objects are deallocated by destroying their pool, so make delete
     inaccessible too.  */
  void operator delete (void *) {}
  /* Set definition where the register is defined.  */
  void set_definition (hsa_insn_basic *insn);
  /* Uses of the value while still in SSA.  */
  auto_vec <hsa_insn_basic *> m_uses;
};

/* Report whether or not P is a register operand.  */

template <>
template <>
inline bool
is_a_helper <hsa_op_reg *>::test (hsa_op_base *p)
{
  return p->m_kind == BRIG_KIND_OPERAND_REGISTER;
}

/* Report whether or not P is a register operand.  */

template <>
template <>
inline bool
is_a_helper <hsa_op_reg *>::test (hsa_op_with_type *p)
{
  return p->m_kind == BRIG_KIND_OPERAND_REGISTER;
}

/* An address HSA operand.  */

class hsa_op_address : public hsa_op_base
{
public:
  /* set up a new address operand consisting of base symbol SYM, register R and
     immediate OFFSET.  If the machine model is not large and offset is 64 bit,
     the upper, 32 bits have to be zero.  */
  hsa_op_address (hsa_symbol *sym, hsa_op_reg *reg,
		  HOST_WIDE_INT offset = 0);

  void *operator new (size_t);

  /* Set up a new address operand consisting of base symbol SYM and
     immediate OFFSET.  If the machine model is not large and offset is 64 bit,
     the upper, 32 bits have to be zero.  */
  hsa_op_address (hsa_symbol *sym, HOST_WIDE_INT offset = 0);

  /* Set up a new address operand consisting of register R and
     immediate OFFSET.  If the machine model is not large and offset is 64 bit,
     the upper, 32 bits have to be zero.  */
  hsa_op_address (hsa_op_reg *reg, HOST_WIDE_INT offset = 0);

  /* Symbol base of the address.  Can be NULL if there is none.  */
  hsa_symbol *m_symbol;

  /* Register offset.  Can be NULL if there is none.  */
  hsa_op_reg *m_reg;

  /* Immediate byte offset.  */
  HOST_WIDE_INT m_imm_offset;

private:
  /* Make the default constructor inaccessible.  */
  hsa_op_address () : hsa_op_base (BRIG_KIND_NONE) {}
  /* All objects are deallocated by destroying their pool, so make delete
     inaccessible too.  */
  void operator delete (void *) {}
};

/* Report whether or not P is an address operand.  */

template <>
template <>
inline bool
is_a_helper <hsa_op_address *>::test (hsa_op_base *p)
{
  return p->m_kind == BRIG_KIND_OPERAND_ADDRESS;
}

/* A reference to code HSA operand.  It can be either reference
   to a start of a BB or a start of a function.  */

class hsa_op_code_ref : public hsa_op_base
{
public:
  hsa_op_code_ref ();

  /* Offset in the code section that this refers to.  */
  unsigned m_directive_offset;
};

/* Report whether or not P is a code reference operand.  */

template <>
template <>
inline bool
is_a_helper <hsa_op_code_ref *>::test (hsa_op_base *p)
{
  return p->m_kind == BRIG_KIND_OPERAND_CODE_REF;
}

/* Code list HSA operand.  */

class hsa_op_code_list: public hsa_op_base
{
public:
  hsa_op_code_list (unsigned elements);
  void *operator new (size_t);

  /* Offset to variable-sized array in hsa_data section, where
     are offsets to entries in the hsa_code section.  */
  auto_vec<unsigned> m_offsets;
private:
  /* Make the default constructor inaccessible.  */
  hsa_op_code_list () : hsa_op_base (BRIG_KIND_NONE) {}
  /* All objects are deallocated by destroying their pool, so make delete
     inaccessible too.  */
  void operator delete (void *) {}
};

/* Report whether or not P is a code list operand.  */

template <>
template <>
inline bool
is_a_helper <hsa_op_code_list *>::test (hsa_op_base *p)
{
  return p->m_kind == BRIG_KIND_OPERAND_CODE_LIST;
}

/* Operand list HSA operand.  */

class hsa_op_operand_list: public hsa_op_base
{
public:
  hsa_op_operand_list (unsigned elements);
  ~hsa_op_operand_list ();
  void *operator new (size_t);

  /* Offset to variable-sized array in hsa_data section, where
     are offsets to entries in the hsa_code section.  */
  auto_vec<unsigned> m_offsets;
private:
  /* Make the default constructor inaccessible.  */
  hsa_op_operand_list () : hsa_op_base (BRIG_KIND_NONE) {}
  /* All objects are deallocated by destroying their pool, so make delete
     inaccessible too.  */
  void operator delete (void *) {}
};

/* Report whether or not P is a code list operand.  */

template <>
template <>
inline bool
is_a_helper <hsa_op_operand_list *>::test (hsa_op_base *p)
{
  return p->m_kind == BRIG_KIND_OPERAND_OPERAND_LIST;
}

/* Opcodes of instructions that are not part of HSA but that we use to
   represent it nevertheless.  */

#define HSA_OPCODE_PHI (-1)
#define HSA_OPCODE_ARG_BLOCK (-2)

/* The number of operand pointers we can directly in an instruction.  */
#define HSA_BRIG_INT_STORAGE_OPERANDS 5

/* Class representing an HSA instruction.  Unlike typical ancestors for
   specialized classes, this one is also directly used for all instructions
   that are then represented as BrigInstBasic.  */

class hsa_insn_basic
{
public:
  hsa_insn_basic (unsigned nops, int opc);
  hsa_insn_basic (unsigned nops, int opc, BrigType16_t t,
		  hsa_op_base *arg0 = NULL,
		  hsa_op_base *arg1 = NULL,
		  hsa_op_base *arg2 = NULL,
		  hsa_op_base *arg3 = NULL);

  void *operator new (size_t);
  void set_op (int index, hsa_op_base *op);
  hsa_op_base *get_op (int index);
  hsa_op_base **get_op_addr (int index);
  unsigned int operand_count ();
  void verify ();
  unsigned input_count ();
  unsigned num_used_ops ();
  void set_output_in_type (hsa_op_reg *dest, unsigned op_index, hsa_bb *hbb);
  bool op_output_p (unsigned opnum);

  /* The previous and next instruction in the basic block.  */
  hsa_insn_basic *m_prev, *m_next;

  /* Basic block this instruction belongs to.  */
  basic_block m_bb;

  /* Operand code distinguishing different types of instructions.  Eventually
     these should only be BRIG_INST_* values from the BrigOpcode16_t range but
     initially we use negative values for PHI nodes and such.  */
  int m_opcode;

  /* Linearized number assigned to the instruction by HSA RA.  */
  int m_number;

  /* Type of the destination of the operations.  */
  BrigType16_t m_type;

  /* BRIG offset of the instruction in code section.  */
  unsigned int m_brig_offset;

private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_basic () {}
  /* All objects are deallocated by destroying their pool, so make delete
     inaccessible too.  */
  void operator delete (void *) {}
  /* The individual operands.  All instructions but PHI nodes have five or
     fewer instructions and so will fit the internal storage.  */
  /* TODO: Vast majority of instructions have three or fewer operands, so we
     may actually try reducing it.  */
  auto_vec<hsa_op_base *, HSA_BRIG_INT_STORAGE_OPERANDS> m_operands;
};

/* Class representing a PHI node of the SSA form of HSA virtual
   registers.  */

class hsa_insn_phi : public hsa_insn_basic
{
public:
  hsa_insn_phi (unsigned nops, hsa_op_reg *dst);

  /* Destination.  */
  hsa_op_reg *m_dest;

private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_phi () : hsa_insn_basic (1, HSA_OPCODE_PHI) {}
};

/* Report whether or not P is a PHI node.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_phi *>::test (hsa_insn_basic *p)
{
  return p->m_opcode == HSA_OPCODE_PHI;
}

/* HSA instruction for  */
class hsa_insn_br : public hsa_insn_basic
{
public:
  hsa_insn_br (unsigned nops, int opc, BrigType16_t t, BrigWidth8_t width,
	       hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
	       hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);

  /* Number of work-items affected in the same way by the instruction.  */
  BrigWidth8_t m_width;

private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_br () : hsa_insn_basic (0, BRIG_OPCODE_BR) {}
};

/* Return true if P is a branching/synchronization instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_br *>::test (hsa_insn_basic *p)
{
  return p->m_opcode == BRIG_OPCODE_BARRIER
    || p->m_opcode == BRIG_OPCODE_BR;
}

/* HSA instruction for conditional branches.  Structurally the same as
   hsa_insn_br but we represent it specially because of inherent control
   flow it represents.  */

class hsa_insn_cbr : public hsa_insn_br
{
public:
  hsa_insn_cbr (hsa_op_reg *ctrl);

private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_cbr () : hsa_insn_br (0, BRIG_OPCODE_CBR, BRIG_TYPE_B1,
				 BRIG_WIDTH_1) {}
};

/* Report whether P is a contitional branching instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_cbr *>::test (hsa_insn_basic *p)
{
  return p->m_opcode == BRIG_OPCODE_CBR;
}

/* HSA instruction for switch branches.  */

class hsa_insn_sbr : public hsa_insn_basic
{
public:
  hsa_insn_sbr (hsa_op_reg *index, unsigned jump_count);

  /* Default destructor.  */
  ~hsa_insn_sbr ();

  void replace_all_labels (basic_block old_bb, basic_block new_bb);

  /* Width as described in HSA documentation.  */
  BrigWidth8_t m_width;

  /* Jump table.  */
  vec <basic_block> m_jump_table;

  /* Code list for label references.  */
  hsa_op_code_list *m_label_code_list;

private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_sbr () : hsa_insn_basic (1, BRIG_OPCODE_SBR) {}
};

/* Report whether P is a switch branching instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_sbr *>::test (hsa_insn_basic *p)
{
  return p->m_opcode == BRIG_OPCODE_SBR;
}

/* HSA instruction for comparisons.  */

class hsa_insn_cmp : public hsa_insn_basic
{
public:
  hsa_insn_cmp (BrigCompareOperation8_t cmp, BrigType16_t t,
		hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
		hsa_op_base *arg2 = NULL);

  /* Source type should be derived from operand types.  */

  /* The comparison operation.  */
  BrigCompareOperation8_t m_compare;

  /* TODO: Modifiers and packing control are missing but so are everywhere
     else.  */
private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_cmp () : hsa_insn_basic (1, BRIG_OPCODE_CMP) {}
};

/* Report whether or not P is a comparison instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_cmp *>::test (hsa_insn_basic *p)
{
  return p->m_opcode == BRIG_OPCODE_CMP;
}

/* HSA instruction for memory operations.  */

class hsa_insn_mem : public hsa_insn_basic
{
public:
  hsa_insn_mem (int opc, BrigType16_t t, hsa_op_base *arg0, hsa_op_base *arg1);

  /* Set alignment to VALUE.  */

  void set_align (BrigAlignment8_t value);

  /* The segment is of the memory access is either the segment of the symbol in
     the address operand or flat address is there is no symbol there.  */

  /* Required alignment of the memory operation.  */
  BrigAlignment8_t m_align;

  /* HSA equiv class, basically an alias set number.  */
  uint8_t m_equiv_class;

  /* TODO:  Add width modifier, perhaps also other things.  */
protected:
  hsa_insn_mem (unsigned nops, int opc, BrigType16_t t,
		hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
		hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);

private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_mem () : hsa_insn_basic (1, BRIG_OPCODE_LD) {}
};

/* Report whether or not P is a memory instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_mem *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_LD
	  || p->m_opcode == BRIG_OPCODE_ST);
}

/* HSA instruction for atomic operations.  */

class hsa_insn_atomic : public hsa_insn_mem
{
public:
  hsa_insn_atomic (int nops, int opc, enum BrigAtomicOperation aop,
		   BrigType16_t t, BrigMemoryOrder memorder,
		   hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
		   hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);

  /* The operation itself.  */
  enum BrigAtomicOperation m_atomicop;

  /* Things like acquire/release/aligned.  */
  enum BrigMemoryOrder m_memoryorder;

  /* Scope of the atomic operation.  */
  enum BrigMemoryScope m_memoryscope;

private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_atomic () : hsa_insn_mem (1, BRIG_KIND_NONE, BRIG_TYPE_NONE) {}
};

/* Report whether or not P is an atomic instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_atomic *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_ATOMIC
	  || p->m_opcode == BRIG_OPCODE_ATOMICNORET);
}

/* HSA instruction for signal operations.  */

class hsa_insn_signal : public hsa_insn_basic
{
public:
  hsa_insn_signal (int nops, int opc, enum BrigAtomicOperation sop,
		   BrigType16_t t, BrigMemoryOrder memorder,
		   hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
		   hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);

  /* Things like acquire/release/aligned.  */
  enum BrigMemoryOrder m_memory_order;

  /* The operation itself.  */
  enum BrigAtomicOperation m_signalop;
};

/* Report whether or not P is a signal instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_signal *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_SIGNAL
	  || p->m_opcode == BRIG_OPCODE_SIGNALNORET);
}

/* HSA instruction to convert between flat addressing and segments.  */

class hsa_insn_seg : public hsa_insn_basic
{
public:
  hsa_insn_seg (int opc, BrigType16_t destt, BrigType16_t srct,
		BrigSegment8_t seg, hsa_op_base *arg0, hsa_op_base *arg1);

  /* Source type.  Depends on the source addressing/segment.  */
  BrigType16_t m_src_type;
  /* The segment we are converting from or to.  */
  BrigSegment8_t m_segment;
private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_seg () : hsa_insn_basic (1, BRIG_OPCODE_STOF) {}
};

/* Report whether or not P is a segment conversion instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_seg *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_STOF
	  || p->m_opcode == BRIG_OPCODE_FTOS);
}

/* Class for internal functions for purpose of HSA emission.  */

class hsa_internal_fn
{
public:
  hsa_internal_fn (enum internal_fn fn, unsigned type_bit_size):
    m_fn (fn), m_type_bit_size (type_bit_size), m_offset (0) {}

  hsa_internal_fn (const hsa_internal_fn *f):
    m_fn (f->m_fn), m_type_bit_size (f->m_type_bit_size),
    m_offset (f->m_offset) {}

  /* Return arity of the internal function.  */
  unsigned get_arity ();

  /* Return BRIG type of N-th argument, if -1 is passed, return value type
     is received.  */
  BrigType16_t get_argument_type (int n);

  /* Return function name.  The memory must be released by a caller.  */
  char *name ();

  /* Internal function.  */
  enum internal_fn m_fn;

  /* Bit width of return type.  */
  unsigned m_type_bit_size;

  /* BRIG offset of declaration of the function.  */
  BrigCodeOffset32_t m_offset;
};

/* HSA instruction for function call.  */

class hsa_insn_call : public hsa_insn_basic
{
public:
  hsa_insn_call (tree callee);
  hsa_insn_call (hsa_internal_fn *fn);

  /* Default destructor.  */
  ~hsa_insn_call ();

  /* Called function.  */
  tree m_called_function;

  /* Called internal function.  */
  hsa_internal_fn *m_called_internal_fn;

  /* Input formal arguments.  */
  auto_vec <hsa_symbol *> m_input_args;

  /* Input arguments store instructions.  */
  auto_vec <hsa_insn_mem *> m_input_arg_insns;

  /* Output argument, can be NULL for void functions.  */
  hsa_symbol *m_output_arg;

  /* Called function code reference.  */
  hsa_op_code_ref m_func;

  /* Code list for arguments of the function.  */
  hsa_op_code_list *m_args_code_list;

  /* Code list for result of the function.  */
  hsa_op_code_list *m_result_code_list;
private:
  /* Make the default constructor inaccessible.  */
  hsa_insn_call () : hsa_insn_basic (0, BRIG_OPCODE_CALL) {}
};

/* Report whether or not P is a call instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_call *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_CALL);
}

/* HSA call instruction block encapsulates definition of arguments,
   result type, corresponding loads and a possible store.
   Moreover, it contains a single call instruction.
   Emission of the instruction will produce multiple
   HSAIL instructions.  */

class hsa_insn_arg_block : public hsa_insn_basic
{
public:
  hsa_insn_arg_block (BrigKind brig_kind, hsa_insn_call * call);

  /* Kind of argument block.  */
  BrigKind m_kind;

  /* Call instruction.  */
  hsa_insn_call *m_call_insn;
};

/* Report whether or not P is a call block instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_arg_block *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == HSA_OPCODE_ARG_BLOCK);
}

/* HSA comment instruction.  */

class hsa_insn_comment: public hsa_insn_basic
{
public:
  /* Constructor of class representing the comment in HSAIL.  */
  hsa_insn_comment (const char *s);

  /* Default destructor.  */
  ~hsa_insn_comment ();

  char *m_comment;
};

/* Report whether or not P is a call block instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_comment *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_KIND_DIRECTIVE_COMMENT);
}

/* HSA queue instruction.  */

class hsa_insn_queue: public hsa_insn_basic
{
public:
  hsa_insn_queue (int nops, int opcode, BrigSegment segment,
		  BrigMemoryOrder memory_order,
		  hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
		  hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);

  /* Destructor.  */
  ~hsa_insn_queue ();

  /* Segment used to refer to the queue.  Must be global or flat.  */
  BrigSegment m_segment;
  /* Memory order used to specify synchronization.  */
  BrigMemoryOrder m_memory_order;
};

/* Report whether or not P is a queue instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_queue *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_ADDQUEUEWRITEINDEX
	  || p->m_opcode == BRIG_OPCODE_CASQUEUEWRITEINDEX
	  || p->m_opcode == BRIG_OPCODE_LDQUEUEREADINDEX
	  || p->m_opcode == BRIG_OPCODE_LDQUEUEWRITEINDEX
	  || p->m_opcode == BRIG_OPCODE_STQUEUEREADINDEX
	  || p->m_opcode == BRIG_OPCODE_STQUEUEWRITEINDEX);
}

/* HSA source type instruction.  */

class hsa_insn_srctype: public hsa_insn_basic
{
public:
  hsa_insn_srctype (int nops, BrigOpcode opcode, BrigType16_t destt,
		   BrigType16_t srct, hsa_op_base *arg0, hsa_op_base *arg1,
		   hsa_op_base *arg2);

  /* Source type.  */
  BrigType16_t m_source_type;

  /* Destructor.  */
  ~hsa_insn_srctype ();
};

/* Report whether or not P is a source type instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_srctype *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_POPCOUNT
	  || p->m_opcode == BRIG_OPCODE_FIRSTBIT
	  || p->m_opcode == BRIG_OPCODE_LASTBIT);
}

/* HSA packed instruction.  */

class hsa_insn_packed : public hsa_insn_srctype
{
public:
  hsa_insn_packed (int nops, BrigOpcode opcode, BrigType16_t destt,
		   BrigType16_t srct, hsa_op_base *arg0, hsa_op_base *arg1,
		   hsa_op_base *arg2);

  /* Operand list for an operand of the instruction.  */
  hsa_op_operand_list *m_operand_list;

  /* Destructor.  */
  ~hsa_insn_packed ();
};

/* Report whether or not P is a combine instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_packed *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_COMBINE
	  || p->m_opcode == BRIG_OPCODE_EXPAND);
}

/* HSA convert instruction.  */

class hsa_insn_cvt: public hsa_insn_basic
{
public:
  hsa_insn_cvt (hsa_op_with_type *dest, hsa_op_with_type *src);
};

/* Report whether or not P is a convert instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_cvt *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_CVT);
}

/* HSA alloca instruction.  */

class hsa_insn_alloca: public hsa_insn_basic
{
public:
  hsa_insn_alloca (hsa_op_with_type *dest, hsa_op_with_type *size,
		   unsigned alignment = 0);

  /* Required alignment of the allocation.  */
  BrigAlignment8_t m_align;
};

/* Report whether or not P is an alloca instruction.  */

template <>
template <>
inline bool
is_a_helper <hsa_insn_alloca *>::test (hsa_insn_basic *p)
{
  return (p->m_opcode == BRIG_OPCODE_ALLOCA);
}

/* Basic block of HSA instructions.  */

class hsa_bb
{
public:
  hsa_bb (basic_block cfg_bb);
  hsa_bb (basic_block cfg_bb, int idx);

  /* Append an instruction INSN into the basic block.  */
  void append_insn (hsa_insn_basic *insn);

  /* Add a PHI instruction.  */
  void append_phi (hsa_insn_phi *phi);

  /* The real CFG BB that this HBB belongs to.  */
  basic_block m_bb;

  /* The operand that refers to the label to this BB.  */
  hsa_op_code_ref m_label_ref;

  /* The first and last instruction.  */
  hsa_insn_basic *m_first_insn, *m_last_insn;
  /* The first and last phi node.  */
  hsa_insn_phi *m_first_phi, *m_last_phi;

  /* Just a number to construct names from.  */
  int m_index;

  auto_bitmap m_liveout, m_livein;
private:
  /* Make the default constructor inaccessible.  */
  hsa_bb ();
  /* All objects are deallocated by destroying their pool, so make delete
     inaccessible too.  */
  void operator delete (void *) {}
};

/* Return the corresponding HSA basic block structure for the given control
   flow basic_block BB.  */

static inline hsa_bb *
hsa_bb_for_bb (basic_block bb)
{
  return (struct hsa_bb *) bb->aux;
}

/* Class for hashing local hsa_symbols.  */

struct hsa_noop_symbol_hasher : nofree_ptr_hash <hsa_symbol>
{
  static inline hashval_t hash (const value_type);
  static inline bool equal (const value_type, const compare_type);
};

/* Hash hsa_symbol.  */

inline hashval_t
hsa_noop_symbol_hasher::hash (const value_type item)
{
  return DECL_UID (item->m_decl);
}

/* Return true if the DECL_UIDs of decls both symbols refer to are equal.  */

inline bool
hsa_noop_symbol_hasher::equal (const value_type a, const compare_type b)
{
  return (DECL_UID (a->m_decl) == DECL_UID (b->m_decl));
}

/* Structure that encapsulates intermediate representation of a HSA
   function.  */

class hsa_function_representation
{
public:
  hsa_function_representation (tree fdecl, bool kernel_p,
			       unsigned ssa_names_count,
			       bool modified_cfg = false);
  hsa_function_representation (hsa_internal_fn *fn);
  ~hsa_function_representation ();

  /* Builds a shadow register that is utilized to a kernel dispatch.  */
  hsa_op_reg *get_shadow_reg ();

  /* Return true if we are in a function that has kernel dispatch
     shadow register.  */
  bool has_shadow_reg_p ();

  /* The entry/exit blocks don't contain incoming code,
     but the HSA generator might use them to put code into,
     so we need hsa_bb instances of them.  */
  void init_extra_bbs ();

  /* Update CFG dominators if m_modified_cfg flag is set.  */
  void update_dominance ();

  /* Return linkage of the representation.  */
  BrigLinkage8_t get_linkage ();

  /* Create a private symbol of requested TYPE.  */
  hsa_symbol *create_hsa_temporary (BrigType16_t type);

  /* Lookup or create a HSA pseudo register for a given gimple SSA name.  */
  hsa_op_reg *reg_for_gimple_ssa (tree ssa);

  /* Name of the function.  */
  char *m_name;

  /* Number of allocated register structures.  */
  int m_reg_count;

  /* Input arguments.  */
  vec <hsa_symbol *> m_input_args;

  /* Output argument or NULL if there is none.  */
  hsa_symbol *m_output_arg;

  /* Hash table of local variable symbols.  */
  hash_table <hsa_noop_symbol_hasher> *m_local_symbols;

  /* Hash map for string constants.  */
  hash_map <tree, hsa_symbol *> m_string_constants_map;

  /* Vector of pointers to spill symbols.  */
  vec <struct hsa_symbol *> m_spill_symbols;

  /* Vector of pointers to global variables and transformed string constants
     that are used by the function.  */
  vec <struct hsa_symbol *> m_global_symbols;

  /* Private function artificial variables.  */
  vec <struct hsa_symbol *> m_private_variables;

  /* Vector of called function declarations.  */
  vec <tree> m_called_functions;

  /* Vector of used internal functions.  */
  vec <hsa_internal_fn *> m_called_internal_fns;

  /* Number of HBB BBs.  */
  int m_hbb_count;

  /* Whether or not we could check and enforce SSA properties.  */
  bool m_in_ssa;

  /* True if the function is kernel function.  */
  bool m_kern_p;

  /* True if the function representation is a declaration.  */
  bool m_declaration_p;

  /* Function declaration tree.  */
  tree m_decl;

  /* Internal function info is used for declarations of internal functions.  */
  hsa_internal_fn *m_internal_fn;

  /* Runtime shadow register.  */
  hsa_op_reg *m_shadow_reg;

  /* Number of kernel dispatched which take place in the function.  */
  unsigned m_kernel_dispatch_count;

  /* If the function representation contains a kernel dispatch,
     OMP data size is necessary memory that is used for copying before
     a kernel dispatch.  */
  unsigned m_maximum_omp_data_size;

  /* Return true if there's an HSA-specific warning already seen.  */
  bool m_seen_error;

  /* Counter for temporary symbols created in the function representation.  */
  unsigned m_temp_symbol_count;

  /* SSA names mapping.  */
  vec <hsa_op_reg *> m_ssa_map;

  /* Flag whether a function needs update of dominators before RA.  */
  bool m_modified_cfg;
};

enum hsa_function_kind
{
  HSA_INVALID,
  HSA_KERNEL,
  HSA_FUNCTION
};

struct hsa_function_summary
{
  /* Default constructor.  */
  hsa_function_summary ();

  /* Kind of GPU/host function.  */
  hsa_function_kind m_kind;

  /* Pointer to a cgraph node which is a HSA implementation of the function.
     In case of the function is a HSA function, the bound function points
     to the host function.  */
  cgraph_node *m_bound_function;

  /* Identifies if the function is an HSA function or a host function.  */
  bool m_gpu_implementation_p;

  /* True if the function is a gridified kernel.  */
  bool m_gridified_kernel_p;
};

inline
hsa_function_summary::hsa_function_summary (): m_kind (HSA_INVALID),
  m_bound_function (NULL), m_gpu_implementation_p (false)
{
}

/* Function summary for HSA functions.  */
class hsa_summary_t: public function_summary <hsa_function_summary *>
{
public:
  hsa_summary_t (symbol_table *table):
    function_summary<hsa_function_summary *> (table)
  {
    disable_insertion_hook ();
  }

  /* Couple GPU and HOST as gpu-specific and host-specific implementation of
     the same function.  KIND determines whether GPU is a host-invokable kernel
     or gpu-callable function and GRIDIFIED_KERNEL_P is set if the function was
     gridified in OMP.  */

  void link_functions (cgraph_node *gpu, cgraph_node *host,
		       hsa_function_kind kind, bool gridified_kernel_p);

private:
  void process_gpu_implementation_attributes (tree gdecl);
};

/* OMP simple builtin describes behavior that should be done for
   the routine.  */
class omp_simple_builtin
{
public:
  omp_simple_builtin (const char *name, const char *warning_message,
	       bool sorry, hsa_op_immed *return_value = NULL):
    m_name (name), m_warning_message (warning_message), m_sorry (sorry),
    m_return_value (return_value)
  {}

  /* Generate HSAIL instructions for the builtin or produce warning message.  */
  void generate (gimple *stmt, hsa_bb *hbb);

  /* Name of function.  */
  const char *m_name;

  /* Warning message.  */
  const char *m_warning_message;

  /* Flag if we should sorry after the warning message is printed.  */
  bool m_sorry;

  /* Return value of the function.  */
  hsa_op_immed *m_return_value;

  /* Emission function.  */
  void (*m_emit_func) (gimple *stmt, hsa_bb *);
};

/* Class for hashing hsa_internal_fn.  */

struct hsa_internal_fn_hasher: free_ptr_hash <hsa_internal_fn>
{
  static inline hashval_t hash (const value_type);
  static inline bool equal (const value_type, const compare_type);
};

/* Hash hsa_symbol.  */

inline hashval_t
hsa_internal_fn_hasher::hash (const value_type item)
{
  return item->m_fn;
}

/* Return true if the DECL_UIDs of decls both symbols refer to  are equal.  */

inline bool
hsa_internal_fn_hasher::equal (const value_type a, const compare_type b)
{
  return a->m_fn == b->m_fn && a->m_type_bit_size == b->m_type_bit_size;
}

/* in hsa-common.c */
extern struct hsa_function_representation *hsa_cfun;
extern hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
extern hsa_summary_t *hsa_summaries;
extern hsa_symbol *hsa_num_threads;
extern unsigned hsa_kernel_calls_counter;
extern hash_set <tree> *hsa_failed_functions;
extern hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols;

bool hsa_callable_function_p (tree fndecl);
void hsa_init_compilation_unit_data (void);
void hsa_deinit_compilation_unit_data (void);
bool hsa_machine_large_p (void);
bool hsa_full_profile_p (void);
bool hsa_opcode_floating_bit_insn_p (BrigOpcode16_t);
unsigned hsa_type_bit_size (BrigType16_t t);
BrigType16_t hsa_bittype_for_bitsize (unsigned bitsize);
BrigType16_t hsa_uint_for_bitsize (unsigned bitsize);
BrigType16_t hsa_float_for_bitsize (unsigned bitsize);
BrigType16_t hsa_bittype_for_type (BrigType16_t t);
BrigType16_t hsa_unsigned_type_for_type (BrigType16_t t);
bool hsa_type_packed_p (BrigType16_t type);
bool hsa_type_float_p (BrigType16_t type);
bool hsa_type_integer_p (BrigType16_t type);
bool hsa_btype_p (BrigType16_t type);
BrigAlignment8_t hsa_alignment_encoding (unsigned n);
BrigAlignment8_t hsa_natural_alignment (BrigType16_t type);
BrigAlignment8_t hsa_object_alignment (tree t);
unsigned hsa_byte_alignment (BrigAlignment8_t alignment);
void hsa_destroy_operand (hsa_op_base *op);
void hsa_destroy_insn (hsa_insn_basic *insn);
void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool);
unsigned hsa_get_number_decl_kernel_mappings (void);
tree hsa_get_decl_kernel_mapping_decl (unsigned i);
char *hsa_get_decl_kernel_mapping_name (unsigned i);
unsigned hsa_get_decl_kernel_mapping_omp_size (unsigned i);
bool hsa_get_decl_kernel_mapping_gridified (unsigned i);
void hsa_free_decl_kernel_mapping (void);
tree *hsa_get_ctor_statements (void);
tree *hsa_get_dtor_statements (void);
tree *hsa_get_kernel_dispatch_type (void);
void hsa_add_kernel_dependency (tree caller, const char *called_function);
void hsa_sanitize_name (char *p);
char *hsa_brig_function_name (const char *p);
const char *hsa_get_declaration_name (tree decl);
void hsa_register_kernel (cgraph_node *host);
void hsa_register_kernel (cgraph_node *gpu, cgraph_node *host);
bool hsa_seen_error (void);
void hsa_fail_cfun (void);

/* In hsa-gen.c.  */
void hsa_build_append_simple_mov (hsa_op_reg *, hsa_op_base *, hsa_bb *);
hsa_symbol *hsa_get_spill_symbol (BrigType16_t);
hsa_symbol *hsa_get_string_cst_symbol (BrigType16_t);
hsa_op_reg *hsa_spill_in (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **);
hsa_op_reg *hsa_spill_out (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **);
hsa_bb *hsa_init_new_bb (basic_block);
hsa_function_representation *hsa_generate_function_declaration (tree decl);
hsa_function_representation *hsa_generate_internal_fn_decl (hsa_internal_fn *);
tree hsa_get_host_function (tree decl);

/* In hsa-regalloc.c.  */
void hsa_regalloc (void);

/* In hsa-brig.c.  */
extern hash_table <hsa_internal_fn_hasher> *hsa_emitted_internal_decls;
void hsa_brig_emit_function (void);
void hsa_output_brig (void);
unsigned hsa_get_imm_brig_type_len (BrigType16_t type);
void hsa_brig_emit_omp_symbols (void);

/*  In hsa-dump.c.  */
const char *hsa_seg_name (BrigSegment8_t);
void dump_hsa_insn (FILE *f, hsa_insn_basic *insn);
void dump_hsa_bb (FILE *, hsa_bb *);
void dump_hsa_cfun (FILE *);
DEBUG_FUNCTION void debug_hsa_operand (hsa_op_base *opc);
DEBUG_FUNCTION void debug_hsa_insn (hsa_insn_basic *insn);

union hsa_bytes
{
  uint8_t b8;
  uint16_t b16;
  uint32_t b32;
  uint64_t b64;
};

/* Return true if a function DECL is an HSA implementation.  */

static inline bool
hsa_gpu_implementation_p (tree decl)
{
  if (hsa_summaries == NULL)
    return false;

  hsa_function_summary *s = hsa_summaries->get (cgraph_node::get_create (decl));
  return s != NULL && s->m_gpu_implementation_p;
}

#endif /* HSA_H */
