Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
It looks reasonable to me now. But let's wait for kito's more comments. juzhe.zh...@rivai.ai From: pan2.li Date: 2023-09-12 16:46 To: gcc-patches CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng Subject: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic From: Pan Li Update in v3: * Rewrite comment for overloaded function add. * Move get_non_overloaded_instance to function_base. Update in v2: * Add get_non_overloaded_instance for function instance. * Fix overload check for policy function. * Enrich the test cases check. Original log: This patch would like add the framework to support the RVV overloaded intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did. However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN with below steps. * Register overloaded functions. * Add function_resolver for overloaded function resolving. * Add resolve API for function shape with default implementation. * Implement HOOK for navigating the overloaded API to non-overloaded API. We validated this framework by the vmv_v intrinsic API(s), and we will add more intrins API support in the underlying patches. gcc/ChangeLog: * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook. (riscv_register_pragmas): Register the hook * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl. * config/riscv/riscv-vector-builtins-shapes.cc (build_one): Register overloaded function. (struct overloaded_base): New struct for overloaded shape. (struct non_overloaded_base): New struct for non overloaded shape. (struct move_def): Inherit overloaded shape. * config/riscv/riscv-vector-builtins.cc (function_base::get_non_overloaded_instance): New API impl. (function_builder::add_function): Add overloaded arg. (function_resolver::function_resolver): New constructor. (function_builder::add_overloaded_function): New API impl. (function_resolver::resolve): Ditto. (function_resolver::lookup): Ditto. (function_resolver::get_sub_code): Ditto. (resolve_overloaded_builtin): New function impl. * config/riscv/riscv-vector-builtins.h: (class function_resolver): New class. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/overloaded_rv32_vmv_v.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vmv_v.c: New test. * gcc.target/riscv/rvv/base/overloaded_vmv_v.h: New test. Signed-off-by: Pan Li --- gcc/config/riscv/riscv-c.cc | 36 gcc/config/riscv/riscv-protos.h | 1 + .../riscv/riscv-vector-builtins-shapes.cc | 20 ++- gcc/config/riscv/riscv-vector-builtins.cc | 155 +- gcc/config/riscv/riscv-vector-builtins.h | 36 +++- .../riscv/rvv/base/overloaded_rv32_vmv_v.c| 8 + .../riscv/rvv/base/overloaded_rv64_vmv_v.c| 8 + .../riscv/rvv/base/overloaded_vmv_v.h | 27 +++ 8 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv_v.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv_v.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv_v.h diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc index 283052ae313..060edd3129d 100644 --- a/gcc/config/riscv/riscv-c.cc +++ b/gcc/config/riscv/riscv-c.cc @@ -220,11 +220,47 @@ riscv_check_builtin_call (location_t loc, vec arg_loc, tree fndecl, gcc_unreachable (); } +/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. */ +static tree +riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl, + void *uncast_arglist) +{ + vec empty = {}; + location_t loc = (location_t) uncast_location; + vec *arglist = (vec *) uncast_arglist; + unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); + unsigned int subcode = code >> RISCV_BUILTIN_SHIFT; + tree new_fndecl = NULL_TREE; + + if (!arglist) +arglist = ∅ + + switch (code & RISCV_BUILTIN_CLASS) +{ +case RISCV_BUILTIN_GENERAL: + break; +case RISCV_BUILTIN_VECTOR: + new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode, + arglist); + break; +default: + gcc_unreachable (); +} + + if (new_fndecl == NULL_TREE) +return new_fndecl; + + return build_function_call_vec (loc, vNULL, new_fndecl, arglist, NULL, + fndecl); +} + /* Implement REGISTER_TARGET_PRAGMAS. */ void riscv_register_pragmas (void) { + targetm.resolve_overloaded_builtin = riscv_resolve_overloaded_builtin; targetm.check_builtin_call = riscv_check_builtin_call; + c_register_pragma ("riscv", "intrinsic", riscv_pragma_intrinsic); } diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 6dbf6b9f943..5d2492dd031 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -381,6 +381,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *); rtx expand_builtin (unsigned int, tree, rtx); bool check_builtin_ca
Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
Sorry for comment again. I am not happy with current get_non_overloaeded_instance function. I think the searching approach is very in-effective: +function_instance * +function_base::get_non_overloaded_instance (unsigned int code, + vec &arglist) const +{ + unsigned int code_limit = vec_safe_length (registered_functions); + + for (unsigned fun_code = code; fun_code < code_limit; fun_code++) +{ + registered_function *rfun = (*registered_functions)[fun_code]; + function_instance instance = rfun->instance; + + if (rfun->overloaded_p) + continue; + + unsigned k; + const rvv_arg_type_info *args = instance.op_info->args; + + for (k = 0; args[k].base_type != NUM_BASE_TYPES; k++) + { + if (k >= arglist.length ()) + break; + + if (TYPE_MODE (instance.get_arg_type (k)) + != TYPE_MODE (TREE_TYPE (arglist[k]))) + break; + } + + if (args[k].base_type == NUM_BASE_TYPES) + return &rfun->instance; +} + + return NULL; +} Instead, I think we should build up a table which map non-overloaded function according to the arguments so that we could get the "instance" effectively. E.g. For vint8mf8_t tumu vadd intrinsic the instance is like this: function_instance ("vadd", bases::vadd, shapes::alu, iu_ops[VECTOR_TYPE_vuint8mf8_t], PRED_TYPE_tumu, &iu_vvv_ops); Since the get_nonoverloaed_instance is already the function of the class BASE. So, The first 3 arguments "vadd", bases::vadd, shapes::alu should already known since it is a known function_base. The last 3 arguments may need some elegant analysis or map table to quickly grep. So, I think we should consider this framework seriously. juzhe.zh...@rivai.ai From: pan2.li Date: 2023-09-12 16:46 To: gcc-patches CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng Subject: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic From: Pan Li Update in v3: * Rewrite comment for overloaded function add. * Move get_non_overloaded_instance to function_base. Update in v2: * Add get_non_overloaded_instance for function instance. * Fix overload check for policy function. * Enrich the test cases check. Original log: This patch would like add the framework to support the RVV overloaded intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did. However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN with below steps. * Register overloaded functions. * Add function_resolver for overloaded function resolving. * Add resolve API for function shape with default implementation. * Implement HOOK for navigating the overloaded API to non-overloaded API. We validated this framework by the vmv_v intrinsic API(s), and we will add more intrins API support in the underlying patches. gcc/ChangeLog: * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook. (riscv_register_pragmas): Register the hook * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl. * config/riscv/riscv-vector-builtins-shapes.cc (build_one): Register overloaded function. (struct overloaded_base): New struct for overloaded shape. (struct non_overloaded_base): New struct for non overloaded shape. (struct move_def): Inherit overloaded shape. * config/riscv/riscv-vector-builtins.cc (function_base::get_non_overloaded_instance): New API impl. (function_builder::add_function): Add overloaded arg. (function_resolver::function_resolver): New constructor. (function_builder::add_overloaded_function): New API impl. (function_resolver::resolve): Ditto. (function_resolver::lookup): Ditto. (function_resolver::get_sub_code): Ditto. (resolve_overloaded_builtin): New function impl. * config/riscv/riscv-vector-builtins.h: (class function_resolver): New class. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/overloaded_rv32_vmv_v.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vmv_v.c: New test. * gcc.target/riscv/rvv/base/overloaded_vmv_v.h: New test. Signed-off-by: Pan Li --- gcc/config/riscv/riscv-c.cc | 36 gcc/config/riscv/riscv-protos.h | 1 + .../riscv/riscv-vector-builtins-shapes.cc | 20 ++- gcc/config/riscv/riscv-vector-builtins.cc | 155 +- gcc/config/riscv/riscv-vector-builtins.h | 36 +++- .../riscv/rvv/base/overloaded_rv32_vmv_v.c| 8 + .../riscv/rvv/base/overloaded_rv64_vmv_v.c| 8 + .../riscv/rvv/base/overloaded_vmv_v.h | 27 +++ 8 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv_v.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv_v.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv_v.h diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc index 283052ae313..060edd3129d 100644 --- a/gcc/config/riscv/riscv-c.cc +++ b/gcc/config/riscv/riscv-c.cc @@ -220,11 +220,47 @@ riscv_check_builtin_call (locati
Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
Hi Pan, +function_instance * +function_base::get_non_overloaded_instance (unsigned int code, + vec &arglist) const +{ + unsigned int code_limit = vec_safe_length (registered_functions); + + for (unsigned fun_code = code; fun_code < code_limit; fun_code++) +{ + registered_function *rfun = (*registered_functions)[fun_code]; + function_instance instance = rfun->instance; + + if (rfun->overloaded_p) + continue; + + unsigned k; + const rvv_arg_type_info *args = instance.op_info->args; + + for (k = 0; args[k].base_type != NUM_BASE_TYPES; k++) + { + if (k >= arglist.length ()) + break; Can we fast continue if args length not equal arglist length before this loop: if (args lengh != arglist.length ()) continue; for (k = 0; args[k].base_type != NUM_BASE_TYPES; k++) { ... -- Best, Lehua
RE: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
Thanks Lehua, actually Yes. Consider we will have a try for hashmap way and will keep you posted. Pan -Original Message- From: Lehua Ding Sent: Friday, September 15, 2023 10:29 AM To: Li, Pan2 ; gcc-patches@gcc.gnu.org Cc: Wang, Yanzhang ; kito.ch...@gmail.com; juzhe.zh...@rivai.ai Subject: Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic Hi Pan, > +function_instance * > +function_base::get_non_overloaded_instance (unsigned int code, > + vec &arglist) const > +{ > + unsigned int code_limit = vec_safe_length (registered_functions); > + > + for (unsigned fun_code = code; fun_code < code_limit; fun_code++) > +{ > + registered_function *rfun = (*registered_functions)[fun_code]; > + function_instance instance = rfun->instance; > + > + if (rfun->overloaded_p) > + continue; > + > + unsigned k; > + const rvv_arg_type_info *args = instance.op_info->args; > + > + for (k = 0; args[k].base_type != NUM_BASE_TYPES; k++) > + { > + if (k >= arglist.length ()) > + break; Can we fast continue if args length not equal arglist length before this loop: if (args lengh != arglist.length ()) continue; for (k = 0; args[k].base_type != NUM_BASE_TYPES; k++) { ... -- Best, Lehua
Re: Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
More information: For PRED_TYPE_tumu, it's easy to analyze, just need to count how many arguments in the arglist. If arglist has 5 arguments (mask, merge, op1, op2, len) Then it must be TUMU. What I mean is that we should be able to quickly to compute the arguments of the construction of the function_instance. Then we can get the non-overloaeded function. juzhe.zh...@rivai.ai From: juzhe.zh...@rivai.ai Date: 2023-09-15 10:02 To: pan2.li; gcc-patches CC: pan2.li; yanzhang.wang; kito.cheng Subject: Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic Sorry for comment again. I am not happy with current get_non_overloaeded_instance function. I think the searching approach is very in-effective: +function_instance * +function_base::get_non_overloaded_instance (unsigned int code, + vec &arglist) const +{ + unsigned int code_limit = vec_safe_length (registered_functions); + + for (unsigned fun_code = code; fun_code < code_limit; fun_code++) +{ + registered_function *rfun = (*registered_functions)[fun_code]; + function_instance instance = rfun->instance; + + if (rfun->overloaded_p) + continue; + + unsigned k; + const rvv_arg_type_info *args = instance.op_info->args; + + for (k = 0; args[k].base_type != NUM_BASE_TYPES; k++) + { + if (k >= arglist.length ()) + break; + + if (TYPE_MODE (instance.get_arg_type (k)) + != TYPE_MODE (TREE_TYPE (arglist[k]))) + break; + } + + if (args[k].base_type == NUM_BASE_TYPES) + return &rfun->instance; +} + + return NULL; +} Instead, I think we should build up a table which map non-overloaded function according to the arguments so that we could get the "instance" effectively. E.g. For vint8mf8_t tumu vadd intrinsic the instance is like this: function_instance ("vadd", bases::vadd, shapes::alu, iu_ops[VECTOR_TYPE_vuint8mf8_t], PRED_TYPE_tumu, &iu_vvv_ops); Since the get_nonoverloaed_instance is already the function of the class BASE. So, The first 3 arguments "vadd", bases::vadd, shapes::alu should already known since it is a known function_base. The last 3 arguments may need some elegant analysis or map table to quickly grep. So, I think we should consider this framework seriously. juzhe.zh...@rivai.ai From: pan2.li Date: 2023-09-12 16:46 To: gcc-patches CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng Subject: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic From: Pan Li Update in v3: * Rewrite comment for overloaded function add. * Move get_non_overloaded_instance to function_base. Update in v2: * Add get_non_overloaded_instance for function instance. * Fix overload check for policy function. * Enrich the test cases check. Original log: This patch would like add the framework to support the RVV overloaded intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did. However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN with below steps. * Register overloaded functions. * Add function_resolver for overloaded function resolving. * Add resolve API for function shape with default implementation. * Implement HOOK for navigating the overloaded API to non-overloaded API. We validated this framework by the vmv_v intrinsic API(s), and we will add more intrins API support in the underlying patches. gcc/ChangeLog: * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook. (riscv_register_pragmas): Register the hook * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl. * config/riscv/riscv-vector-builtins-shapes.cc (build_one): Register overloaded function. (struct overloaded_base): New struct for overloaded shape. (struct non_overloaded_base): New struct for non overloaded shape. (struct move_def): Inherit overloaded shape. * config/riscv/riscv-vector-builtins.cc (function_base::get_non_overloaded_instance): New API impl. (function_builder::add_function): Add overloaded arg. (function_resolver::function_resolver): New constructor. (function_builder::add_overloaded_function): New API impl. (function_resolver::resolve): Ditto. (function_resolver::lookup): Ditto. (function_resolver::get_sub_code): Ditto. (resolve_overloaded_builtin): New function impl. * config/riscv/riscv-vector-builtins.h: (class function_resolver): New class. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/overloaded_rv32_vmv_v.c: New test. * gcc.target/riscv/rvv/base/overloaded_rv64_vmv_v.c: New test. * gcc.target/riscv/rvv/base/overloaded_vmv_v.h: New test. Signed-off-by: Pan Li --- gcc/config/riscv/riscv-c.cc | 36 gcc/config/riscv/riscv-protos.h | 1 + .../riscv/riscv-vector-builtins-shapes.cc | 20 ++- gcc/config/riscv/riscv-vector-builtins.cc | 155 +- gcc/config/riscv/riscv-vector-builtins.h | 36 +++- .../riscv/rvv/base/overloaded_r
RE: Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
Thanks Juzhe for comments, got the point and will have a try for hashmap liked approach to get the non-overloaded later in PATCH v4. Sorry for that in the middle of something. Pan From: juzhe.zh...@rivai.ai Sent: Friday, September 15, 2023 10:21 AM To: Li, Pan2 ; gcc-patches Cc: Li, Pan2 ; Wang, Yanzhang ; kito.cheng Subject: Re: Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic More information: For PRED_TYPE_tumu, it's easy to analyze, just need to count how many arguments in the arglist. If arglist has 5 arguments (mask, merge, op1, op2, len) Then it must be TUMU. What I mean is that we should be able to quickly to compute the arguments of the construction of the function_instance. Then we can get the non-overloaeded function. juzhe.zh...@rivai.ai<mailto:juzhe.zh...@rivai.ai> From: juzhe.zh...@rivai.ai<mailto:juzhe.zh...@rivai.ai> Date: 2023-09-15 10:02 To: pan2.li<mailto:pan2...@intel.com>; gcc-patches<mailto:gcc-patches@gcc.gnu.org> CC: pan2.li<mailto:pan2...@intel.com>; yanzhang.wang<mailto:yanzhang.w...@intel.com>; kito.cheng<mailto:kito.ch...@gmail.com> Subject: Re: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic Sorry for comment again. I am not happy with current get_non_overloaeded_instance function. I think the searching approach is very in-effective: +function_instance * +function_base::get_non_overloaded_instance (unsigned int code, + vec &arglist) const +{ + unsigned int code_limit = vec_safe_length (registered_functions); + + for (unsigned fun_code = code; fun_code < code_limit; fun_code++) +{ + registered_function *rfun = (*registered_functions)[fun_code]; + function_instance instance = rfun->instance; + + if (rfun->overloaded_p) + continue; + + unsigned k; + const rvv_arg_type_info *args = instance.op_info->args; + + for (k = 0; args[k].base_type != NUM_BASE_TYPES; k++) + { + if (k >= arglist.length ()) + break; + + if (TYPE_MODE (instance.get_arg_type (k)) + != TYPE_MODE (TREE_TYPE (arglist[k]))) + break; + } + + if (args[k].base_type == NUM_BASE_TYPES) + return &rfun->instance; +} + + return NULL; +} Instead, I think we should build up a table which map non-overloaded function according to the arguments so that we could get the "instance" effectively. E.g. For vint8mf8_t tumu vadd intrinsic the instance is like this: function_instance ("vadd", bases::vadd, shapes::alu, iu_ops[VECTOR_TYPE_vuint8mf8_t], PRED_TYPE_tumu, &iu_vvv_ops); Since the get_nonoverloaed_instance is already the function of the class BASE. So, The first 3 arguments "vadd", bases::vadd, shapes::alu should already known since it is a known function_base. The last 3 arguments may need some elegant analysis or map table to quickly grep. So, I think we should consider this framework seriously. juzhe.zh...@rivai.ai<mailto:juzhe.zh...@rivai.ai> From: pan2.li<mailto:pan2...@intel.com> Date: 2023-09-12 16:46 To: gcc-patches<mailto:gcc-patches@gcc.gnu.org> CC: juzhe.zhong<mailto:juzhe.zh...@rivai.ai>; pan2.li<mailto:pan2...@intel.com>; yanzhang.wang<mailto:yanzhang.w...@intel.com>; kito.cheng<mailto:kito.ch...@gmail.com> Subject: [PATCH v3] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic From: Pan Li mailto:pan2...@intel.com>> Update in v3: * Rewrite comment for overloaded function add. * Move get_non_overloaded_instance to function_base. Update in v2: * Add get_non_overloaded_instance for function instance. * Fix overload check for policy function. * Enrich the test cases check. Original log: This patch would like add the framework to support the RVV overloaded intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did. However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN with below steps. * Register overloaded functions. * Add function_resolver for overloaded function resolving. * Add resolve API for function shape with default implementation. * Implement HOOK for navigating the overloaded API to non-overloaded API. We validated this framework by the vmv_v intrinsic API(s), and we will add more intrins API support in the underlying patches. gcc/ChangeLog: * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook. (riscv_register_pragmas): Register the hook * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl. * config/riscv/riscv-vector-builtins-shapes.cc (build_one): Register overloaded function. (struct overloaded_base): New struct for overloaded shape. (struct non_overloaded_base): New struct for non overloaded shape. (struct move_def): Inherit overloaded shape. * config/riscv/riscv-vector-builtins.cc (function_base::get_non_overloade