In some new cases, we need to parse the features for a specific version
of the target and get the cl_target_option. This commit splits the
parse_features_for_version function to a new function that returns
the cl_target_option. The original function is kept for backward
compatibility.

Signed-off-by: Yangyu Chen <c...@cyyself.name>

gcc/ChangeLog:

        * config/riscv/riscv.cc (parse_features_for_version): Split
        parse_features_for_version with cl_target_option returned.
---
 gcc/config/riscv/riscv.cc | 60 ++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 23 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 38f3ae7cd84..65b82795541 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -13092,31 +13092,25 @@ riscv_c_mode_for_floating_type (enum tree_index ti)
   return default_mode_for_floating_type (ti);
 }
 
-/* This parses the attribute arguments to target_version in DECL and modifies
-   the feature mask and priority required to select those targets.  */
-static void
+/* This parses the attribute arguments for target_version in DECL and modifies
+   the cl_target_option &opt.  Return value indicates whether the attribute was
+   found and the arch is not default. If the attribute is not found, or the 
arch
+   is default, return false, and the res is not modified.  */
+static bool
 parse_features_for_version (tree decl,
-                           struct riscv_feature_bits &res,
-                           int &priority)
+                           struct cl_target_option &opt)
 {
   tree version_attr = lookup_attribute ("target_version",
                                        DECL_ATTRIBUTES (decl));
   if (version_attr == NULL_TREE)
-    {
-      res.length = 0;
-      priority = 0;
-      return;
-    }
+    return false;
 
   const char *version_string = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE
                                                    (version_attr)));
   gcc_assert (version_string != NULL);
   if (strcmp (version_string, "default") == 0)
-    {
-      res.length = 0;
-      priority = 0;
-      return;
-    }
+    return false;
+
   struct cl_target_option cur_target;
   cl_target_option_save (&cur_target, &global_options,
                         &global_options_set);
@@ -13128,19 +13122,39 @@ parse_features_for_version (tree decl,
 
   riscv_process_target_version_attr (TREE_VALUE (version_attr),
                                     DECL_SOURCE_LOCATION (decl));
+  /* In case of the parse error, compilation will be aborted, thus
+     we don't need to check the return value.  */
 
-  priority = global_options.x_riscv_fmv_priority;
-  const char *arch_string = global_options.x_riscv_arch_string;
+  cl_target_option_save (&opt, &global_options,
+                        &global_options_set);
+
+  cl_target_option_restore (&global_options, &global_options_set,
+                           &cur_target);
+  return true;
+}
+
+/* This parses the attribute arguments to target_version in DECL and modifies
+   the feature mask and priority required to select those targets.  */
+static void
+parse_features_for_version (tree decl,
+                           struct riscv_feature_bits &res,
+                           int &priority)
+{
+  struct cl_target_option versioned_opts;
+  bool opts_res = parse_features_for_version (decl, versioned_opts);
+  if (! opts_res)
+    {
+      res.length = 0;
+      priority = 0;
+      return;
+    }
+
+  priority = versioned_opts.x_riscv_fmv_priority;
+  const char *arch_string = versioned_opts.x_riscv_arch_string;
   bool parse_res
     = riscv_minimal_hwprobe_feature_bits (arch_string, &res,
                                          DECL_SOURCE_LOCATION (decl));
   gcc_assert (parse_res);
-
-  if (arch_string != default_opts->x_riscv_arch_string)
-    free (CONST_CAST (void *, (const void *) arch_string));
-
-  cl_target_option_restore (&global_options, &global_options_set,
-                           &cur_target);
 }
 
 /* Compare priorities of two feature masks.  Return:
-- 
2.49.0

Reply via email to