Consolidate implied-extension logic by removing the old `riscv_implied_info`
array and using the `implied_exts` field in the unified riscv_ext_info_t
structures generated from `riscv-ext.def`.

gcc/ChangeLog:

        * common/config/riscv/riscv-common.cc
        (riscv_implied_info::riscv_implied_info_t): Remove unused
        variant.
        (struct riscv_implied_info_t): Remove unsued field.
        (riscv_implied_info::match): Remove unused variant, and adjust
        the logic.
        (get_riscv_ext_info): New.
        (riscv_implied_info): Remove.
        (riscv_ext_info_t::apply_implied_ext): New.
        (riscv_combine_info). Remove.
        (riscv_subset_list::handle_implied_ext): Use riscv_ext_info_t
        rather than riscv_implied_info.
        (riscv_subset_list::check_implied_ext): Ditto.
        (riscv_subset_list::handle_combine_ext): Use riscv_ext_info_t
        rather than riscv_combine_info.
        (riscv_minimal_hwprobe_feature_bits): Use riscv_ext_info_t
        rather than riscv_implied_info.
---
 gcc/common/config/riscv/riscv-common.cc | 342 +++++-------------------
 1 file changed, 65 insertions(+), 277 deletions(-)

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 72d5d8181d16..faec954e0c15 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -95,32 +95,17 @@ struct riscv_implied_info_t
   constexpr riscv_implied_info_t (const char *implied_ext,
                                  riscv_implied_predicator_t predicator
                                  = nullptr)
-    : ext (nullptr), implied_ext (implied_ext), predicator (predicator)
+    : implied_ext (implied_ext), predicator (predicator)
   {}
 
-  constexpr riscv_implied_info_t (const char *ext, const char *implied_ext,
-                                 riscv_implied_predicator_t predicator
-                                 = nullptr)
-    : ext (ext), implied_ext (implied_ext), predicator (predicator){};
-
-  bool match (const riscv_subset_list *subset_list, const char *ext_name) const
+  bool match (const riscv_subset_list *subset_list) const
   {
-    if (ext_name && strcmp (ext_name, ext) != 0)
-      return false;
-
     if (predicator && !predicator (subset_list))
       return false;
 
     return true;
   }
 
-  bool match (const riscv_subset_list *subset_list,
-             const riscv_subset_t *subset) const
-  {
-    return match (subset_list, subset->name.c_str());
-  }
-
-  const char *ext;
   const char *implied_ext;
   riscv_implied_predicator_t predicator;
 };
@@ -230,196 +215,43 @@ static const std::unordered_map<std::string, 
riscv_ext_info_t> riscv_ext_infos
 #undef DEFINE_RISCV_EXT
 };
 
-/* Implied ISA info, must end with NULL sentinel.  */
-static const riscv_implied_info_t riscv_implied_info[] =
+static const riscv_ext_info_t &
+get_riscv_ext_info (const std::string &ext)
 {
-  {"m", "zmmul"},
-
-  {"d", "f"},
-  {"f", "zicsr"},
-  {"d", "zicsr"},
-
-  {"a", "zaamo"},
-  {"a", "zalrsc"},
-
-  {"c", "zca"},
-  {"c", "zcf",
-   [] (const riscv_subset_list *subset_list) -> bool
-   {
-     return subset_list->xlen () == 32 && subset_list->lookup ("f");
-   }},
-  {"c", "zcd",
-   [] (const riscv_subset_list *subset_list) -> bool
-   {
-     return subset_list->lookup ("d");
-   }},
-
-  {"zabha", "zaamo"},
-  {"zacas", "zaamo"},
-  {"zawrs", "zalrsc"},
-
-  {"zcmop", "zca"},
-
-  {"b", "zba"},
-  {"b", "zbb"},
-  {"b", "zbs"},
-
-  {"zdinx", "zfinx"},
-  {"zfinx", "zicsr"},
-  {"zdinx", "zicsr"},
-
-  {"zicfiss", "zicsr"},
-  {"zicfiss", "zimop"},
-  {"zicfilp", "zicsr"},
-
-  {"zk", "zkn"},
-  {"zk", "zkr"},
-  {"zk", "zkt"},
-  {"zkn", "zbkb"},
-  {"zkn", "zbkc"},
-  {"zkn", "zbkx"},
-  {"zkn", "zkne"},
-  {"zkn", "zknd"},
-  {"zkn", "zknh"},
-  {"zks", "zbkb"},
-  {"zks", "zbkc"},
-  {"zks", "zbkx"},
-  {"zks", "zksed"},
-  {"zks", "zksh"},
-
-  {"v", "zvl128b"},
-  {"v", "zve64d"},
-
-  {"zve32f", "f"},
-  {"zve64f", "f"},
-  {"zve64d", "d"},
-
-  {"zve32x", "zicsr"},
-  {"zve32x", "zvl32b"},
-  {"zve32f", "zve32x"},
-  {"zve32f", "zvl32b"},
-
-  {"zve64x", "zve32x"},
-  {"zve64x", "zvl64b"},
-  {"zve64f", "zve32f"},
-  {"zve64f", "zve64x"},
-  {"zve64f", "zvl64b"},
-  {"zve64d", "zve64f"},
-  {"zve64d", "zvl64b"},
-
-  {"zvl64b", "zvl32b"},
-  {"zvl128b", "zvl64b"},
-  {"zvl256b", "zvl128b"},
-  {"zvl512b", "zvl256b"},
-  {"zvl1024b", "zvl512b"},
-  {"zvl2048b", "zvl1024b"},
-  {"zvl4096b", "zvl2048b"},
-  {"zvl8192b", "zvl4096b"},
-  {"zvl16384b", "zvl8192b"},
-  {"zvl32768b", "zvl16384b"},
-  {"zvl65536b", "zvl32768b"},
-
-  {"zvkn", "zvkned"},
-  {"zvkn", "zvknhb"},
-  {"zvkn", "zvkb"},
-  {"zvkn", "zvkt"},
-  {"zvknc", "zvkn"},
-  {"zvknc", "zvbc"},
-  {"zvkng", "zvkn"},
-  {"zvkng", "zvkg"},
-  {"zvks", "zvksed"},
-  {"zvks", "zvksh"},
-  {"zvks", "zvkb"},
-  {"zvks", "zvkt"},
-  {"zvksc", "zvks"},
-  {"zvksc", "zvbc"},
-  {"zvksg", "zvks"},
-  {"zvksg", "zvkg"},
-  {"zvbb",  "zvkb"},
-  {"zvbc",   "zve64x"},
-  {"zvkb",   "zve32x"},
-  {"zvkg",   "zve32x"},
-  {"zvkned", "zve32x"},
-  {"zvknha", "zve32x"},
-  {"zvknhb", "zve64x"},
-  {"zvksed", "zve32x"},
-  {"zvksh",  "zve32x"},
-
-  {"zfbfmin", "zfhmin"},
-  {"zfh", "zfhmin"},
-  {"zfhmin", "f"},
-
-  {"zfa", "f"},
-
-  {"zvfbfmin", "zve32f"},
-  {"zvfbfwma", "zvfbfmin"},
-  {"zvfbfwma", "zfbfmin"},
-  {"zvfhmin", "zve32f"},
-  {"zvfh", "zve32f"},
-  {"zvfh", "zfhmin"},
-
-  {"zhinx", "zhinxmin"},
-  {"zhinxmin", "zfinx"},
-
-  {"zce",  "zca"},
-  {"zce",  "zcb"},
-  {"zce",  "zcmp"},
-  {"zce",  "zcmt"},
-  {"zcf",  "zca"},
-  {"zcd",  "zca"},
-  {"zcb",  "zca"},
-  {"zcmp", "zca"},
-  {"zcmt", "zca"},
-  {"zcmt", "zicsr"},
-  {"zce", "zcf",
-   [] (const riscv_subset_list *subset_list) -> bool
-   {
-     return subset_list->xlen () == 32 && subset_list->lookup ("f");
-   }},
-  {"zca", "c",
-   [] (const riscv_subset_list *subset_list) -> bool
-   {
-     /* For RV32 Zca implies C for one of these combinations of
-       extensions: Zca, F_Zca_Zcf and FD_Zca_Zcf_Zcd.  */
-     if (subset_list->xlen () == 32)
-       {
-        if (subset_list->lookup ("d"))
-          return subset_list->lookup ("zcf") && subset_list->lookup ("zcd");
-
-        if (subset_list->lookup ("f"))
-          return subset_list->lookup ("zcf");
-
-        return true;
-       }
-
-     /* For RV64 Zca implies C for one of these combinations of
-       extensions: Zca and FD_Zca_Zcd (Zcf is not available
-       for RV64).  */
-     if (subset_list->xlen () == 64)
-       {
-        if (subset_list->lookup ("d"))
-          return subset_list->lookup ("zcd");
-
-        return true;
-       }
-
-     /* Do nothing for future RV128 specification. Behaviour
-       for this case is not yet well defined.  */
-     return false;
-   }},
-
-  {"smaia", "ssaia"},
-  {"smstateen", "ssstateen"},
-  {"smepmp", "zicsr"},
-  {"ssaia", "zicsr"},
-  {"sscofpmf", "zicsr"},
-  {"ssstateen", "zicsr"},
-  {"sstc", "zicsr"},
-
-  {"xsfvcp", "zve32x"},
-
-  {NULL, NULL, NULL}
-};
+  auto itr = riscv_ext_infos.find (ext);
+  if (itr == riscv_ext_infos.end ())
+    {
+      gcc_unreachable ();
+    }
+  return itr->second;
+}
+
+/* Return true if any change.  */
+bool
+riscv_ext_info_t::apply_implied_ext (riscv_subset_list *subset_list) const
+{
+  bool any_change = false;
+  for (const riscv_implied_info_t &implied_info : m_implied_exts)
+    {
+      /* Skip if implied extension already present.  */
+      if (subset_list->lookup (implied_info.implied_ext))
+       continue;
+
+      any_change = true;
+      if (!implied_info.match (subset_list))
+       continue;
+
+      /* Version of implied extension will get from current ISA spec
+        version.  */
+      subset_list->add (implied_info.implied_ext, true);
+
+      /* Recursively add implied extension by implied_info->implied_ext.  */
+      const riscv_ext_info_t &implied_ext_info
+       = get_riscv_ext_info (implied_info.implied_ext);
+      implied_ext_info.apply_implied_ext (subset_list);
+    }
+  return any_change;
+}
 
 /* This structure holds version information for specific ISA version.  */
 
@@ -641,24 +473,6 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
 };
 
-/* Combine extensions defined in this table  */
-static const struct riscv_ext_version riscv_combine_info[] =
-{
-  {"a", ISA_SPEC_CLASS_20191213, 2, 1},
-  {"b",  ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zk",  ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zkn",  ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zks",  ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zvkn", ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zvknc", ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zvkng", ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zvks", ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zvksc", ISA_SPEC_CLASS_NONE, 1, 0},
-  {"zvksg", ISA_SPEC_CLASS_NONE, 1, 0},
-  /* Terminate the list.  */
-  {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
-};
-
 static const riscv_cpu_info riscv_cpu_tables[] =
 {
 #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
@@ -1401,25 +1215,8 @@ riscv_subset_list::parse_single_std_ext (const char *p, 
bool exact_single_p)
 void
 riscv_subset_list::handle_implied_ext (const char *ext)
 {
-  const riscv_implied_info_t *implied_info;
-  for (implied_info = &riscv_implied_info[0];
-       implied_info->ext;
-       ++implied_info)
-    {
-      if (!implied_info->match (this, ext))
-       continue;
-
-      /* Skip if implied extension already present.  */
-      if (lookup (implied_info->implied_ext))
-       continue;
-
-      /* Version of implied extension will get from current ISA spec
-        version.  */
-      add (implied_info->implied_ext, true);
-
-      /* Recursively add implied extension by implied_info->implied_ext.  */
-      handle_implied_ext (implied_info->implied_ext);
-    }
+  const riscv_ext_info_t &ext_info = get_riscv_ext_info (ext);
+  ext_info.apply_implied_ext (this);
 
   /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifence is
      included in the base ISA.  */
@@ -1440,14 +1237,13 @@ riscv_subset_list::check_implied_ext ()
   riscv_subset_t *itr;
   for (itr = m_head; itr != NULL; itr = itr->next)
     {
-      const riscv_implied_info_t *implied_info;
-      for (implied_info = &riscv_implied_info[0]; implied_info->ext;
-          ++implied_info)
+      auto &ext = *itr;
+      auto &ext_info = get_riscv_ext_info (ext.name);
+      for (auto &implied_ext : ext_info.implied_exts ())
        {
-         if (!implied_info->match (this, itr))
+         if (!implied_ext.match (this))
            continue;
-
-         if (!lookup (implied_info->implied_ext))
+         if (lookup (implied_ext.implied_ext) == NULL)
            return false;
        }
     }
@@ -1458,27 +1254,23 @@ riscv_subset_list::check_implied_ext ()
 void
 riscv_subset_list::handle_combine_ext ()
 {
-  const riscv_ext_version *combine_info;
-  const riscv_implied_info_t *implied_info;
-  bool is_combined = false;
-
-  for (combine_info = &riscv_combine_info[0]; combine_info->name;
-       ++combine_info)
+  for (const auto &[ext_name, ext_info] : riscv_ext_infos)
     {
-      /* Skip if combine extensions are present */
-      if (lookup (combine_info->name))
+      bool is_combined = true;
+      /* Skip if this extension don't need to combine.  */
+      if (!ext_info.need_combine_p ())
+       continue;
+      /* Skip if combine extensions are present.  */
+      if (lookup (ext_name.c_str ()))
        continue;
 
-      /* Find all extensions of the combine extension   */
-      for (implied_info = &riscv_implied_info[0]; implied_info->ext;
-          ++implied_info)
+      /* Check all implied extensions is present.  */
+      for (const auto &implied_ext : ext_info.implied_exts ())
        {
-         if (!implied_info->match (this, combine_info->name))
+         if (!implied_ext.match (this))
            continue;
 
-         if (lookup (implied_info->implied_ext))
-           is_combined = true;
-         else
+         if (!lookup (implied_ext.implied_ext))
            {
              is_combined = false;
              break;
@@ -1488,11 +1280,9 @@ riscv_subset_list::handle_combine_ext ()
       /* Add combine extensions */
       if (is_combined)
        {
-         if (lookup (combine_info->name) == NULL)
-           {
-             add (combine_info->name, combine_info->major_version,
-                  combine_info->minor_version, false, true);
-           }
+         riscv_version_t ver = ext_info.default_version();
+         add (ext_name.c_str (), ver.major_version,
+              ver.minor_version, false, true);
        }
     }
 }
@@ -2106,20 +1896,18 @@ riscv_minimal_hwprobe_feature_bits (const char *isa,
          search_q.pop ();
 
          /* Iterate through the implied extension table.  */
-         const riscv_implied_info_t *implied_info;
-         for (implied_info = &riscv_implied_info[0];
-             implied_info->ext;
-             ++implied_info)
+         auto &ext_info = get_riscv_ext_info (search_ext);
+         for (const auto &implied_ext : ext_info.implied_exts ())
            {
              /* When the search extension matches the implied extension and
                 the implied extension has not been visited, mark the implied
                 extension in the implied_exts set and push it into the
                 queue.  */
-             if (implied_info->match (subset_list, search_ext)
-                 && implied_exts.count (implied_info->implied_ext) == 0)
+             if (implied_ext.match (subset_list)
+                 && implied_exts.count (implied_ext.implied_ext) == 0)
                {
-                 implied_exts.insert (implied_info->implied_ext);
-                 search_q.push (implied_info->implied_ext);
+                 implied_exts.insert (implied_ext.implied_ext);
+                 search_q.push (implied_ext.implied_ext);
                }
            }
        }
-- 
2.34.1

Reply via email to