/* brig-to-generic.h -- brig to gcc generic conversion Copyright (C) 2016-2017 Free Software Foundation, Inc. Contributed by Pekka Jaaskelainen for General Processor Tech. 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 . */ #ifndef BRIG_TO_GENERIC_H #define BRIG_TO_GENERIC_H #include #include #include #include "config.h" #include "system.h" #include "ansidecl.h" #include "coretypes.h" #include "opts.h" #include "tree.h" #include "tree-iterator.h" #include "hsa-brig-format.h" #include "brig-function.h" struct reg_decl_index_entry; /* Converts an HSAIL BRIG input to GENERIC. This class holds global state for the translation process. Handling of the smaller pieces of BRIG data is delegated to various handler classes declared in brig-code-entry-handlers.h. */ class brig_to_generic { public: typedef std::map variable_index; private: typedef std::map var_offset_table; typedef std::map name_index; public: brig_to_generic (); void parse (const char *brig_blob); void write_globals (); std::string get_string (size_t entry_offset) const; const BrigData *get_brig_data_entry (size_t entry_offset) const; const BrigBase *get_brig_operand_entry (size_t entry_offset) const; const BrigBase *get_brig_code_entry (size_t entry_offset) const; void append_global (tree g); tree function_decl (const std::string &name); void add_function_decl (const std::string &name, tree func_decl); tree global_variable (const std::string &name) const; void add_global_variable (const std::string &name, tree var_decl); void add_host_def_var_ptr (const std::string &name, tree var_decl); void start_function (tree f); void finish_function (); void append_group_variable (const std::string &name, size_t size, size_t alignment); void append_private_variable (const std::string &name, size_t size, size_t alignment); size_t group_variable_segment_offset (const std::string &name) const; bool has_group_variable (const std::string &name) const; size_t private_variable_segment_offset (const std::string &name) const; bool has_private_variable (const std::string &name) const; size_t private_variable_size (const std::string &name) const; template std::string get_mangled_name_tmpl (const T *brigVar) const; std::string get_mangled_name (const BrigDirectiveFbarrier *fbar) const { return get_mangled_name_tmpl (fbar); } std::string get_mangled_name (const BrigDirectiveVariable *var) const { return get_mangled_name_tmpl (var); } std::string get_mangled_name (const BrigDirectiveExecutable *func) const; size_t group_segment_size () const; size_t private_segment_size () const; brig_function *get_finished_function (tree func_decl); static tree s_fp16_type; static tree s_fp32_type; static tree s_fp64_type; /* The default rounding mode that should be used for float instructions. This can be set in each BRIG module header. */ BrigRound8_t m_default_float_rounding_mode; /* The currently built function. */ brig_function *m_cf; /* The name of the currently handled BRIG module. */ std::string m_module_name; private: /* The BRIG blob and its different sections of the file currently being parsed. */ const char *m_brig; const char *m_data; size_t m_data_size; const char *m_operand; size_t m_operand_size; const char *m_code; size_t m_code_size; tree m_globals; label_index m_global_variables; /* The size of each private variable, including the alignment padding. */ std::map m_private_data_sizes; /* The same for group variables. */ size_t m_next_group_offset; var_offset_table m_group_offsets; /* And private. */ size_t m_next_private_offset; var_offset_table m_private_offsets; /* Name index for declared functions. */ label_index m_function_index; /* Stores all processed kernels in order. */ std::vector m_kernels; /* Stores all already processed functions from the translation unit for some interprocedural analysis. */ std::map m_finished_functions; /* The parsed BRIG blobs. Owned and will be deleted after use. */ std::vector m_brig_blobs; /* The original dump file. */ FILE *m_dump_file; /* The original dump file flags. */ int m_dump_flags; }; /* Produce a "mangled name" for the given brig variable. The mangling is used to make unique global symbol names for module and function scope variables. The templated version is suitable for most of the variable types. Functions and kernels (BrigDirectiveExecutable) are handled with a specialized get_mangled_name() version. */ template std::string brig_to_generic::get_mangled_name_tmpl (const T *brigVar) const { std::string var_name = get_string (brigVar->name).substr (1); /* Mangle the variable name using the function name and the module name in case of a function scope variable. */ if (m_cf != NULL && m_cf->has_function_scope_var (&brigVar->base)) var_name = m_cf->m_name + "." + var_name; if (brigVar->linkage == BRIG_LINKAGE_MODULE) var_name = "gccbrig." + m_module_name + "." + var_name; return var_name; } /* An interface to organize the different types of BRIG element handlers. */ class brig_entry_handler { public: brig_entry_handler (brig_to_generic &parent) : m_parent (parent) { } /* Handles the brig_code data at the given pointer and adds it to the currently built tree. Returns the number of consumed bytes; */ virtual size_t operator () (const BrigBase *base) = 0; protected: brig_to_generic &m_parent; }; tree call_builtin (tree pdecl, int nargs, tree rettype, ...); tree build_reinterpret_cast (tree destination_type, tree source); tree build_stmt (enum tree_code code, ...); tree get_unsigned_int_type (tree type); void dump_function (FILE *dump_file, brig_function *f); #endif