[lld] r277780 - Split InputSectionDescription::Sort into SortInner and SortOuter.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 4 15:27:01 PDT 2016
Author: ruiu
Date: Thu Aug 4 17:27:00 2016
New Revision: 277780
URL: http://llvm.org/viewvc/llvm-project?rev=277780&view=rev
Log:
Split InputSectionDescription::Sort into SortInner and SortOuter.
Summary:
The comparator function to compare input sections as instructed by
SORT command was a bit too complicated because it needed to handle
four different cases. This patch split it into two function calls.
This patch also simplifies the parser.
Reviewers: grimar
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D23140
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=277780&r1=277779&r2=277780&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Aug 4 17:27:00 2016
@@ -135,27 +135,27 @@ static void addSection(OutputSectionFact
Sec->addSection(C);
}
-template <class ELFT> struct SectionsSorter {
- SectionsSorter(SortKind Kind) : Kind(Kind) {}
- bool operator()(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
- int AlignmentCmp = A->Alignment - B->Alignment;
- if (Kind == SortKind::Align || (Kind == SortKind::AlignName && AlignmentCmp != 0))
- return AlignmentCmp > 0;
-
- int NameCmp = A->getSectionName().compare(B->getSectionName());
- if (Kind == SortKind::Name || (Kind == SortKind::NameAlign && NameCmp != 0))
- return NameCmp < 0;
-
- if (Kind == SortKind::NameAlign)
- return AlignmentCmp > 0;
- if (Kind == SortKind::AlignName)
- return NameCmp < 0;
+template <class ELFT>
+static bool compareName(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
+ return A->getSectionName() < B->getSectionName();
+}
- llvm_unreachable("unknown section sort kind in predicate");
- return false;
- }
- SortKind Kind;
-};
+template <class ELFT>
+static bool compareAlignment(InputSectionBase<ELFT> *A,
+ InputSectionBase<ELFT> *B) {
+ // ">" is not a mistake. Larger alignments are placed before smaller
+ // alignments in order to reduce the amount of padding necessary.
+ // This is compatible with GNU.
+ return A->Alignment > B->Alignment;
+}
+
+template <class ELFT>
+static std::function<bool(InputSectionBase<ELFT> *, InputSectionBase<ELFT> *)>
+getComparator(SortKind K) {
+ if (K == SortByName)
+ return compareName<ELFT>;
+ return compareAlignment<ELFT>;
+}
template <class ELFT>
void LinkerScript<ELFT>::createSections(
@@ -173,9 +173,12 @@ void LinkerScript<ELFT>::createSections(
continue;
}
- if (Cmd->Sort != SortKind::None)
+ if (Cmd->SortInner)
std::stable_sort(Sections.begin(), Sections.end(),
- SectionsSorter<ELFT>(Cmd->Sort));
+ getComparator<ELFT>(Cmd->SortInner));
+ if (Cmd->SortOuter)
+ std::stable_sort(Sections.begin(), Sections.end(),
+ getComparator<ELFT>(Cmd->SortOuter));
for (InputSectionBase<ELFT> *S : Sections)
addSection(Factory, *OutputSections, S, OutputName);
@@ -489,6 +492,7 @@ private:
std::vector<StringRef> readInputFilePatterns();
InputSectionDescription *readInputSectionRules();
unsigned readPhdrType();
+ SortKind readSortKind();
SymbolAssignment *readProvide(bool Hidden);
Expr readAlign();
void readSort();
@@ -731,41 +735,36 @@ std::vector<StringRef> ScriptParser::rea
return V;
}
+SortKind ScriptParser::readSortKind() {
+ if (skip("SORT") || skip("SORT_BY_NAME"))
+ return SortByName;
+ if (skip("SORT_BY_ALIGNMENT"))
+ return SortByAlignment;
+ return SortNone;
+}
+
InputSectionDescription *ScriptParser::readInputSectionRules() {
auto *Cmd = new InputSectionDescription;
Cmd->FilePattern = next();
expect("(");
+ // Read EXCLUDE_FILE().
if (skip("EXCLUDE_FILE")) {
expect("(");
while (!Error && !skip(")"))
Cmd->ExcludedFiles.push_back(next());
}
- if (skip("SORT") || skip("SORT_BY_NAME")) {
- expect("(");
- if (skip("SORT_BY_ALIGNMENT")) {
- Cmd->Sort = SortKind::NameAlign;
- expect("(");
- Cmd->SectionPatterns = readInputFilePatterns();
- expect(")");
- } else {
- Cmd->Sort = SortKind::Name;
- Cmd->SectionPatterns = readInputFilePatterns();
- }
- expect(")");
- return Cmd;
- }
-
- if (skip("SORT_BY_ALIGNMENT")) {
+ // Read SORT().
+ if (SortKind K1 = readSortKind()) {
+ Cmd->SortOuter = K1;
expect("(");
- if (skip("SORT") || skip("SORT_BY_NAME")) {
- Cmd->Sort = SortKind::AlignName;
+ if (SortKind K2 = readSortKind()) {
+ Cmd->SortInner = K2;
expect("(");
Cmd->SectionPatterns = readInputFilePatterns();
expect(")");
} else {
- Cmd->Sort = SortKind::Align;
Cmd->SectionPatterns = readInputFilePatterns();
}
expect(")");
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=277780&r1=277779&r2=277780&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Thu Aug 4 17:27:00 2016
@@ -88,13 +88,14 @@ struct OutputSectionCommand : BaseComman
ConstraintKind Constraint = ConstraintKind::NoConstraint;
};
-enum class SortKind { None, Name, Align, NameAlign, AlignName };
+enum SortKind { SortNone, SortByName, SortByAlignment };
struct InputSectionDescription : BaseCommand {
InputSectionDescription() : BaseCommand(InputSectionKind) {}
static bool classof(const BaseCommand *C);
StringRef FilePattern;
- SortKind Sort = SortKind::None;
+ SortKind SortOuter = SortNone;
+ SortKind SortInner = SortNone;
std::vector<StringRef> ExcludedFiles;
std::vector<StringRef> SectionPatterns;
};
More information about the llvm-commits
mailing list