aboutsummaryrefslogtreecommitdiff
path: root/gcc/common
diff options
context:
space:
mode:
authorChristoph Müllner <christoph.muellner@vrull.eu>2024-06-22 21:59:04 +0200
committerChristoph Müllner <christoph.muellner@vrull.eu>2024-07-15 19:06:12 +0200
commitaa8e2de78cae4dca7f9b0efe0685f3382f9ecb9a (patch)
tree6698ceeeddc5c41d2f17631c268bb241808d5c35 /gcc/common
parent5040c273484d7123a40a99cdeb434cecbd17a2e9 (diff)
downloadgcc-aa8e2de78cae4dca7f9b0efe0685f3382f9ecb9a.zip
gcc-aa8e2de78cae4dca7f9b0efe0685f3382f9ecb9a.tar.gz
gcc-aa8e2de78cae4dca7f9b0efe0685f3382f9ecb9a.tar.bz2
RISC-V: Rewrite target attribute handling
The target-arch attribute handling in RISC-V is only a few months old, but already saw a rewrite (9941f0295a14), which addressed an important issue. This rewrite introduced a hash table in the backend, which is used to keep track of target-arch attributes of all functions. The index of this hash table is the pointer to the function declaration object (fndecl). However, objects like these don't have the lifetime that is assumed here, which resulted in observing two fndecl objects with the same address for different objects (triggering the assertion in riscv_func_target_put() -- see also PR115562). This patch removes the hash table approach in favor of storing target specific options using the DECL_FUNCTION_SPECIFIC_TARGET() macro, which is also used by other backends and is specifically designed for this purpose (https://gcc.gnu.org/onlinedocs/gccint/Function-Properties.html). To have an accessible field in the target options, we need to adjust riscv.opt and introduce the field riscv_arch_string (for the already existing option '-march='). Using this macro allows to remove much code from riscv-common.cc, which controls access to the objects 'func_target_table' and 'current_subset_list'. One thing to mention is, that we had two subset lists: current_subset_list and cmdline_subset_list, with the latter being introduced recently for target attribute handling. This patch reduces them back to one (cmdline_subset_list) which contains the list of extensions that have been enabled by the command line arguments. Note that the patch keeps the existing behavior of rejecting duplications of extensions when added via the '+' operator in a function target attribute. E.g. "-march=rv64gc_zbb" and "arch=+zbb" will trigger an error (see pr115554.c). However, at the same time this patch breaks the acceptance of adding implied extensions, which causes the following six regressions (with the error "extension 'EXT' appear more than one time"): * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-39.c * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-42.c * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-43.c * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-44.c * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-45.c * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-46.c New tests were added to document the behavior and to ensure it won't regress. This patch did not show any regressions for rv32/rv64 and fixes the ICEs from PR115554 and PR115562. PR target/115554 PR target/115562 gcc/ChangeLog: * common/config/riscv/riscv-common.cc (struct riscv_func_target_info): Remove. (struct riscv_func_target_hasher): Likewise. (riscv_func_decl_hash): Likewise. (riscv_func_target_hasher::hash): Likewise. (riscv_func_target_hasher::equal): Likewise. (riscv_current_subset_list): Likewise. (riscv_cmdline_subset_list): Remove obsolete space. (riscv_func_target_table_lazy_init): Remove. (riscv_func_target_get): Likewise. (riscv_func_target_put): Likewise. (riscv_func_target_remove_and_destory): Likewise. (riscv_arch_str): Generate from cmdline_subset_list. (riscv_set_arch_by_subset_list): Don't set current_subset_list. (riscv_parse_arch_string): Remove current_subset_list. * config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Get subset list via riscv_cmdline_subset_list(). * config/riscv/riscv-subset.h (riscv_current_subset_list): Remove prototype. (riscv_func_target_get): Likewise. (riscv_func_target_put): Likewise. (riscv_func_target_remove_and_destory): Likewise. * config/riscv/riscv-target-attr.cc (riscv_target_attr_parser::parse_arch): Build base arch string from existing target options, if any. (riscv_target_attr_parser::update_settings): Store new arch string in target options. (riscv_process_one_target_attr): Whitespace fix. (riscv_process_target_attr): Drop opts argument. (riscv_option_valid_attribute_p): Properly save, change and restore target options. * config/riscv/riscv.cc (get_arch_str): New function. (riscv_declare_function_name): Get arch string for option-arch directive from function's target options. * config/riscv/riscv.opt: Add riscv_arch_string variable to march option. gcc/testsuite/ChangeLog: * gcc.target/riscv/target-attr-01.c: Add test for option-arch directive. * gcc.target/riscv/target-attr-02.c: Likewise. * gcc.target/riscv/target-attr-03.c: Likewise. * gcc.target/riscv/target-attr-04.c: Likewise. * gcc.target/riscv/target-attr-05.c: Fix formatting. * gcc.target/riscv/target-attr-06.c: Likewise. * gcc.target/riscv/target-attr-07.c: Likewise. * gcc.target/riscv/pr115554.c: New test. * gcc.target/riscv/pr115562.c: New test. * gcc.target/riscv/target-attr-08.c: New test. * gcc.target/riscv/target-attr-09.c: New test. * gcc.target/riscv/target-attr-10.c: New test. * gcc.target/riscv/target-attr-11.c: New test. * gcc.target/riscv/target-attr-12.c: New test. * gcc.target/riscv/target-attr-13.c: New test. * gcc.target/riscv/target-attr-14.c: New test. * gcc.target/riscv/target-attr-15.c: New test. Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Diffstat (limited to 'gcc/common')
-rw-r--r--gcc/common/config/riscv/riscv-common.cc113
1 files changed, 4 insertions, 109 deletions
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index d883efa..8e9beb6 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -462,110 +462,13 @@ static const char *riscv_supported_std_ext (void);
bool riscv_subset_list::parse_failed = false;
-static riscv_subset_list *current_subset_list = NULL;
-
static riscv_subset_list *cmdline_subset_list = NULL;
-struct riscv_func_target_info
-{
- tree fn_decl;
- std::string fn_target_name;
-
- riscv_func_target_info (const tree &decl, const std::string &target_name)
- : fn_decl (decl), fn_target_name (target_name)
- {
- }
-};
-
-struct riscv_func_target_hasher : nofree_ptr_hash<struct riscv_func_target_info>
-{
- typedef tree compare_type;
-
- static hashval_t hash (value_type);
- static bool equal (value_type, const compare_type &);
-};
-
-static hash_table<riscv_func_target_hasher> *func_target_table = NULL;
-
-static inline hashval_t riscv_func_decl_hash (tree fn_decl)
-{
- inchash::hash h;
-
- h.add_ptr (fn_decl);
-
- return h.end ();
-}
-
-inline hashval_t
-riscv_func_target_hasher::hash (value_type value)
-{
- return riscv_func_decl_hash (value->fn_decl);
-}
-
-inline bool
-riscv_func_target_hasher::equal (value_type value, const compare_type &key)
-{
- return value->fn_decl == key;
-}
-
-const riscv_subset_list *riscv_current_subset_list ()
-{
- return current_subset_list;
-}
-
-const riscv_subset_list * riscv_cmdline_subset_list ()
+const riscv_subset_list *riscv_cmdline_subset_list ()
{
return cmdline_subset_list;
}
-static inline void riscv_func_target_table_lazy_init ()
-{
- if (func_target_table != NULL)
- return;
-
- func_target_table = new hash_table<riscv_func_target_hasher> (1023);
-}
-
-std::string * riscv_func_target_get (tree fn_decl)
-{
- riscv_func_target_table_lazy_init ();
-
- hashval_t hash = riscv_func_decl_hash (fn_decl);
- struct riscv_func_target_info *info
- = func_target_table->find_with_hash (fn_decl, hash);
-
- return info == NULL ? NULL : &info->fn_target_name;
-}
-
-void riscv_func_target_put (tree fn_decl, std::string fn_target_name)
-{
- riscv_func_target_table_lazy_init ();
-
- hashval_t hash = riscv_func_decl_hash (fn_decl);
- struct riscv_func_target_info **target_info_slot
- = func_target_table->find_slot_with_hash (fn_decl, hash, INSERT);
-
- gcc_assert (!*target_info_slot);
-
- struct riscv_func_target_info *info
- = new riscv_func_target_info (fn_decl, fn_target_name);
-
- *target_info_slot = info;
-}
-
-void riscv_func_target_remove_and_destory (tree fn_decl)
-{
- hashval_t hash = riscv_func_decl_hash (fn_decl);
- struct riscv_func_target_info *info
- = func_target_table->find_with_hash (fn_decl, hash);
-
- if (info)
- {
- func_target_table->remove_elt_with_hash (fn_decl, hash);
- delete info;
- }
-}
-
/* struct for recording multi-lib info. */
struct riscv_multi_lib_info_t {
std::string path;
@@ -1644,8 +1547,8 @@ riscv_subset_list::finalize ()
std::string
riscv_arch_str (bool version_p)
{
- if (current_subset_list)
- return current_subset_list->to_string (version_p);
+ if (cmdline_subset_list)
+ return cmdline_subset_list->to_string (version_p);
else
return std::string();
}
@@ -1833,8 +1736,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
{NULL, NULL, 0}
};
-/* Apply SUBSET_LIST to OPTS if OPTS is not null, also set CURRENT_SUBSET_LIST
- to SUBSET_LIST, just note this WON'T delete old CURRENT_SUBSET_LIST. */
+/* Apply SUBSET_LIST to OPTS if OPTS is not null. */
void
riscv_set_arch_by_subset_list (riscv_subset_list *subset_list,
@@ -1861,8 +1763,6 @@ riscv_set_arch_by_subset_list (riscv_subset_list *subset_list,
opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask;
}
}
-
- current_subset_list = subset_list;
}
/* Parse a RISC-V ISA string into an option mask. Must clear or set all arch
@@ -1878,15 +1778,10 @@ riscv_parse_arch_string (const char *isa,
if (!subset_list)
return;
- /* Avoid double delete if current_subset_list equals cmdline_subset_list. */
- if (current_subset_list && current_subset_list != cmdline_subset_list)
- delete current_subset_list;
-
if (cmdline_subset_list)
delete cmdline_subset_list;
cmdline_subset_list = subset_list;
- /* current_subset_list is set in the call below. */
riscv_set_arch_by_subset_list (subset_list, opts);
}