From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 39422 invoked by alias); 27 Nov 2015 14:40:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 39411 invoked by uid 89); 27 Nov 2015 14:40:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Fri, 27 Nov 2015 14:40:47 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 7F1D7AB13 for ; Fri, 27 Nov 2015 14:39:04 +0000 (UTC) To: GCC Patches From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Subject: [HSA] Implementation of various omp_* function Message-ID: <56586B6B.3030203@suse.cz> Date: Fri, 27 Nov 2015 14:41:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------060109050303010102040403" X-IsSubscribed: yes X-SW-Source: 2015-11/txt/msg03379.txt.bz2 This is a multi-part message in MIME format. --------------060109050303010102040403 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 112 Hello. Following pair of patches implements missing omp function. Installed to the HSA branch. Thanks, Martin --------------060109050303010102040403 Content-Type: text/x-patch; name="0001-HSA-implement-omp_get_level.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-HSA-implement-omp_get_level.patch" Content-length: 15083 >From 90cb91ca75ce29e560184fbd1ca03a7e58fc6685 Mon Sep 17 00:00:00 2001 From: marxin Date: Thu, 26 Nov 2015 10:18:44 +0100 Subject: [PATCH 1/5] HSA: implement omp_get_level libgomp/ChangeLog: 2015-11-26 Martin Liska * plugin/plugin-hsa.c (struct hsa_kernel_description): Add field gridified_kernel_p. (struct kernel_info): Likewise. (GOMP_OFFLOAD_load_image): Fill-up the field. (init_single_kernel): Dump value of the field. (create_kernel_dispatch): Set-up omp_level for kernel packet dispatch structure. gcc/ChangeLog: 2015-11-26 Martin Liska * hsa-brig.c (hsa_output_kernels): Append gridified_kernel_p to kernel_info structure. * hsa-gen.c (gen_get_level): Generate call of the builtin. (gen_hsa_insns_for_known_library_call): Call the aforementioned function. (generate_hsa):Output gridified_kernel_p from HSA summary. * hsa.c (struct hsa_decl_kernel_map_element): Add gridified_kernel_p field. (hsa_add_kern_decl_mapping): Add argument for the field. (hsa_get_decl_kernel_mapping_gridified): New function. (hsa_summary_t::link_functions): Add new argument for gridified_kernel_p. (hsa_register_kernel): Mark gridified kernel within HSA summary. * hsa.h (struct hsa_function_summary): Declare new field in HSA summary. * ipa-hsa.c (process_hsa_functions): Use modified signature of link_functions. include/ChangeLog: 2015-11-26 Martin Liska * gomp-constants.h (struct GOMP_hsa_kernel_dispatch): Declare new field in kernel dispatch structure. --- gcc/hsa-brig.c | 27 ++++++++++++++++++--------- gcc/hsa-gen.c | 39 ++++++++++++++++++++++++++++++++++++++- gcc/hsa.c | 25 ++++++++++++++++++------- gcc/hsa.h | 11 ++++++++--- gcc/ipa-hsa.c | 4 ++-- include/gomp-constants.h | 2 ++ libgomp/plugin/plugin-hsa.c | 7 +++++++ 7 files changed, 93 insertions(+), 22 deletions(-) diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c index ca30598..9f65d50 100644 --- a/gcc/hsa-brig.c +++ b/gcc/hsa-brig.c @@ -1982,15 +1982,19 @@ hsa_output_kernels (tree *host_func_table, tree *kernels) unsigned_type_node); DECL_CHAIN (id_f2) = id_f1; tree id_f3 = build_decl (BUILTINS_LOCATION, FIELD_DECL, - get_identifier ("kernel_dependencies_count"), - unsigned_type_node); + get_identifier ("gridified_kernel_p"), + boolean_type_node); DECL_CHAIN (id_f3) = id_f2; tree id_f4 = build_decl (BUILTINS_LOCATION, FIELD_DECL, + get_identifier ("kernel_dependencies_count"), + unsigned_type_node); + DECL_CHAIN (id_f4) = id_f3; + tree id_f5 = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("kernel_dependencies"), build_pointer_type (build_pointer_type (char_type_node))); - DECL_CHAIN (id_f4) = id_f3; - finish_builtin_struct (kernel_info_type, "__hsa_kernel_info", id_f4, + DECL_CHAIN (id_f5) = id_f4; + finish_builtin_struct (kernel_info_type, "__hsa_kernel_info", id_f5, NULL_TREE); int_num_of_kernels = build_int_cstu (uint32_type_node, map_count); @@ -2018,7 +2022,10 @@ hsa_output_kernels (tree *host_func_table, tree *kernels) free (copy); unsigned omp_size = hsa_get_decl_kernel_mapping_omp_size (i); - tree omp_data_size = build_int_cstu (uint32_type_node, omp_size); + tree omp_data_size = build_int_cstu (unsigned_type_node, omp_size); + bool gridified_kernel_p = hsa_get_decl_kernel_mapping_gridified (i); + tree gridified_kernel_p_tree = build_int_cstu (boolean_type_node, + gridified_kernel_p); unsigned count = 0; kernel_dependencies_vector_type = build_array_type @@ -2057,7 +2064,7 @@ hsa_output_kernels (tree *host_func_table, tree *kernels) } } - tree dependencies_count = build_int_cstu (uint32_type_node, count); + tree dependencies_count = build_int_cstu (unsigned_type_node, count); vec *kernel_info_vec = NULL; CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE, @@ -2066,11 +2073,10 @@ hsa_output_kernels (tree *host_func_table, tree *kernels) (kern_name)), kern_name)); CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE, omp_data_size); + CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE, + gridified_kernel_p_tree); CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE, dependencies_count); - tree kernel_info_ctor = build_constructor (kernel_info_type, - kernel_info_vec); - if (count > 0) { ASM_GENERATE_INTERNAL_LABEL (tmp_name, "__hsa_dependencies_list", i); @@ -2098,6 +2104,9 @@ hsa_output_kernels (tree *host_func_table, tree *kernels) else CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE, null_pointer_node); + tree kernel_info_ctor = build_constructor (kernel_info_type, + kernel_info_vec); + CONSTRUCTOR_APPEND_ELT (kernel_info_vector_vec, NULL_TREE, kernel_info_ctor); } diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index 0df1eb6..5993ed5 100644 --- a/gcc/hsa-gen.c +++ b/gcc/hsa-gen.c @@ -3594,6 +3594,38 @@ gen_get_team_num (gimple *stmt, hsa_bb *hbb) hbb->append_insn (basic); } +/* Emit instructions that get levels-var ICV to lhs of gimple STMT. + Instructions are appended to basic block HBB. */ + +static void +gen_get_level (gimple *stmt, hsa_bb *hbb) +{ + if (gimple_call_lhs (stmt) == NULL_TREE) + return; + + hbb->append_insn (new hsa_insn_comment ("omp_get_level")); + + tree lhs = gimple_call_lhs (stmt); + hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs); + + hsa_op_reg *shadow_reg_ptr = hsa_cfun->get_shadow_reg (); + if (shadow_reg_ptr == NULL) + { + HSA_SORRY_AT (gimple_location (stmt), + "support for HSA does not implement omp_get_level called " + "from a function not being inlined within a kernel"); + return; + } + + hsa_op_address *addr = new hsa_op_address + (shadow_reg_ptr, offsetof (GOMP_hsa_kernel_dispatch, omp_level)); + + hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_LD, BRIG_TYPE_U64, NULL, + addr); + hbb->append_insn (mem); + mem->set_output_in_type (dest, 0, hbb); +} + /* Emit instructions that implement alloca builtin gimple STMT. Instructions are appended to basic block HBB. */ @@ -3687,6 +3719,8 @@ gen_hsa_insns_for_known_library_call (gimple *stmt, hsa_bb *hbb) gen_get_num_teams (stmt, hbb); else if (strcmp (name, "omp_get_team_num") == 0) gen_get_team_num (stmt, hbb); + else if (strcmp (name, "omp_get_level") == 0) + gen_get_level (stmt, hbb); else if (strcmp (name, "hsa_set_debug_value") == 0) { if (hsa_cfun->has_shadow_reg_p ()) @@ -5576,8 +5610,11 @@ generate_hsa (bool kernel) if (hsa_cfun->m_kern_p) { + hsa_function_summary *s = hsa_summaries->get + (cgraph_node::get (hsa_cfun->m_decl)); hsa_add_kern_decl_mapping (current_function_decl, hsa_cfun->m_name, - hsa_cfun->m_maximum_omp_data_size); + hsa_cfun->m_maximum_omp_data_size, + s->m_gridified_kernel_p); } #ifdef ENABLE_CHECKING diff --git a/gcc/hsa.c b/gcc/hsa.c index 8ab5da7..7c4e404 100644 --- a/gcc/hsa.c +++ b/gcc/hsa.c @@ -52,6 +52,8 @@ struct GTY(()) hsa_decl_kernel_map_element char * GTY((skip)) name; /* Size of OMP data, if the kernel contains a kernel dispatch. */ unsigned omp_data_size; + /* True if the function is gridified kernel. */ + bool gridified_kernel_p; }; /* Mapping between decls and corresponding HSA kernels in this compilation @@ -584,12 +586,14 @@ hsa_destroy_operand (hsa_op_base *op) /* Create a mapping between the original function DECL and kernel name NAME. */ void -hsa_add_kern_decl_mapping (tree decl, char *name, unsigned omp_data_size) +hsa_add_kern_decl_mapping (tree decl, char *name, unsigned omp_data_size, + bool gridified_kernel_p) { hsa_decl_kernel_map_element dkm; dkm.decl = decl; dkm.name = name; dkm.omp_data_size = omp_data_size; + dkm.gridified_kernel_p = gridified_kernel_p; vec_safe_push (hsa_decl_kernel_mapping, dkm); } @@ -625,6 +629,14 @@ hsa_get_decl_kernel_mapping_omp_size (unsigned i) return (*hsa_decl_kernel_mapping)[i].omp_data_size; } +/* Return if the function is gridified kernel in decl name mapping. */ + +bool +hsa_get_decl_kernel_mapping_gridified (unsigned i) +{ + return (*hsa_decl_kernel_mapping)[i].gridified_kernel_p; +} + /* Free the mapping between original decls and kernel names. */ void @@ -708,13 +720,9 @@ hsa_get_declaration_name (tree decl) return NULL; } -/* Couple GPU and HOST as gpu-specific and host-specific implementation of the - same function. KIND determines whether GPU is a host-invokable kernel or - gpu-callable function. */ - void hsa_summary_t::link_functions (cgraph_node *gpu, cgraph_node *host, - hsa_function_kind kind) + hsa_function_kind kind, bool gridified_kernel_p) { hsa_function_summary *gpu_summary = get (gpu); hsa_function_summary *host_summary = get (host); @@ -725,6 +733,9 @@ hsa_summary_t::link_functions (cgraph_node *gpu, cgraph_node *host, gpu_summary->m_gpu_implementation_p = true; host_summary->m_gpu_implementation_p = false; + gpu_summary->m_gridified_kernel_p = gridified_kernel_p; + host_summary->m_gridified_kernel_p = gridified_kernel_p; + gpu_summary->m_binded_function = host; host_summary->m_binded_function = gpu; @@ -761,7 +772,7 @@ hsa_register_kernel (cgraph_node *gpu, cgraph_node *host) { if (hsa_summaries == NULL) hsa_summaries = new hsa_summary_t (symtab); - hsa_summaries->link_functions (gpu, host, HSA_KERNEL); + hsa_summaries->link_functions (gpu, host, HSA_KERNEL, true); } /* Return true if expansion of the current HSA function has already failed. */ diff --git a/gcc/hsa.h b/gcc/hsa.h index dc2202a..a59a725 100644 --- a/gcc/hsa.h +++ b/gcc/hsa.h @@ -1151,6 +1151,9 @@ struct hsa_function_summary /* Identifies if the function is an HSA function or a host function. */ bool m_gpu_implementation_p; + + /* True if the function is a gridified kernel. */ + bool m_gridified_kernel_p; }; inline @@ -1168,10 +1171,11 @@ public: /* Couple GPU and HOST as gpu-specific and host-specific implementation of the same function. KIND determines whether GPU is a host-invokable kernel - or gpu-callable function. */ + or gpu-callable function and GRIDIFIED_KERNEL_P is set if the function was + gridified in OMP. */ void link_functions (cgraph_node *gpu, cgraph_node *host, - hsa_function_kind kind); + hsa_function_kind kind, bool gridified_kernel_p); }; /* in hsa.c */ @@ -1200,11 +1204,12 @@ BrigAlignment8_t hsa_alignment_encoding (unsigned n); BrigAlignment8_t hsa_natural_alignment (BrigType16_t type); void hsa_destroy_operand (hsa_op_base *op); void hsa_destroy_insn (hsa_insn_basic *insn); -void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned); +void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool); unsigned hsa_get_number_decl_kernel_mappings (void); tree hsa_get_decl_kernel_mapping_decl (unsigned i); char *hsa_get_decl_kernel_mapping_name (unsigned i); unsigned hsa_get_decl_kernel_mapping_omp_size (unsigned i); +bool hsa_get_decl_kernel_mapping_gridified (unsigned i); void hsa_free_decl_kernel_mapping (void); void hsa_add_kernel_dependency (tree caller, const char *called_function); void hsa_sanitize_name (char *p); diff --git a/gcc/ipa-hsa.c b/gcc/ipa-hsa.c index d77fa6b..a497841 100644 --- a/gcc/ipa-hsa.c +++ b/gcc/ipa-hsa.c @@ -92,7 +92,7 @@ process_hsa_functions (void) TREE_PUBLIC (clone->decl) = TREE_PUBLIC (node->decl); clone->force_output = true; - hsa_summaries->link_functions (clone, node, s->m_kind); + hsa_summaries->link_functions (clone, node, s->m_kind, false); if (dump_file) fprintf (dump_file, "Created a new HSA clone: %s, type: %s\n", @@ -109,7 +109,7 @@ process_hsa_functions (void) if (!cgraph_local_p (node)) clone->force_output = true; - hsa_summaries->link_functions (clone, node, HSA_FUNCTION); + hsa_summaries->link_functions (clone, node, HSA_FUNCTION, false); if (dump_file) fprintf (dump_file, "Created a new HSA function clone: %s\n", diff --git a/include/gomp-constants.h b/include/gomp-constants.h index b710eb1..1dae474 100644 --- a/include/gomp-constants.h +++ b/include/gomp-constants.h @@ -294,6 +294,8 @@ struct GOMP_hsa_kernel_dispatch uint32_t omp_num_threads; /* Debug purpose argument. */ uint64_t debug; + /* Levels-var ICV. */ + uint64_t omp_level; /* Kernel dispatch structures created for children kernel dispatches. */ struct GOMP_hsa_kernel_dispatch **children_dispatches; }; diff --git a/libgomp/plugin/plugin-hsa.c b/libgomp/plugin/plugin-hsa.c index 39e2366..b132954 100644 --- a/libgomp/plugin/plugin-hsa.c +++ b/libgomp/plugin/plugin-hsa.c @@ -157,6 +157,7 @@ struct hsa_kernel_description { const char *name; unsigned omp_data_size; + bool gridified_kernel_p; unsigned kernel_dependencies_count; const char **kernel_dependencies; }; @@ -217,6 +218,8 @@ struct kernel_info unsigned dependencies_count; /* Maximum OMP data size necessary for kernel from kernel dispatches. */ unsigned max_omp_data_size; + /* True if the kernel is gridified. */ + bool gridified_kernel_p; }; /* Information about a particular brig module, its image and kernels. */ @@ -619,6 +622,7 @@ GOMP_OFFLOAD_load_image (int ord, unsigned version, void *target_data, kernel->module = module; kernel->name = d->name; kernel->omp_data_size = d->omp_data_size; + kernel->gridified_kernel_p = d->gridified_kernel_p; kernel->dependencies_count = d->kernel_dependencies_count; kernel->dependencies = d->kernel_dependencies; if (pthread_mutex_init (&kernel->init_mutex, NULL)) @@ -916,6 +920,7 @@ init_single_kernel (struct kernel_info *kernel, unsigned *max_omp_data_size) HSA_DEBUG (" kernarg_segment_size: %u\n", (unsigned) kernel->kernarg_segment_size); HSA_DEBUG (" omp_data_size: %u\n", kernel->omp_data_size); + HSA_DEBUG (" gridified_kernel_p: %u\n", kernel->gridified_kernel_p); if (kernel->omp_data_size > *max_omp_data_size) *max_omp_data_size = kernel->omp_data_size; @@ -1003,6 +1008,7 @@ create_kernel_dispatch (struct kernel_info *kernel, unsigned omp_data_size) (kernel, omp_data_size); shadow->omp_num_threads = 64; shadow->debug = 0; + shadow->omp_level = kernel->gridified_kernel_p ? 1 : 0; /* Create kernel dispatch data structures. We do not allow to have a kernel dispatch with depth bigger than one. */ @@ -1014,6 +1020,7 @@ create_kernel_dispatch (struct kernel_info *kernel, unsigned omp_data_size) (dependency, omp_data_size); shadow->children_dispatches[i]->queue = kernel->agent->kernel_dispatch_command_q; + shadow->children_dispatches[i]->omp_level = 1; } return shadow; -- 2.6.3 --------------060109050303010102040403 Content-Type: text/x-patch; name="0002-HSA-implement-various-omp_-functions.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0002-HSA-implement-various-omp_-functions.patch" Content-length: 11683 >From d44e7fa95b57574fade387a8094e1b733221f8b5 Mon Sep 17 00:00:00 2001 From: marxin Date: Thu, 26 Nov 2015 10:59:52 +0100 Subject: [PATCH 2/5] HSA: implement various omp_* functions. gcc/ChangeLog: 2015-11-26 Martin Liska * hsa-gen.c (hsa_init_simple_builtins): New function. (hsa_deinit_data_for_cfun): Release memory of omp_simple_builtins. (gen_get_num_teams): Change comment message. (gen_get_team_num): Likewise. (gen_get_max_threads): Dtto. (omp_simple_builtin::generate): New method. (gen_hsa_insns_for_known_library_call): Handle new set of OMP functions. * hsa.h (class simple_omp_builtin): New class. --- gcc/hsa-gen.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- gcc/hsa.h | 32 +++++++++- 2 files changed, 197 insertions(+), 26 deletions(-) diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index 5993ed5..ed47b35 100644 --- a/gcc/hsa-gen.c +++ b/gcc/hsa-gen.c @@ -306,6 +306,76 @@ hsa_function_representation::create_hsa_temporary (BrigType16_t type) return s; } +/* Hash map of simple OMP builtins. */ +static hash_map *omp_simple_builtins + = NULL; + +/* Warning messages for OMP builtins. */ + +#define HSA_WARN_LOCK_ROUTINE "support for HSA does not implement OMP lock " \ + "routine" +#define HSA_WARN_TIMING_ROUTINE "support for HSA does not implement OMP " \ + "timing routine" +#define HSA_WARN_MEMORY_ROUTINE "support for HSA does not implement OMP " \ + "device memory routine" + +/* Initialize hash map with simple OMP builtins. */ + +static void +hsa_init_simple_builtins () +{ + if (omp_simple_builtins != NULL) + return; + + omp_simple_builtins = new hash_map + (); + + omp_simple_builtin omp_builtins[] = + { + omp_simple_builtin + ("omp_get_initial_device", NULL, false, + new hsa_op_immed (GOMP_DEVICE_HOST, (BrigType16_t) BRIG_TYPE_S64)), + omp_simple_builtin ("omp_is_initial_device", NULL, false, + new hsa_op_immed (0, (BrigType16_t) BRIG_TYPE_S64)), + omp_simple_builtin ("omp_get_dynamic", NULL, false, + new hsa_op_immed (0, (BrigType16_t) BRIG_TYPE_S64)), + omp_simple_builtin ("omp_set_dynamic", NULL, false, NULL), + omp_simple_builtin ("omp_init_lock", HSA_WARN_LOCK_ROUTINE, true), + omp_simple_builtin ("omp_init_lock_with_hint", HSA_WARN_LOCK_ROUTINE, + true), + omp_simple_builtin ("omp_init_nest_lock_with_hint", HSA_WARN_LOCK_ROUTINE, + true), + omp_simple_builtin ("omp_destroy_lock", HSA_WARN_LOCK_ROUTINE, true), + omp_simple_builtin ("omp_set_lock", HSA_WARN_LOCK_ROUTINE, true), + omp_simple_builtin ("omp_unset_lock", HSA_WARN_LOCK_ROUTINE, true), + omp_simple_builtin ("omp_test_lock", HSA_WARN_LOCK_ROUTINE, true), + omp_simple_builtin ("omp_get_wtime", HSA_WARN_TIMING_ROUTINE, true), + omp_simple_builtin ("omp_get_wtick", HSA_WARN_TIMING_ROUTINE, true), + omp_simple_builtin ("omp_target_alloc", HSA_WARN_MEMORY_ROUTINE, false, + new hsa_op_immed (0, (BrigType16_t) BRIG_TYPE_U64)), + omp_simple_builtin ("omp_target_free", HSA_WARN_MEMORY_ROUTINE, false), + omp_simple_builtin + ("omp_target_is_present", HSA_WARN_MEMORY_ROUTINE, + false, new hsa_op_immed (-1, (BrigType16_t) BRIG_TYPE_S64)), + omp_simple_builtin ("omp_target_memcpy", HSA_WARN_MEMORY_ROUTINE, false, + new hsa_op_immed (-1, (BrigType16_t) BRIG_TYPE_S64)), + omp_simple_builtin + ("omp_target_memcpy_rect", HSA_WARN_MEMORY_ROUTINE, + false, new hsa_op_immed (-1, (BrigType16_t) BRIG_TYPE_S64)), + omp_simple_builtin + ("omp_target_associate_ptr", HSA_WARN_MEMORY_ROUTINE, false, + new hsa_op_immed (-1, (BrigType16_t) BRIG_TYPE_S64)), + omp_simple_builtin + ("omp_target_disassociate_ptr", HSA_WARN_MEMORY_ROUTINE, + false, new hsa_op_immed (-1, (BrigType16_t) BRIG_TYPE_S64)) + }; + + unsigned count = sizeof (omp_builtins) / sizeof (omp_simple_builtin); + + for (unsigned i = 0; i < count; i++) + omp_simple_builtins->put (omp_builtins[i].m_name, omp_builtins[i]); +} + /* Allocate HSA structures that we need only while generating with this. */ static void @@ -382,6 +452,12 @@ hsa_deinit_data_for_cfun (void) hsa_instructions.release (); + if (omp_simple_builtins != NULL) + { + delete omp_simple_builtins; + omp_simple_builtins = NULL; + } + delete hsa_allocp_operand_address; delete hsa_allocp_operand_immed; delete hsa_allocp_operand_reg; @@ -908,7 +984,7 @@ hsa_op_immed::hsa_op_immed (tree tree_val, bool min32int) /* Constructor of class representing HSA immediate values. INTEGER_VALUE is the integer representation of the immediate value. TYPE is BRIG type. */ -hsa_op_immed::hsa_op_immed (HOST_WIDE_INT integer_value, BrigKind16_t type) +hsa_op_immed::hsa_op_immed (HOST_WIDE_INT integer_value, BrigType16_t type) : hsa_op_with_type (BRIG_KIND_OPERAND_CONSTANT_BYTES, type), m_tree_value (NULL), m_brig_repr (NULL) { @@ -3559,8 +3635,7 @@ gen_get_num_teams (gimple *stmt, hsa_bb *hbb) if (gimple_call_lhs (stmt) == NULL_TREE) return; - hbb->append_insn - (new hsa_insn_comment ("__builtin_omp_get_num_teams")); + hbb->append_insn (new hsa_insn_comment ("omp_get_num_teams")); tree lhs = gimple_call_lhs (stmt); hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs); @@ -3581,8 +3656,7 @@ gen_get_team_num (gimple *stmt, hsa_bb *hbb) if (gimple_call_lhs (stmt) == NULL_TREE) return; - hbb->append_insn - (new hsa_insn_comment ("__builtin_omp_get_team_num")); + hbb->append_insn (new hsa_insn_comment ("omp_get_team_num")); tree lhs = gimple_call_lhs (stmt); hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs); @@ -3626,6 +3700,23 @@ gen_get_level (gimple *stmt, hsa_bb *hbb) mem->set_output_in_type (dest, 0, hbb); } +/* Emit instruction that implement omp_get_max_threads of gimple STMT. */ + +static void +gen_get_max_threads (gimple *stmt, hsa_bb *hbb) +{ + tree lhs = gimple_call_lhs (stmt); + if (!lhs) + return; + + hbb->append_insn (new hsa_insn_comment ("omp_get_max_threads")); + + hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs); + hsa_op_with_type *num_theads_reg = gen_num_threads_for_dispatch (hbb) + ->get_in_type (dest->m_type, hbb); + hsa_build_append_simple_mov (dest, num_theads_reg, hbb); +} + /* Emit instructions that implement alloca builtin gimple STMT. Instructions are appended to basic block HBB. */ @@ -3690,6 +3781,35 @@ set_debug_value (hsa_bb *hbb, hsa_op_with_type *value) hbb->append_insn (mem); } +void +omp_simple_builtin::generate (gimple *stmt, hsa_bb *hbb) +{ + if (m_sorry) + { + if (m_warning_message) + HSA_SORRY_AT (gimple_location (stmt), m_warning_message) + else + HSA_SORRY_ATV (gimple_location (stmt), + "Support for HSA does not implement calls to %s\n", + m_name) + } + else if (m_warning_message != NULL) + warning_at (gimple_location (stmt), OPT_Whsa, m_warning_message); + + if (m_return_value != NULL) + { + tree lhs = gimple_call_lhs (stmt); + if (!lhs) + return; + + hbb->append_insn (new hsa_insn_comment (m_name)); + + hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs); + hsa_build_append_simple_mov + (dest, m_return_value->get_in_type (dest->m_type, hbb), hbb); + } +} + /* If STMT is a call of a known library function, generate code to perform it and return true. */ @@ -3698,30 +3818,51 @@ gen_hsa_insns_for_known_library_call (gimple *stmt, hsa_bb *hbb) { const char *name = hsa_get_declaration_name (gimple_call_fndecl (stmt)); - if (strcmp (name, "omp_is_initial_device") == 0) + /* Handle omp_* routines. */ + if (strstr (name, "omp_") == name) { - tree lhs = gimple_call_lhs (stmt); - if (!lhs) - return true; + hsa_init_simple_builtins (); + omp_simple_builtin *builtin = omp_simple_builtins->get (name); + if (builtin) + { + builtin->generate (stmt, hbb); + return true; + } - hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs); - hsa_op_immed *imm = new hsa_op_immed (build_zero_cst (TREE_TYPE (lhs))); + bool handled = true; - hsa_build_append_simple_mov (dest, imm, hbb); + if (strcmp (name, "omp_set_num_threads") == 0) + gen_set_num_threads (gimple_call_arg (stmt, 0), hbb); + else if (strcmp (name, "omp_get_thread_num") == 0) + { + hbb->append_insn (new hsa_insn_comment (name)); + query_hsa_grid (stmt, BRIG_OPCODE_WORKITEMABSID, 0, hbb); + } + else if (strcmp (name, "omp_get_num_threads") == 0) + { + hbb->append_insn (new hsa_insn_comment (name)); + query_hsa_grid (stmt, BRIG_OPCODE_GRIDSIZE, 0, hbb); + } + else if (strcmp (name, "omp_get_num_teams") == 0) + gen_get_num_teams (stmt, hbb); + else if (strcmp (name, "omp_get_team_num") == 0) + gen_get_team_num (stmt, hbb); + else if (strcmp (name, "omp_get_level") == 0) + gen_get_level (stmt, hbb); + else if (strcmp (name, "omp_get_active_level") == 0) + gen_get_level (stmt, hbb); + else if (strcmp (name, "omp_in_parallel") == 0) + gen_get_level (stmt, hbb); + else if (strcmp (name, "omp_get_max_threads") == 0) + gen_get_max_threads (stmt, hbb); + else + handled = false; + + if (handled) + return true; } - else if (strcmp (name, "omp_set_num_threads") == 0) - gen_set_num_threads (gimple_call_arg (stmt, 0), hbb); - else if (strcmp (name, "omp_get_thread_num") == 0) - query_hsa_grid (stmt, BRIG_OPCODE_WORKITEMABSID, 0, hbb); - else if (strcmp (name, "omp_get_num_threads") == 0) - query_hsa_grid (stmt, BRIG_OPCODE_GRIDSIZE, 0, hbb); - else if (strcmp (name, "omp_get_num_teams") == 0) - gen_get_num_teams (stmt, hbb); - else if (strcmp (name, "omp_get_team_num") == 0) - gen_get_team_num (stmt, hbb); - else if (strcmp (name, "omp_get_level") == 0) - gen_get_level (stmt, hbb); - else if (strcmp (name, "hsa_set_debug_value") == 0) + + if (strcmp (name, "__hsa_set_debug_value") == 0) { if (hsa_cfun->has_shadow_reg_p ()) { diff --git a/gcc/hsa.h b/gcc/hsa.h index a59a725..e4bea99 100644 --- a/gcc/hsa.h +++ b/gcc/hsa.h @@ -163,7 +163,7 @@ class hsa_op_immed : public hsa_op_with_type { public: hsa_op_immed (tree tree_val, bool min32int = true); - hsa_op_immed (HOST_WIDE_INT int_value, BrigKind16_t type); + hsa_op_immed (HOST_WIDE_INT int_value, BrigType16_t type); void *operator new (size_t); ~hsa_op_immed (); void set_type (BrigKind16_t t); @@ -1178,6 +1178,36 @@ public: hsa_function_kind kind, bool gridified_kernel_p); }; +/* OMP simple builtin describes behavior that should be done for + the routine. */ +class omp_simple_builtin +{ +public: + omp_simple_builtin (const char *name, const char *warning_message, + bool sorry, hsa_op_immed *return_value = NULL): + m_name (name), m_warning_message (warning_message), m_sorry (sorry), + m_return_value (return_value) + {} + + /* Generate HSAIL instructions for the builtin or produce warning message. */ + void generate (gimple *stmt, hsa_bb *hbb); + + /* Name of function. */ + const char *m_name; + + /* Warning message. */ + const char *m_warning_message; + + /* Flag if we should sorry after the warning message is printed. */ + bool m_sorry; + + /* Return value of the function. */ + hsa_op_immed *m_return_value; + + /* Emission function. */ + void (*m_emit_func) (gimple *stmt, hsa_bb *); +}; + /* in hsa.c */ extern struct hsa_function_representation *hsa_cfun; extern hash_map *> *hsa_decl_kernel_dependencies; -- 2.6.3 --------------060109050303010102040403--