[clang] bbe463d - [OptTable] Make ValuesCode initialisation of Options constexpr

via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 12 03:08:21 PST 2023


Author: serge-sans-paille
Date: 2023-01-12T12:08:01+01:00
New Revision: bbe463d6ba268a2bfc45d539314b70cfd72d2360

URL: https://github.com/llvm/llvm-project/commit/bbe463d6ba268a2bfc45d539314b70cfd72d2360
DIFF: https://github.com/llvm/llvm-project/commit/bbe463d6ba268a2bfc45d539314b70cfd72d2360.diff

LOG: [OptTable] Make ValuesCode initialisation of Options constexpr

Current implementation requires a copy of the initialization array to a
vector to be able to modify their Values field.

This is inefficient: it requires a large copy to update a value, while
TableGen has all information to avoid this overwrite.

Modify TableGen to emit the Values code and use it to perform the
initialisation.

The impact on performance is not amazing compared to the actual
compilation, but still noticeable:

https://llvm-compile-time-tracker.com/compare.php?from=d9ab3e82f30d646deff054230b0c742704a1cf26&to=f2b37fb65d5149f70b43d1801beb5239285a2a20&stat=instructions:u

Differential Revision: https://reviews.llvm.org/D140699

Added: 
    

Modified: 
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/DriverOptions.cpp
    llvm/include/llvm/Option/OptTable.h
    llvm/lib/Option/OptTable.cpp
    llvm/utils/TableGen/OptParserEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3fcf9ddc29ea0..6cee51f72702f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4252,7 +4252,7 @@ def std_default_EQ : Joined<["-"], "std-default=">;
 def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option,FlangOption,FC1Option]>,
   Group<CompileOnly_Group>, HelpText<"Language standard to compile for">,
   ValuesCode<[{
-    const char *Values =
+    static constexpr const char VALUES_CODE [] =
     #define LANGSTANDARD(id, name, lang, desc, features) name ","
     #define LANGSTANDARD_ALIAS(id, alias) alias ","
     #include "clang/Basic/LangStandards.def"
@@ -5263,7 +5263,7 @@ def analyzer_stats : Flag<["-"], "analyzer-stats">,
 def analyzer_checker : Separate<["-"], "analyzer-checker">,
   HelpText<"Choose analyzer checkers to enable">,
   ValuesCode<[{
-    const char *Values =
+    static constexpr const char VALUES_CODE [] =
     #define GET_CHECKERS
     #define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN)  FULLNAME ","
     #include "clang/StaticAnalyzer/Checkers/Checkers.inc"

diff  --git a/clang/lib/Driver/DriverOptions.cpp b/clang/lib/Driver/DriverOptions.cpp
index 197fa0a2eb69b..0a14749bc1106 100644
--- a/clang/lib/Driver/DriverOptions.cpp
+++ b/clang/lib/Driver/DriverOptions.cpp
@@ -16,6 +16,10 @@ using namespace clang::driver;
 using namespace clang::driver::options;
 using namespace llvm::opt;
 
+#define OPTTABLE_VALUES_CODE
+#include "clang/Driver/Options.inc"
+#undef OPTTABLE_VALUES_CODE
+
 #define PREFIX(NAME, VALUE)                                                    \
   static constexpr llvm::StringLiteral NAME##_init[] = VALUE;                  \
   static constexpr llvm::ArrayRef<llvm::StringLiteral> NAME(                   \
@@ -43,16 +47,6 @@ class DriverOptTable : public OptTable {
 }
 
 const llvm::opt::OptTable &clang::driver::getDriverOptTable() {
-  static const DriverOptTable *Table = []() {
-    auto Result = std::make_unique<DriverOptTable>();
-    // Options.inc is included in DriverOptions.cpp, and calls OptTable's
-    // addValues function.
-    // Opt is a variable used in the code fragment in Options.inc.
-    OptTable &Opt = *Result;
-#define OPTTABLE_ARG_INIT
-#include "clang/Driver/Options.inc"
-#undef OPTTABLE_ARG_INIT
-    return Result.release();
-  }();
-  return *Table;
+  static DriverOptTable Table;
+  return Table;
 }

diff  --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index 52354eb954559..4933116968e66 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -60,7 +60,7 @@ class OptTable {
 
 private:
   /// The option information table.
-  std::vector<Info> OptionInfos;
+  ArrayRef<Info> OptionInfos;
   bool IgnoreCase;
   bool GroupedShortOptions = false;
   const char *EnvVar = nullptr;
@@ -174,17 +174,6 @@ class OptTable {
                        unsigned FlagsToInclude = 0, unsigned FlagsToExclude = 0,
                        unsigned MinimumLength = 4) const;
 
-  /// Add Values to Option's Values class
-  ///
-  /// \param [in] Option - Prefix + Name of the flag which Values will be
-  ///  changed. For example, "-analyzer-checker".
-  /// \param [in] Values - String of Values seperated by ",", such as
-  ///  "foo, bar..", where foo and bar is the argument which the Option flag
-  ///  takes
-  ///
-  /// \return true in success, and false in fail.
-  bool addValues(StringRef Option, const char *Values);
-
   /// Parse a single argument; returning the new argument and
   /// updating Index.
   ///

diff  --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp
index 3b4e439bdaf30..49d56c01d415b 100644
--- a/llvm/lib/Option/OptTable.cpp
+++ b/llvm/lib/Option/OptTable.cpp
@@ -300,17 +300,6 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString,
   return BestDistance;
 }
 
-bool OptTable::addValues(StringRef Option, const char *Values) {
-  for (size_t I = FirstSearchableIndex, E = OptionInfos.size(); I < E; I++) {
-    Info &In = OptionInfos[I];
-    if (optionMatches(In, Option)) {
-      In.Values = Values;
-      return true;
-    }
-  }
-  return false;
-}
-
 // Parse a single argument, return the new argument, and update Index. If
 // GroupedShortOptions is true, -a matches "-abc" and the argument in Args will
 // be updated to "-bc". This overload does not support

diff  --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp
index 8c57ddaaf96c8..b8978430abb87 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -259,6 +259,21 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
   OS << "#undef COMMA\n";
   OS << "#endif // PREFIX\n\n";
 
+  OS << "/////////\n";
+  OS << "// ValuesCode\n\n";
+  OS << "#ifdef OPTTABLE_VALUES_CODE\n";
+  for (const Record &R : llvm::make_pointee_range(Opts)) {
+    // The option values, if any;
+    if (!isa<UnsetInit>(R.getValueInit("ValuesCode"))) {
+      assert(isa<UnsetInit>(R.getValueInit("Values")) &&
+             "Cannot choose between Values and ValuesCode");
+      OS << "#define VALUES_CODE " << getOptionName(R) << "_Values\n";
+      OS << R.getValueAsString("ValuesCode") << "\n";
+      OS << "#undef VALUES_CODE\n";
+    }
+  }
+  OS << "#endif\n";
+
   OS << "/////////\n";
   OS << "// Groups\n\n";
   OS << "#ifdef OPTION\n";
@@ -388,6 +403,9 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
     OS << ", ";
     if (!isa<UnsetInit>(R.getValueInit("Values")))
       write_cstring(OS, R.getValueAsString("Values"));
+    else if (!isa<UnsetInit>(R.getValueInit("ValuesCode"))) {
+      OS << getOptionName(R) << "_Values";
+    }
     else
       OS << "nullptr";
   };
@@ -460,29 +478,5 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
   OS << "\n";
 
   OS << "\n";
-  OS << "#ifdef OPTTABLE_ARG_INIT\n";
-  OS << "//////////\n";
-  OS << "// Option Values\n\n";
-  for (const Record &R : llvm::make_pointee_range(Opts)) {
-    if (isa<UnsetInit>(R.getValueInit("ValuesCode")))
-      continue;
-    OS << "{\n";
-    OS << "bool ValuesWereAdded;\n";
-    OS << R.getValueAsString("ValuesCode");
-    OS << "\n";
-    for (StringRef Prefix : R.getValueAsListOfStrings("Prefixes")) {
-      OS << "ValuesWereAdded = Opt.addValues(";
-      std::string S(Prefix);
-      S += R.getValueAsString("Name");
-      write_cstring(OS, S);
-      OS << ", Values);\n";
-      OS << "(void)ValuesWereAdded;\n";
-      OS << "assert(ValuesWereAdded && \"Couldn't add values to "
-            "OptTable!\");\n";
-    }
-    OS << "}\n";
-  }
-  OS << "\n";
-  OS << "#endif // OPTTABLE_ARG_INIT\n";
 }
 } // end namespace llvm


        


More information about the cfe-commits mailing list