xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/brig/brigfrontend/brig-function.h (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1 /* brig-function.h -- declaration of brig_function class.
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_FUNCTION_H
23 #define BRIG_FUNCTION_H
24 
25 #include "config.h"
26 #include "system.h"
27 #include "ansidecl.h"
28 #include "coretypes.h"
29 #include "opts.h"
30 #include "tree.h"
31 #include "tree-iterator.h"
32 #include "hsa-brig-format.h"
33 #include "brig-util.h"
34 
35 #include <map>
36 #include <string>
37 #include <vector>
38 #include <set>
39 
40 #include "phsa.h"
41 
42 class brig_to_generic;
43 
44 typedef std::map<std::string, tree> label_index;
45 typedef std::map<const BrigDirectiveVariable *, tree> variable_index;
46 typedef std::vector<tree> tree_stl_vec;
47 
48 /* Holds data for the currently built GENERIC function.  */
49 
50 class brig_function
51 {
52 public:
53   typedef std::map<const BrigDirectiveVariable *, size_t> var_offset_table;
54 
55 private:
56   struct reg_decl_index_entry
57   {
58     tree m_var_decl;
59   };
60 
61 public:
62   brig_function (const BrigDirectiveExecutable *exec, brig_to_generic *parent);
63   ~brig_function ();
64 
65   tree arg_variable (const BrigDirectiveVariable *var) const;
66   void add_arg_variable (const BrigDirectiveVariable *brigVar, tree treeDecl);
67 
68   void append_kernel_arg (const BrigDirectiveVariable *var, size_t size,
69 			  size_t alignment);
70 
71   size_t kernel_arg_offset (const BrigDirectiveVariable *var) const;
72 
73   void add_id_variables ();
74 
75   tree label (const std::string &name);
76 
77   tree add_local_variable (std::string name, tree type);
78 
79   size_t group_variable_segment_offset (const std::string &name) const;
80 
81   bool has_group_variable (const std::string &name) const;
82 
83   size_t group_segment_size () const;
84 
85   tree get_m_var_declfor_reg (const BrigOperandRegister *reg);
86 
87   bool convert_to_wg_function ();
88 
89   void add_wi_loop (int dim, tree_stmt_iterator *header_entry,
90 		    tree_stmt_iterator *branch_after);
91 
92   tree emit_metadata (tree stmt_list);
93   tree emit_launcher_and_metadata ();
94 
95   tree append_statement (tree stmt);
96 
97   void create_alloca_frame ();
98 
99   void finish ();
100   void finish_kernel ();
101 
102   void append_return_stmt ();
103 
104   bool has_function_scope_var (const BrigBase* var) const;
105 
106   void analyze_calls ();
107 
108   tree expand_builtin (BrigOpcode16_t brig_opcode, tree_stl_vec &operands);
109 
110   tree expand_or_call_builtin (BrigOpcode16_t brig_opcode,
111 			       BrigType16_t brig_type, tree arith_type,
112 			       tree_stl_vec &operands);
113   bool can_expand_builtin (BrigOpcode16_t brig_opcode) const;
114 
115   tree get_builtin_for_hsa_opcode (tree type, BrigOpcode16_t brig_opcode,
116 				   BrigType16_t brig_type) const;
117 
118   void unpack (tree value, tree_stl_vec &elements);
119   tree pack (tree_stl_vec &elements);
120   tree add_temp_var (std::string name, tree expr);
121 
122   static bool needs_workitem_context_data (BrigOpcode16_t brig_opcode);
123   static HOST_WIDE_INT int_constant_value (tree node);
124   static tree_code get_tree_code_for_hsa_opcode (BrigOpcode16_t brig_opcode,
125 						 BrigType16_t brig_type);
126 
127   void start_new_bb ();
128   void add_reg_var_update (tree reg_var, tree val);
129   bool is_id_val (tree reg_var);
130   tree id_val (tree reg_var);
131 
132   const BrigDirectiveExecutable *m_brig_def;
133 
134   bool m_is_kernel;
135   bool m_is_finished;
136   std::string m_name;
137   tree m_current_bind_expr;
138   tree m_func_decl;
139   tree m_entry_label_stmt;
140   tree m_exit_label;
141 
142   /* The __context function argument.  */
143   tree m_context_arg;
144 
145   /* The __group_base_ptr argument in the current function.
146      Points to the start of the group segment for the work-group.  */
147   tree m_group_base_arg;
148 
149    /* The __group_local_offset_ptr argument in the current function.  It
150       contains the offset related to the group_base_ptr where the function's
151       local area for group variables resides.  */
152   tree m_group_local_offset_arg;
153 
154   /* The __private_base_ptr argument in the current function.
155      Points to the start of the private segment.  */
156   tree m_private_base_arg;
157 
158   /* The return value variable for the current function.  */
159   tree m_ret_value;
160 
161   /* The offsets of the kernel arguments in the __arg blob
162      pointing to the kernel argument space.  */
163   size_t m_next_kernarg_offset;
164 
165   /* The largest kernel argument variable alignment.  */
166   size_t m_kernarg_max_align;
167 
168   var_offset_table m_kernarg_offsets;
169 
170   /* Argument variables in the currently handled binding expression
171      (argument segment).  */
172   variable_index m_arg_variables;
173 
174   /* The brig variable for the function return value.  */
175   const BrigDirectiveVariable *m_ret_value_brig_var;
176 
177   /* The function local temporary variable for the return value.  */
178   tree m_ret_temp;
179 
180   /* Labels in the current function are collected here so we can refer
181      to them from jumps before they have been placed to the function.  */
182   label_index m_label_index;
183 
184   /* If the kernel contains at least one barrier, this is set to true.  */
185   bool m_has_barriers;
186 
187   /* True if the function has at least one alloca instruction.  */
188   bool m_has_allocas;
189 
190   /* If the kernel contains at least one function call that _may_
191      contain a barrier call, this is set to true.  */
192   bool m_has_function_calls_with_barriers;
193 
194   /* Set to true after this function has been analyzed for barrier and
195      dispatch packet instruction usage in the final call graph analysis.  */
196   bool m_calls_analyzed;
197 
198   /* True in case the function was successfully converted to a WG function.  */
199   bool m_is_wg_function;
200 
201   /* Work-item ID related variables are cached in the entry of the kernel
202      function in order to use them directly in address computations, leading
203      to more efficient optimizations.  The references to the local variables
204      are stored here.  */
205   tree m_local_id_vars[3];
206   tree m_cur_wg_size_vars[3];
207   tree m_wg_id_vars[3];
208   tree m_wg_size_vars[3];
209   tree m_grid_size_vars[3];
210   /* Explicitly computed WG base for the absolute IDs which is used
211      as the initial value when looping that dimension.   We update
212      the abs id with ++ to make it easy for the vectorizer.  */
213   tree m_abs_id_base_vars[3];
214   tree m_abs_id_vars[3];
215 
216   /* Set to true in case the kernel contains at least one dispatch packet
217      (work-item ID-related) builtin call that could not be expanded to
218      tree nodes.  */
219   bool m_has_unexpanded_dp_builtins;
220 
221   /* Points to the instruction after which the real kernel code starts.
222      Usually points to the last WI ID variable initialization statement.  */
223   tree_stmt_iterator m_kernel_entry;
224 
225   /* True if we are currently generating the contents of an arg block.  */
226   bool m_generating_arg_block;
227 
228   /* A collection of function scope variables seen so far for resolving
229      variable references vs. module scope declarations.  */
230   std::set<const BrigBase*> m_function_scope_vars;
231 
232   /* The functions called by this function.  */
233   std::vector<tree> m_called_functions;
234 
235   /* Stores the kernel scope group variable offsets if the function is
236      a kernel.  */
237   group_variable_offset_index m_local_group_variables;
238 
239   brig_to_generic *m_parent;
240   /* The metadata of the function that should be stored with the binary and
241      passed to the HSA runtime:  */
242   phsa_descriptor m_descriptor;
243 
244 private:
245 
246   tree get_tree_type_for_hsa_reg (const BrigOperandRegister *reg) const;
247 
248   /* Bookkeeping for the different HSA registers and their tree declarations
249      for the currently generated function.  */
250   reg_decl_index_entry *m_regs[BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT];
251 
252   /* Map for keeping book reads of ID variables, which can be propagated
253      to uses in address expressions to produce cleaner indexing functions
254      with unnecessary casts stripped off, etc.  */
255   typedef std::map<tree, tree> id_val_map;
256 
257   /* Keeps track of ID values alive in registers in the currently
258      processed BB.  */
259   id_val_map m_id_val_defs;
260 
261   /* HSAIL-specific builtin functions not yet integrated to gcc.  */
262   typedef std::map<std::pair<BrigOpcode16_t, BrigType16_t>, tree> builtin_map;
263 
264   static builtin_map s_custom_builtins;
265 };
266 
267 #endif
268