@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see
52
52
#include "stringpool.h"
53
53
#include "attribs.h"
54
54
#include "cfgloop.h"
55
+ #include "context.h"
55
56
56
57
/* Describe the OpenACC looping structure of a function. The entire
57
58
function is held in a 'NULL' loop. */
@@ -158,6 +159,138 @@ add_decls_addresses_to_decl_constructor (vec<tree, va_gc> *v_decls,
158
159
}
159
160
}
160
161
162
+ /* Return true if DECL is a function for which its references should be
163
+ analyzed. */
164
+
165
+ static bool
166
+ omp_declare_target_fn_p (tree decl )
167
+ {
168
+ return (TREE_CODE (decl ) == FUNCTION_DECL
169
+ && lookup_attribute ("omp declare target" , DECL_ATTRIBUTES (decl ))
170
+ && !lookup_attribute ("omp declare target host" ,
171
+ DECL_ATTRIBUTES (decl ))
172
+ && (!flag_openacc
173
+ || oacc_get_fn_attrib (decl ) == NULL_TREE ));
174
+ }
175
+
176
+ /* Return true if DECL Is a variable for which its initializer references
177
+ should be analyzed. */
178
+
179
+ static bool
180
+ omp_declare_target_var_p (tree decl )
181
+ {
182
+ return (VAR_P (decl )
183
+ && lookup_attribute ("omp declare target" , DECL_ATTRIBUTES (decl ))
184
+ && !lookup_attribute ("omp declare target link" ,
185
+ DECL_ATTRIBUTES (decl )));
186
+ }
187
+
188
+ /* Helper function for omp_discover_implicit_declare_target, called through
189
+ walk_tree. Mark referenced FUNCTION_DECLs implicitly as
190
+ declare target to. */
191
+
192
+ static tree
193
+ omp_discover_declare_target_fn_r (tree * tp , int * walk_subtrees , void * data )
194
+ {
195
+ if (TREE_CODE (* tp ) == FUNCTION_DECL
196
+ && !omp_declare_target_fn_p (* tp )
197
+ && !lookup_attribute ("omp declare target host" , DECL_ATTRIBUTES (* tp )))
198
+ {
199
+ tree id = get_identifier ("omp declare target" );
200
+ if (!DECL_EXTERNAL (* tp ) && DECL_SAVED_TREE (* tp ))
201
+ ((vec < tree > * ) data )-> safe_push (* tp );
202
+ DECL_ATTRIBUTES (* tp ) = tree_cons (id , NULL_TREE , DECL_ATTRIBUTES (* tp ));
203
+ symtab_node * node = symtab_node ::get (* tp );
204
+ if (node != NULL )
205
+ {
206
+ node -> offloadable = 1 ;
207
+ if (ENABLE_OFFLOADING )
208
+ g -> have_offload = true;
209
+ }
210
+ }
211
+ else if (TYPE_P (* tp ))
212
+ * walk_subtrees = 0 ;
213
+ /* else if (TREE_CODE (*tp) == OMP_TARGET)
214
+ {
215
+ if (tree dev = omp_find_clause (OMP_TARGET_CLAUSES (*tp)))
216
+ if (OMP_DEVICE_ANCESTOR (dev))
217
+ *walk_subtrees = 0;
218
+ } */
219
+ return NULL_TREE ;
220
+ }
221
+
222
+ /* Helper function for omp_discover_implicit_declare_target, called through
223
+ walk_tree. Mark referenced FUNCTION_DECLs implicitly as
224
+ declare target to. */
225
+
226
+ static tree
227
+ omp_discover_declare_target_var_r (tree * tp , int * walk_subtrees , void * data )
228
+ {
229
+ if (TREE_CODE (* tp ) == FUNCTION_DECL )
230
+ return omp_discover_declare_target_fn_r (tp , walk_subtrees , data );
231
+ else if (VAR_P (* tp )
232
+ && is_global_var (* tp )
233
+ && !omp_declare_target_var_p (* tp ))
234
+ {
235
+ tree id = get_identifier ("omp declare target" );
236
+ if (lookup_attribute ("omp declare target link" , DECL_ATTRIBUTES (* tp )))
237
+ {
238
+ error_at (DECL_SOURCE_LOCATION (* tp ),
239
+ "%qD specified both in declare target %<link%> and "
240
+ "implicitly in %<to%> clauses" , * tp );
241
+ DECL_ATTRIBUTES (* tp )
242
+ = remove_attribute ("omp declare target link" , DECL_ATTRIBUTES (* tp ));
243
+ }
244
+ if (TREE_STATIC (* tp ) && DECL_INITIAL (* tp ))
245
+ ((vec < tree > * ) data )-> safe_push (* tp );
246
+ DECL_ATTRIBUTES (* tp ) = tree_cons (id , NULL_TREE , DECL_ATTRIBUTES (* tp ));
247
+ symtab_node * node = symtab_node ::get (* tp );
248
+ if (node != NULL && !node -> offloadable )
249
+ {
250
+ node -> offloadable = 1 ;
251
+ if (ENABLE_OFFLOADING )
252
+ {
253
+ g -> have_offload = true;
254
+ if (is_a < varpool_node * > (node ))
255
+ vec_safe_push (offload_vars , node -> decl );
256
+ }
257
+ }
258
+ }
259
+ else if (TYPE_P (* tp ))
260
+ * walk_subtrees = 0 ;
261
+ return NULL_TREE ;
262
+ }
263
+
264
+ /* Perform the OpenMP implicit declare target to discovery. */
265
+
266
+ void
267
+ omp_discover_implicit_declare_target (void )
268
+ {
269
+ cgraph_node * node ;
270
+ varpool_node * vnode ;
271
+ auto_vec < tree > worklist ;
272
+
273
+ FOR_EACH_DEFINED_FUNCTION (node )
274
+ if (omp_declare_target_fn_p (node -> decl ) && DECL_SAVED_TREE (node -> decl ))
275
+ worklist .safe_push (node - > decl );
276
+ FOR_EACH_STATIC_INITIALIZER (vnode )
277
+ if (omp_declare_target_var_p (vnode - > decl ))
278
+ worklist .safe_push (vnode - > decl );
279
+ while (!worklist .is_empty ())
280
+ {
281
+ tree decl = worklist .pop ();
282
+ if (TREE_CODE (decl ) == FUNCTION_DECL )
283
+ walk_tree_without_duplicates (& DECL_SAVED_TREE (decl ),
284
+ omp_discover_declare_target_fn_r ,
285
+ & worklist );
286
+ else
287
+ walk_tree_without_duplicates (& DECL_INITIAL (decl ),
288
+ omp_discover_declare_target_var_r ,
289
+ & worklist );
290
+ }
291
+ }
292
+
293
+
161
294
/* Create new symbols containing (address, size) pairs for global variables,
162
295
marked with "omp declare target" attribute, as well as addresses for the
163
296
functions, which are outlined offloading regions. */
0 commit comments