[lld] 3542384 - [COFF] Use a global option table to avoid reconstructing it

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Sat May 2 15:06:13 PDT 2020


Author: Reid Kleckner
Date: 2020-05-02T15:04:19-07:00
New Revision: 3542384ae9fd43ec4594d45d22f0fe543be9ba20

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

LOG: [COFF] Use a global option table to avoid reconstructing it

Otherwise an ArgumentParser is constructed for every directive section,
and that involves copying the entire table of options into a vector.
There is no need for this, just have one option table.

Added: 
    

Modified: 
    lld/COFF/Driver.cpp
    lld/COFF/Driver.h
    lld/COFF/DriverUtils.cpp

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index c2bb0db6e6ae..0469b49b88eb 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -251,7 +251,7 @@ void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive, bool lazy) {
       // the option `/nodefaultlib` than a reference to a file in the root
       // directory.
       std::string nearest;
-      if (COFFOptTable().findNearest(pathStr, nearest) > 1)
+      if (optTable.findNearest(pathStr, nearest) > 1)
         error(msg);
       else
         error(msg + "; did you mean '" + nearest + "'");

diff  --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index 4b6d0c9dcbe3..92c0db84c384 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -41,6 +41,10 @@ class COFFOptTable : public llvm::opt::OptTable {
   COFFOptTable();
 };
 
+// Constructing the option table is expensive. Use a global table to avoid doing
+// it more than once.
+extern COFFOptTable optTable;
+
 // The result of parsing the .drective section. The /export: and /include:
 // options are handled separately because they reference symbols, and the number
 // of symbols can be quite large. The LLVM Option library will perform at least
@@ -70,8 +74,6 @@ class ArgParser {
   void addLINK(SmallVector<const char *, 256> &argv);
 
   std::vector<const char *> tokenize(StringRef s);
-
-  COFFOptTable table;
 };
 
 class LinkerDriver {

diff  --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index daaddad1239d..6cb761abea4e 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -767,6 +767,8 @@ static const llvm::opt::OptTable::Info infoTable[] = {
 
 COFFOptTable::COFFOptTable() : OptTable(infoTable, true) {}
 
+COFFOptTable optTable;
+
 // Set color diagnostics according to --color-diagnostics={auto,always,never}
 // or --no-color-diagnostics flags.
 static void handleColorDiagnostics(opt::InputArgList &args) {
@@ -812,8 +814,7 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
   // options so we parse here before and ignore all the options but
   // --rsp-quoting and /lldignoreenv.
   // (This means --rsp-quoting can't be added through %LINK%.)
-  opt::InputArgList args = table.ParseArgs(argv, missingIndex, missingCount);
-
+  opt::InputArgList args = optTable.ParseArgs(argv, missingIndex, missingCount);
 
   // Expand response files (arguments in the form of @<filename>) and insert
   // flags from %LINK% and %_LINK_%, and then parse the argument again.
@@ -822,8 +823,8 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
   if (!args.hasArg(OPT_lldignoreenv))
     addLINK(expandedArgv);
   cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv);
-  args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex,
-                         missingCount);
+  args = optTable.ParseArgs(makeArrayRef(expandedArgv).drop_front(),
+                            missingIndex, missingCount);
 
   // Print the real command line if response files are expanded.
   if (args.hasArg(OPT_verbose) && argv.size() != expandedArgv.size()) {
@@ -847,7 +848,7 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
 
   for (auto *arg : args.filtered(OPT_UNKNOWN)) {
     std::string nearest;
-    if (table.findNearest(arg->getAsString(args), nearest) > 1)
+    if (optTable.findNearest(arg->getAsString(args), nearest) > 1)
       warn("ignoring unknown argument '" + arg->getAsString(args) + "'");
     else
       warn("ignoring unknown argument '" + arg->getAsString(args) +
@@ -886,7 +887,7 @@ ParsedDirectives ArgParser::parseDirectives(StringRef s) {
   unsigned missingIndex;
   unsigned missingCount;
 
-  result.args = table.ParseArgs(rest, missingIndex, missingCount);
+  result.args = optTable.ParseArgs(rest, missingIndex, missingCount);
 
   if (missingCount)
     fatal(Twine(result.args.getArgString(missingIndex)) + ": missing argument");
@@ -917,9 +918,9 @@ std::vector<const char *> ArgParser::tokenize(StringRef s) {
 }
 
 void printHelp(const char *argv0) {
-  COFFOptTable().PrintHelp(lld::outs(),
-                           (std::string(argv0) + " [options] file...").c_str(),
-                           "LLVM Linker", false);
+  optTable.PrintHelp(lld::outs(),
+                     (std::string(argv0) + " [options] file...").c_str(),
+                     "LLVM Linker", false);
 }
 
 } // namespace coff


        


More information about the llvm-commits mailing list