xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/brig/brigfrontend/brig-to-generic.h (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1 /* brig-to-generic.h -- brig to gcc generic conversion
2    Copyright (C) 2016-2020 Free Software Foundation, Inc.
3    Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
4    for General Processor Tech.
5 
6    This file is part of GCC.
7 
8    GCC is free software; you can redistribute it and/or modify it under
9    the terms of the GNU General Public License as published by the Free
10    Software Foundation; either version 3, or (at your option) any later
11    version.
12 
13    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14    WARRANTY; without even the implied warranty of MERCHANTABILITY or
15    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16    for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING3.  If not see
20    <http://www.gnu.org/licenses/>.  */
21 
22 #ifndef BRIG_TO_GENERIC_H
23 #define BRIG_TO_GENERIC_H
24 
25 #include <string>
26 #include <map>
27 #include <vector>
28 
29 #include "config.h"
30 #include "system.h"
31 #include "ansidecl.h"
32 #include "coretypes.h"
33 #include "opts.h"
34 #include "tree.h"
35 #include "tree-iterator.h"
36 #include "hsa-brig-format.h"
37 #include "brig-function.h"
38 
39 struct reg_decl_index_entry;
40 
41 /* Converts an HSAIL BRIG input to GENERIC.  This class holds global state
42    for the translation process.  Handling of the smaller pieces of BRIG data
43    is delegated to various handler classes declared in
44    brig-code-entry-handlers.h.  */
45 
46 class brig_to_generic
47 {
48 public:
49   typedef std::map<const BrigDirectiveVariable *, tree> variable_index;
50 
51 private:
52   typedef std::map<std::string, size_t> var_offset_table;
53   typedef std::map<const BrigBase *, std::string> name_index;
54 
55 public:
56   brig_to_generic ();
57 
58   void analyze (const char *brig_blob);
59   void parse (const char *brig_blob);
60 
61   void write_globals ();
62 
63   std::string get_string (size_t entry_offset) const;
64 
65   const BrigData *get_brig_data_entry (size_t entry_offset) const;
66   const BrigBase *get_brig_operand_entry (size_t entry_offset) const;
67   const BrigBase *get_brig_code_entry (size_t entry_offset) const;
68 
69   void append_global (tree g);
70 
71   tree function_decl (const std::string &name);
72   void add_function_decl (const std::string &name, tree func_decl);
73 
74   tree global_variable (const std::string &name) const;
75   void add_global_variable (const std::string &name, tree var_decl);
76   void add_host_def_var_ptr (const std::string &name, tree var_decl);
77   void add_decl_call (tree call);
78 
79   void start_function (tree f);
80   void finish_function ();
81 
82   void append_private_variable (const std::string &name, size_t size,
83 				size_t alignment);
84 
85   size_t
86   private_variable_segment_offset (const std::string &name) const;
87 
88   bool
89   has_private_variable (const std::string &name) const;
90 
91   size_t private_variable_size (const std::string &name) const;
92 
93   template <typename T>
94     std::string
95     get_mangled_name_tmpl (const T *brigVar) const;
96 
get_mangled_name(const BrigDirectiveFbarrier * fbar)97   std::string get_mangled_name (const BrigDirectiveFbarrier *fbar) const
98     { return get_mangled_name_tmpl (fbar); }
get_mangled_name(const BrigDirectiveVariable * var)99   std::string get_mangled_name (const BrigDirectiveVariable *var) const
100     { return get_mangled_name_tmpl (var); }
101   std::string get_mangled_name (const BrigDirectiveExecutable *func) const;
102 
103   size_t private_segment_size () const;
104 
105   brig_function *get_finished_function (tree func_decl);
106 
107   void add_group_variable (const std::string &name, size_t size,
108 			   size_t alignment, bool function_scope);
109 
110   void add_reg_used_as_type (const BrigOperandRegister &brig_reg,
111 			     tree operand_type);
112 
113   static tree s_fp16_type;
114   static tree s_fp32_type;
115   static tree s_fp64_type;
116 
117   /* The default rounding mode that should be used for float instructions.
118      This can be set in each BRIG module header.  */
119   BrigRound8_t m_default_float_rounding_mode;
120 
121   /* The currently built function.  */
122   brig_function *m_cf;
123 
124   /* Stores the module and function scope group variable offsets.  */
125   group_variable_offset_index m_module_group_variables;
126 
127   /* The name of the currently handled BRIG module.  */
128   std::string m_module_name;
129 
130   /* Set to true if the compilation is in 'analyze' phase.  */
131   bool m_analyzing;
132 
133   /* Accumulates the total group segment usage.  */
134   size_t m_total_group_segment_usage;
135 
136   /* Statistics about register uses per function.  */
137   std::map<std::string, regs_use_index> m_fn_regs_use_index;
138 
139 private:
140 
141   void find_brig_sections ();
142   /* The BRIG blob and its different sections of the file currently being
143      parsed.  */
144   const char *m_brig;
145   const char *m_data;
146   size_t m_data_size;
147   const char *m_operand;
148   size_t m_operand_size;
149   const char *m_code;
150   size_t m_code_size;
151 
152   tree m_globals;
153 
154   label_index m_global_variables;
155 
156   /* Calls to declarations to be fixed in the end of processing to call
157      defs instead.  */
158   std::vector<tree> m_decl_call;
159 
160   /* The size of each private variable, including the alignment padding.  */
161   std::map<std::string, size_t> m_private_data_sizes;
162 
163   /* And private.  */
164   size_t m_next_private_offset;
165   var_offset_table m_private_offsets;
166 
167   /* Name index for declared functions.  */
168   label_index m_function_index;
169 
170   /* Stores all processed kernels in order.  */
171   std::vector<brig_function *> m_kernels;
172 
173   /* Stores all already processed functions from the translation unit
174      for some interprocedural analysis.  */
175   std::map<std::string, brig_function *> m_finished_functions;
176 
177   /* The original dump file.  */
178   FILE *m_dump_file;
179 
180   /* The original dump file flags.  */
181   dump_flags_t m_dump_flags;
182 };
183 
184 /* Produce a "mangled name" for the given brig variable.  The mangling is used
185    to make unique global symbol names for module and function scope variables.
186    The templated version is suitable for most of the variable types.  Functions
187    and kernels (BrigDirectiveExecutable) are handled with a specialized
188    get_mangled_name() version.  */
189 
190 template <typename T>
191 std::string
get_mangled_name_tmpl(const T * brigVar)192 brig_to_generic::get_mangled_name_tmpl (const T *brigVar) const
193 {
194   std::string var_name = get_string (brigVar->name).substr (1);
195 
196   /* Mangle the variable name using the function name and the module name
197      in case of a function scope variable.  */
198   if (m_cf != NULL
199       && m_cf->has_function_scope_var (&brigVar->base))
200     var_name = m_cf->m_name + "." + var_name;
201 
202   if (brigVar->linkage == BRIG_LINKAGE_MODULE)
203     var_name = "gccbrig." + m_module_name + "." + var_name;
204   return var_name;
205 }
206 
207 /* An interface to organize the different types of BRIG element handlers.  */
208 
209 class brig_entry_handler
210 {
211 public:
brig_entry_handler(brig_to_generic & parent)212   brig_entry_handler (brig_to_generic &parent) : m_parent (parent)
213   {
214   }
215 
216   /* Handles the brig_code data at the given pointer and adds it to the
217      currently built tree.  Returns the number of consumed bytes;  */
218   virtual size_t operator () (const BrigBase *base) = 0;
219 
220 protected:
221   brig_to_generic &m_parent;
222 };
223 
224 tree call_builtin (tree pdecl, int nargs, tree rettype, ...);
225 
226 tree build_resize_convert_view (tree destination_type, tree source);
227 tree build_reinterpret_to_uint (tree source);
228 
229 tree build_stmt (enum tree_code code, ...);
230 
231 tree get_unsigned_int_type (tree type);
232 
233 tree get_scalar_unsigned_int_type (tree type);
234 void set_externally_visible (tree decl);
235 
236 void set_inline (tree decl);
237 
238 void dump_function (FILE *dump_file, brig_function *f);
239 
240 #endif
241