[lld] r285895 - Use globMatch() instead of llvm::regex in linker scripts

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 3 03:54:59 PDT 2016


Author: evgeny777
Date: Thu Nov  3 05:54:58 2016
New Revision: 285895

URL: http://llvm.org/viewvc/llvm-project?rev=285895&view=rev
Log:
Use globMatch() instead of llvm::regex in linker scripts

This can speed up lld up to 5 times when linking applications 
with large number of sections and using linker script.

Differential revision: https://reviews.llvm.org/D26241

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/Strings.cpp
    lld/trunk/ELF/Strings.h

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=285895&r1=285894&r2=285895&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Nov  3 05:54:58 2016
@@ -936,7 +936,7 @@ private:
   std::vector<uint8_t> readOutputSectionFiller(StringRef Tok);
   std::vector<StringRef> readOutputSectionPhdrs();
   InputSectionDescription *readInputSectionDescription(StringRef Tok);
-  Regex readFilePatterns();
+  StringMatcher readFilePatterns();
   std::vector<SectionPattern> readInputSectionsList();
   InputSectionDescription *readInputSectionRules(StringRef FilePattern);
   unsigned readPhdrType();
@@ -1207,11 +1207,11 @@ static int precedence(StringRef Op) {
       .Default(-1);
 }
 
-Regex ScriptParser::readFilePatterns() {
+StringMatcher ScriptParser::readFilePatterns() {
   std::vector<StringRef> V;
   while (!Error && !consume(")"))
     V.push_back(next());
-  return compileGlobPatterns(V);
+  return StringMatcher(std::move(V));
 }
 
 SortSectionPolicy ScriptParser::readSortKind() {
@@ -1236,7 +1236,7 @@ SortSectionPolicy ScriptParser::readSort
 std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
   std::vector<SectionPattern> Ret;
   while (!Error && peek() != ")") {
-    Regex ExcludeFileRe;
+    StringMatcher ExcludeFileRe;
     if (consume("EXCLUDE_FILE")) {
       expect("(");
       ExcludeFileRe = readFilePatterns();
@@ -1247,7 +1247,7 @@ std::vector<SectionPattern> ScriptParser
       V.push_back(next());
 
     if (!V.empty())
-      Ret.push_back({std::move(ExcludeFileRe), compileGlobPatterns(V)});
+      Ret.push_back({std::move(ExcludeFileRe), StringMatcher(std::move(V))});
     else
       setError("section pattern is expected");
   }

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=285895&r1=285894&r2=285895&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Thu Nov  3 05:54:58 2016
@@ -19,7 +19,6 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Regex.h"
 #include <functional>
 
 namespace lld {
@@ -115,9 +114,9 @@ struct OutputSectionCommand : BaseComman
 // It can optionally have negative match pattern for EXCLUDED_FILE command.
 // Also it may be surrounded with SORT() command, so contains sorting rules.
 struct SectionPattern {
-  SectionPattern(llvm::Regex &&Re1, llvm::Regex &&Re2)
-      : ExcludedFileRe(std::forward<llvm::Regex>(Re1)),
-        SectionRe(std::forward<llvm::Regex>(Re2)) {}
+  SectionPattern(StringMatcher &&Re1, StringMatcher &&Re2)
+      : ExcludedFileRe(std::forward<StringMatcher>(Re1)),
+        SectionRe(std::forward<StringMatcher>(Re2)) {}
 
   SectionPattern(SectionPattern &&Other) {
     std::swap(ExcludedFileRe, Other.ExcludedFileRe);
@@ -126,18 +125,17 @@ struct SectionPattern {
     std::swap(SortInner, Other.SortInner);
   }
 
-  llvm::Regex ExcludedFileRe;
-  llvm::Regex SectionRe;
+  StringMatcher ExcludedFileRe;
+  StringMatcher SectionRe;
   SortSectionPolicy SortOuter;
   SortSectionPolicy SortInner;
 };
 
 struct InputSectionDescription : BaseCommand {
   InputSectionDescription(StringRef FilePattern)
-      : BaseCommand(InputSectionKind),
-        FileRe(compileGlobPatterns({FilePattern})) {}
+      : BaseCommand(InputSectionKind), FileRe(FilePattern) {}
   static bool classof(const BaseCommand *C);
-  llvm::Regex FileRe;
+  StringMatcher FileRe;
 
   // Input sections that matches at least one of SectionPatterns
   // will be associated with this InputSectionDescription.

Modified: lld/trunk/ELF/Strings.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Strings.cpp?rev=285895&r1=285894&r2=285895&view=diff
==============================================================================
--- lld/trunk/ELF/Strings.cpp (original)
+++ lld/trunk/ELF/Strings.cpp Thu Nov  3 05:54:58 2016
@@ -21,6 +21,36 @@ using namespace llvm;
 using namespace lld;
 using namespace lld::elf;
 
+// Returns true if S matches T. S can contain glob meta-characters.
+// The asterisk ('*') matches zero or more characters, and the question
+// mark ('?') matches one character.
+static bool globMatch(StringRef S, StringRef T) {
+  for (;;) {
+    if (S.empty())
+      return T.empty();
+    if (S[0] == '*') {
+      S = S.substr(1);
+      if (S.empty())
+        // Fast path. If a pattern is '*', it matches anything.
+        return true;
+      for (size_t I = 0, E = T.size(); I < E; ++I)
+        if (globMatch(S, T.substr(I)))
+          return true;
+      return false;
+    }
+    if (T.empty() || (S[0] != T[0] && S[0] != '?'))
+      return false;
+    S = S.substr(1);
+    T = T.substr(1);
+  }
+}
+
+bool StringMatcher::match(StringRef S) {
+  for (StringRef P : Patterns)
+    if (globMatch(P, S))
+      return true;
+  return false;
+}
 // If an input string is in the form of "foo.N" where N is a number,
 // return N. Otherwise, returns 65536, which is one greater than the
 // lowest priority.

Modified: lld/trunk/ELF/Strings.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Strings.h?rev=285895&r1=285894&r2=285895&view=diff
==============================================================================
--- lld/trunk/ELF/Strings.h (original)
+++ lld/trunk/ELF/Strings.h Thu Nov  3 05:54:58 2016
@@ -25,6 +25,18 @@ std::vector<uint8_t> parseHex(StringRef
 bool isValidCIdentifier(StringRef S);
 StringRef unquote(StringRef S);
 
+class StringMatcher {
+public:
+  StringMatcher() = default;
+  explicit StringMatcher(StringRef P) : Patterns({P}) {}
+  explicit StringMatcher(std::vector<StringRef> &&Pat)
+      : Patterns(std::move(Pat)) {}
+
+  bool match(StringRef S);
+private:
+  std::vector<StringRef> Patterns;
+};
+
 // Returns a demangled C++ symbol name. If Name is not a mangled
 // name or the system does not provide __cxa_demangle function,
 // it returns an unmodified string.




More information about the llvm-commits mailing list