Ping.
On 17 December 2013 15:39, Michael V. Zolotukhin <michael.v.zolotuk...@gmail.com> wrote: > Hi everybody, > > Here is a patch 2/3: Add tables generation. > > This patch is just a slightly modified patch sent a couple of weeks ago. When > compiling with '-fopenmp' compiler generates a special symbol, containing > addresses and sizes of globals/omp_fn-functions, and places it into a special > section. Later, at linking, these sections are merged together and we get a > single table with all addresses/sizes for entire binary. Also, in this patch > we > start to pass '__OPENMP_TARGET__' symbol to GOMP_target calls. > > Thanks, > Michael > > > --- > gcc/omp-low.c | 119 > +++++++++++++++++++++++++++++++++++++++++++++++++++++---- > gcc/omp-low.h | 1 + > gcc/toplev.c | 3 + > 3 files changed, 115 insertions(+), 8 deletions(-) > > diff --git a/gcc/omp-low.c b/gcc/omp-low.c > index e0f7d1d..f860204 100644 > --- a/gcc/omp-low.c > +++ b/gcc/omp-low.c > @@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see > #include "optabs.h" > #include "cfgloop.h" > #include "target.h" > +#include "common/common-target.h" > #include "omp-low.h" > #include "gimple-low.h" > #include "tree-cfgcleanup.h" > @@ -8371,19 +8372,22 @@ expand_omp_target (struct omp_region *region) > } > > gimple g; > - /* FIXME: This will be address of > - extern char __OPENMP_TARGET__[] __attribute__((visibility ("hidden"))) > - symbol, as soon as the linker plugin is able to create it for us. */ > - tree openmp_target = build_zero_cst (ptr_type_node); > + tree openmp_target > + = build_decl (UNKNOWN_LOCATION, VAR_DECL, > + get_identifier ("__OPENMP_TARGET__"), ptr_type_node); > + TREE_PUBLIC (openmp_target) = 1; > + DECL_EXTERNAL (openmp_target) = 1; > if (kind == GF_OMP_TARGET_KIND_REGION) > { > tree fnaddr = build_fold_addr_expr (child_fn); > - g = gimple_build_call (builtin_decl_explicit (start_ix), 7, > - device, fnaddr, openmp_target, t1, t2, t3, t4); > + g = gimple_build_call (builtin_decl_explicit (start_ix), 7, device, > + fnaddr, build_fold_addr_expr (openmp_target), > + t1, t2, t3, t4); > } > else > - g = gimple_build_call (builtin_decl_explicit (start_ix), 6, > - device, openmp_target, t1, t2, t3, t4); > + g = gimple_build_call (builtin_decl_explicit (start_ix), 6, device, > + build_fold_addr_expr (openmp_target), > + t1, t2, t3, t4); > gimple_set_location (g, gimple_location (entry_stmt)); > gsi_insert_before (&gsi, g, GSI_SAME_STMT); > if (kind != GF_OMP_TARGET_KIND_REGION) > @@ -12379,4 +12383,103 @@ make_pass_omp_simd_clone (gcc::context *ctxt) > return new pass_omp_simd_clone (ctxt); > } > > +/* Helper function for omp_finish_file routine. > + Takes decls from V_DECLS and adds their addresses and sizes to > + constructor-vector V_CTOR. It will be later used as DECL_INIT for decl > + representing a global symbol for OpenMP descriptor. > + If IS_FUNCTION is true, we use 1 for size. */ > +static void > +add_decls_addresses_to_decl_constructor (vec<tree, va_gc> *v_decls, > + vec<constructor_elt, va_gc> *v_ctor, > + bool is_function) > +{ > + unsigned int len = 0, i; > + tree size, it; > + len = vec_safe_length (v_decls); > + for (i = 0; i < len; i++) > + { > + /* Decls are placed in reversed order in fat-objects, so we need to > + revert them back if we compile target. */ > + if (!flag_openmp_target) > + it = (*v_decls)[i]; > + else > + it = (*v_decls)[len - i - 1]; > + size = is_function ? integer_one_node : DECL_SIZE (it); > + CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, build_fold_addr_expr (it)); > + CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, > + fold_convert (const_ptr_type_node, > + size)); > + } > +} > + > +/* Create new symbol containing (address, size) pairs for omp-marked > + functions and global variables. */ > +void > +omp_finish_file (void) > +{ > + struct cgraph_node *node; > + struct varpool_node *vnode; > + const char *section_name = ".offload_func_table_section"; > + tree new_decl, new_decl_type; > + vec<constructor_elt, va_gc> *v; > + vec<tree, va_gc> *v_func, *v_var; > + tree ctor; > + int num = 0; > + > + if (!targetm_common.have_named_sections) > + return; > + > + vec_alloc (v_func, 0); > + vec_alloc (v_var, 0); > + > + /* Collect all omp-target functions. */ > + FOR_EACH_DEFINED_FUNCTION (node) > + { > + /* TODO: This check could fail on functions, created by omp > + parallel/task pragmas. It's better to name outlined for offloading > + functions in some different way and to check here the function name. > + It could be something like "*_omp_tgtfn" in contrast with "*_omp_fn" > + for functions from omp parallel/task pragmas. */ > + if (!lookup_attribute ("omp declare target", > + DECL_ATTRIBUTES (node->decl)) > + || !DECL_ARTIFICIAL (node->decl)) > + continue; > + vec_safe_push (v_func, node->decl); > + num ++; > + } > + /* Collect all omp-target global variables. */ > + FOR_EACH_DEFINED_VARIABLE (vnode) > + { > + if (!lookup_attribute ("omp declare target", > + DECL_ATTRIBUTES (vnode->decl)) > + || TREE_CODE (vnode->decl) != VAR_DECL > + || DECL_SIZE (vnode->decl) == 0) > + continue; > + > + vec_safe_push (v_var, vnode->decl); > + num ++; > + } > + > + if (num == 0) > + return; > + > + vec_alloc (v, num * 2); > + > + add_decls_addresses_to_decl_constructor (v_func, v, true); > + add_decls_addresses_to_decl_constructor (v_var, v, false); > + > + new_decl_type = build_array_type_nelts (pointer_sized_int_node, num * 2); > + ctor = build_constructor (new_decl_type, v); > + TREE_CONSTANT (ctor) = 1; > + TREE_STATIC (ctor) = 1; > + new_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, > + get_identifier (".omp_table"), new_decl_type); > + TREE_STATIC (new_decl) = 1; > + DECL_INITIAL (new_decl) = ctor; > + DECL_SECTION_NAME (new_decl) = build_string (strlen (section_name), > + section_name); > + > + varpool_assemble_decl (varpool_node_for_decl (new_decl)); > +} > + > #include "gt-omp-low.h" > diff --git a/gcc/omp-low.h b/gcc/omp-low.h > index 6b5a2ff..813189d 100644 > --- a/gcc/omp-low.h > +++ b/gcc/omp-low.h > @@ -27,5 +27,6 @@ extern void omp_expand_local (basic_block); > extern void free_omp_regions (void); > extern tree omp_reduction_init (tree, tree); > extern bool make_gimple_omp_edges (basic_block, struct omp_region **); > +extern void omp_finish_file (void); > > #endif /* GCC_OMP_LOW_H */ > diff --git a/gcc/toplev.c b/gcc/toplev.c > index 5fedcea..af010ff 100644 > --- a/gcc/toplev.c > +++ b/gcc/toplev.c > @@ -78,6 +78,7 @@ along with GCC; see the file COPYING3. If not see > #include "diagnostic-color.h" > #include "context.h" > #include "pass_manager.h" > +#include "omp-low.h" > > #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) > #include "dbxout.h" > @@ -576,6 +577,8 @@ compile_file (void) > if (flag_sanitize & SANITIZE_THREAD) > tsan_finish_file (); > > + omp_finish_file (); > + > output_shared_constant_pool (); > output_object_blocks (); > finish_tm_clone_pairs (); > -- > 1.7.1 >