forked from OSchip/llvm-project
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 llvm-svn: 285895
This commit is contained in:
parent
3aa330f98a
commit
db68845485
|
@ -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::readSortKind() {
|
|||
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::readInputSectionsList() {
|
|||
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");
|
||||
}
|
||||
|
|
|
@ -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 : BaseCommand {
|
|||
// 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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -25,6 +25,18 @@ std::vector<uint8_t> parseHex(StringRef S);
|
|||
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.
|
||||
|
|
Loading…
Reference in New Issue