Mercurial > hg > CbC > CbC_gcc
diff gcc/brig/brigfrontend/brig-function-handler.cc @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/brig/brigfrontend/brig-function-handler.cc Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/brig/brigfrontend/brig-function-handler.cc Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* brig-code-entry-handler.cc -- brig function directive handling - Copyright (C) 2016-2017 Free Software Foundation, Inc. + Copyright (C) 2016-2018 Free Software Foundation, Inc. Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com> for General Processor Tech. @@ -80,6 +80,10 @@ if (m_parent.m_analyzing) return bytes_consumed; + /* There can be multiple forward declarations of the same function. + Skip all but the first one. */ + if (!is_definition && m_parent.function_decl (func_name) != NULL_TREE) + return bytes_consumed; tree fndecl; tree ret_value = NULL_TREE; @@ -89,6 +93,25 @@ represent HSAIL registers. */ tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL); + tree restrict_char_ptr + = build_qualified_type (build_pointer_type (char_type_node), + TYPE_QUAL_RESTRICT); + tree restrict_void_ptr + = build_qualified_type (build_pointer_type (void_type_node), + TYPE_QUAL_RESTRICT); + + tree restrict_const_char_ptr + = build_qualified_type (build_pointer_type + (build_qualified_type (char_type_node, + TYPE_QUAL_CONST)), + TYPE_QUAL_RESTRICT); + + tree restrict_const_void_ptr + = build_qualified_type (build_pointer_type + (build_qualified_type (void_type_node, + TYPE_QUAL_CONST)), + TYPE_QUAL_RESTRICT); + if (is_kernel) { tree name_identifier @@ -103,12 +126,11 @@ 3) a void* parameter that contains the first flat address of the group region allocated to the current work-group. */ - tree char_ptr_type_node = build_pointer_type (char_type_node); fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, build_function_type_list (void_type_node, - char_ptr_type_node, - ptr_type_node, - ptr_type_node, NULL_TREE)); + restrict_const_char_ptr, + restrict_void_ptr, + restrict_char_ptr, NULL_TREE)); SET_DECL_ASSEMBLER_NAME (fndecl, name_identifier); @@ -121,9 +143,10 @@ = gccbrig_get_target_addr_space_id (BRIG_SEGMENT_KERNARG); tree arg_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__args"), char_ptr_type_node); + get_identifier ("__args"), + restrict_const_char_ptr); DECL_ARGUMENTS (fndecl) = arg_arg; - DECL_ARG_TYPE (arg_arg) = char_ptr_type_node; + DECL_ARG_TYPE (arg_arg) = restrict_const_char_ptr; DECL_CONTEXT (arg_arg) = fndecl; DECL_ARTIFICIAL (arg_arg) = 1; TREE_READONLY (arg_arg) = 1; @@ -132,6 +155,14 @@ DECL_RESULT (fndecl) = resdecl; DECL_CONTEXT (resdecl) = fndecl; DECL_EXTERNAL (fndecl) = 0; + + /* Aggressive inlining to the kernel function is usually a good + idea with offlined functionality to enchance SIMD execution on + GPUs and vector units. */ + + DECL_ATTRIBUTES (fndecl) + = tree_cons (get_identifier ("flatten"), NULL, + DECL_ATTRIBUTES (fndecl)); } else { @@ -177,7 +208,7 @@ if (arg_decls == NULL_TREE) arg_decls = arg_var; else - chainon (arg_decls, arg_var); + arg_decls = chainon (arg_decls, arg_var); m_parent.m_cf->add_arg_variable (brigVar, arg_var); @@ -218,16 +249,13 @@ vec_safe_push (args, TREE_TYPE (arg_var)); m_parent.m_cf->add_arg_variable (brigVar, arg_var); - - if (arg_decls == NULL_TREE) - arg_decls = arg_var; - else - chainon (arg_decls, arg_var); + arg_decls = chainon (arg_decls, arg_var); } } - - vec_safe_push (args, ptr_type_node); - vec_safe_push (args, ptr_type_node); + vec_safe_push (args, restrict_void_ptr); + vec_safe_push (args, restrict_char_ptr); + vec_safe_push (args, uint32_type_node); + vec_safe_push (args, restrict_char_ptr); fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, build_function_type_vec (ret_type, args)); @@ -240,26 +268,30 @@ /* All functions need the hidden __context argument passed on because they might call WI-specific functions which need - the context info. */ + the context info. Only kernels can write it, if they need + to update the local ids in the work-item loop. */ + + tree context_arg_type + = true ? restrict_void_ptr : restrict_const_void_ptr; tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__context"), ptr_type_node); - if (DECL_ARGUMENTS (fndecl) == NULL_TREE) - DECL_ARGUMENTS (fndecl) = context_arg; - else - chainon (DECL_ARGUMENTS (fndecl), context_arg); + get_identifier ("__context"), + context_arg_type); + DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), context_arg); DECL_CONTEXT (context_arg) = fndecl; - DECL_ARG_TYPE (context_arg) = ptr_type_node; + DECL_ARG_TYPE (context_arg) = context_arg_type; DECL_ARTIFICIAL (context_arg) = 1; TREE_READONLY (context_arg) = 1; TREE_USED (context_arg) = 1; + m_parent.m_cf->m_context_arg = context_arg; /* They can also access group memory, so we need to pass the group pointer along too. */ tree group_base_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__group_base_addr"), ptr_type_node); - chainon (DECL_ARGUMENTS (fndecl), group_base_arg); - DECL_ARG_TYPE (group_base_arg) = ptr_type_node; + get_identifier ("__group_base_addr"), + restrict_char_ptr); + DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), group_base_arg); + DECL_ARG_TYPE (group_base_arg) = restrict_char_ptr; DECL_CONTEXT (group_base_arg) = fndecl; DECL_ARTIFICIAL (group_base_arg) = 1; TREE_READONLY (group_base_arg) = 1; @@ -274,7 +306,7 @@ tree group_local_offset_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, get_identifier ("__group_local_offset"), uint32_type_node); - chainon (DECL_ARGUMENTS (fndecl), group_local_offset_arg); + DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), group_local_offset_arg); DECL_ARG_TYPE (group_local_offset_arg) = uint32_type_node; DECL_CONTEXT (group_local_offset_arg) = fndecl; DECL_ARTIFICIAL (group_local_offset_arg) = 1; @@ -285,37 +317,39 @@ /* Same for private. */ tree private_base_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__private_base_addr"), ptr_type_node); - chainon (DECL_ARGUMENTS (fndecl), private_base_arg); - DECL_ARG_TYPE (private_base_arg) = ptr_type_node; + get_identifier ("__private_base_addr"), restrict_char_ptr); + DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), private_base_arg); + DECL_ARG_TYPE (private_base_arg) = restrict_char_ptr; DECL_CONTEXT (private_base_arg) = fndecl; DECL_ARTIFICIAL (private_base_arg) = 1; TREE_READONLY (private_base_arg) = 1; TREE_USED (private_base_arg) = 1; + m_parent.m_cf->m_private_base_arg = private_base_arg; DECL_SAVED_TREE (fndecl) = bind_expr; - /* Try to preserve the functions across IPA. */ - DECL_PRESERVE_P (fndecl) = 1; - TREE_SIDE_EFFECTS (fndecl) = 1; - - TREE_ADDRESSABLE (fndecl) = 1; - if (base->kind == BRIG_KIND_DIRECTIVE_FUNCTION) { - TREE_STATIC (fndecl) = 1; + TREE_STATIC (fndecl) = 0; TREE_PUBLIC (fndecl) = 1; + DECL_EXTERNAL (fndecl) = 0; + DECL_DECLARED_INLINE_P (fndecl) = 1; + set_inline (fndecl); + set_externally_visible (fndecl); } else if (base->kind == BRIG_KIND_DIRECTIVE_KERNEL) { - TREE_STATIC (fndecl) = 1; + TREE_STATIC (fndecl) = 0; TREE_PUBLIC (fndecl) = 1; + DECL_EXTERNAL (fndecl) = 0; + set_externally_visible (fndecl); } else if (base->kind == BRIG_KIND_DIRECTIVE_SIGNATURE) { TREE_STATIC (fndecl) = 0; TREE_PUBLIC (fndecl) = 1; DECL_EXTERNAL (fndecl) = 1; + set_inline (fndecl); } else if (base->kind == BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION) { @@ -349,15 +383,16 @@ m_parent.add_function_decl (func_name, fndecl); m_parent.append_global (fndecl); + if (!is_definition) - return bytes_consumed; + { + DECL_EXTERNAL (fndecl) = 1; + return bytes_consumed; + } m_parent.start_function (fndecl); - m_parent.m_cf->m_func_decl = fndecl; m_parent.m_cf->m_current_bind_expr = bind_expr; - m_parent.m_cf->m_context_arg = context_arg; - m_parent.m_cf->m_private_base_arg = private_base_arg; if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node) {