[lld] r194129 - [PECOFF] Do not add the same library to the input graph more than once.

Rui Ueyama ruiu at google.com
Tue Nov 5 21:13:21 PST 2013


Author: ruiu
Date: Tue Nov  5 23:13:20 2013
New Revision: 194129

URL: http://llvm.org/viewvc/llvm-project?rev=194129&view=rev
Log:
[PECOFF] Do not add the same library to the input graph more than once.

/defaultlib options can be specified implicitly via the .drectve section, and
it's pretty common that multiple object files add the same library, such as
user32.lib, to the input. We shouldn't add the same library multiple times.

Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=194129&r1=194128&r2=194129&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Tue Nov  5 23:13:20 2013
@@ -194,6 +194,11 @@ public:
     return _noDefaultLibs;
   }
 
+  void addDefaultLib(StringRef path) { _defaultLibs.insert(path); }
+  bool hasDefaultLib(StringRef path) const {
+    return _defaultLibs.count(path) == 1;
+  }
+
   void setNoDefaultLibAll(bool val) { _noDefaultLibAll = val; }
   bool getNoDefaultLibAll() const { return _noDefaultLibAll; }
 
@@ -256,6 +261,11 @@ private:
   // The set to store /nodefaultlib arguments.
   std::set<std::string> _noDefaultLibs;
 
+  // A set containing all the library files specified by /defaultlib. This is to
+  // keep track what files are already added to the input graph, in order to
+  // prevent adding the same file more than once to the input graph.
+  std::set<std::string> _defaultLibs;
+
   std::vector<StringRef> _inputSearchPaths;
   std::unique_ptr<Reader> _reader;
   std::unique_ptr<Writer> _writer;

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=194129&r1=194128&r2=194129&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Tue Nov  5 23:13:20 2013
@@ -827,14 +827,18 @@ WinLinkDriver::parse(int argc, const cha
           std::unique_ptr<InputElement>(new PECOFFFileNode(ctx, value)));
   }
 
-  // Add the libraries specified by /defaultlib unless they are blacklisted by
-  // /nodefaultlib.
-  if (!ctx.getNoDefaultLibAll())
-    for (const StringRef defaultLibPath : defaultLibs)
-      if (ctx.getNoDefaultLibs().find(defaultLibPath) ==
-          ctx.getNoDefaultLibs().end())
+  // Add the libraries specified by /defaultlib unless they are already added
+  // nor blacklisted by /nodefaultlib.
+  if (!ctx.getNoDefaultLibAll()) {
+    for (const StringRef path : defaultLibs) {
+      if (ctx.getNoDefaultLibs().find(path) == ctx.getNoDefaultLibs().end() &&
+	  !ctx.hasDefaultLib(path)) {
         inputElements.push_back(std::unique_ptr<InputElement>(
-            new PECOFFLibraryNode(ctx, defaultLibPath)));
+            new PECOFFLibraryNode(ctx, path)));
+	ctx.addDefaultLib(path);
+      }
+    }
+  }
 
   if (inputElements.size() == 0 && !isReadingDirectiveSection) {
     diagnostics << "No input files\n";

Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=194129&r1=194128&r2=194129&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Tue Nov  5 23:13:20 2013
@@ -259,6 +259,14 @@ TEST_F(WinLinkParserTest, DefaultLib) {
   EXPECT_EQ("kernel32.lib", inputFile(2));
 }
 
+TEST_F(WinLinkParserTest, DefaultLibDuplicates) {
+  EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib",
+                    "/defaultlib:user32.lib", "a.obj", nullptr));
+  EXPECT_EQ(2, inputFileCount());
+  EXPECT_EQ("a.obj", inputFile(0));
+  EXPECT_EQ("user32.lib", inputFile(1));
+}
+
 TEST_F(WinLinkParserTest, NoDefaultLib) {
   EXPECT_TRUE(parse("link.exe", "/defaultlib:user32.lib",
                     "/defaultlib:kernel32", "/nodefaultlib:user32.lib", "a.obj",





More information about the llvm-commits mailing list