[lld] a1c2ee0 - [ELF] LinkerScript/OutputSection: change other std::vector members to SmallVector
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 26 13:53:52 PST 2021
Author: Fangrui Song
Date: 2021-12-26T13:53:47-08:00
New Revision: a1c2ee01470e00c0e191606e7391e9ee14d0a113
URL: https://github.com/llvm/llvm-project/commit/a1c2ee01470e00c0e191606e7391e9ee14d0a113
DIFF: https://github.com/llvm/llvm-project/commit/a1c2ee01470e00c0e191606e7391e9ee14d0a113.diff
LOG: [ELF] LinkerScript/OutputSection: change other std::vector members to SmallVector
11+KiB smaller .text with both libc++ and libstdc++ builds.
Added:
Modified:
lld/ELF/LinkerScript.cpp
lld/ELF/LinkerScript.h
lld/ELF/OutputSections.cpp
lld/ELF/OutputSections.h
lld/ELF/ScriptParser.cpp
lld/ELF/SyntheticSections.h
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 9a95256a15af1..7c67ee53adbac 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -306,7 +306,7 @@ getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
// Process INSERT [AFTER|BEFORE] commands. For each command, we move the
// specified output section to the designated place.
void LinkerScript::processInsertCommands() {
- std::vector<OutputSection *> moves;
+ SmallVector<OutputSection *, 0> moves;
for (const InsertCommand &cmd : insertCommands) {
for (StringRef name : cmd.names) {
// If base is empty, it may have been discarded by
@@ -490,7 +490,7 @@ SmallVector<InputSectionBase *, 0>
LinkerScript::computeInputSections(const InputSectionDescription *cmd,
ArrayRef<InputSectionBase *> sections) {
SmallVector<InputSectionBase *, 0> ret;
- std::vector<size_t> indexes;
+ SmallVector<size_t, 0> indexes;
DenseSet<size_t> seen;
auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
llvm::sort(MutableArrayRef<size_t>(indexes).slice(begin, end - begin));
@@ -827,7 +827,7 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map,
// Add sections that didn't match any sections command.
void LinkerScript::addOrphanSections() {
StringMap<TinyPtrVector<OutputSection *>> map;
- std::vector<OutputSection *> v;
+ SmallVector<OutputSection *, 0> v;
std::function<void(InputSectionBase *)> add;
add = [&](InputSectionBase *s) {
@@ -1110,7 +1110,7 @@ bool LinkerScript::isDiscarded(const OutputSection *sec) const {
}
static void maybePropagatePhdrs(OutputSection &sec,
- std::vector<StringRef> &phdrs) {
+ SmallVector<StringRef, 0> &phdrs) {
if (sec.phdrs.empty()) {
// To match the bfd linker script behaviour, only propagate program
// headers to sections that are allocated.
@@ -1144,7 +1144,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
// the previous sections. Only a few flags are needed to keep the impact low.
uint64_t flags = SHF_ALLOC;
- std::vector<StringRef> defPhdrs;
+ SmallVector<StringRef, 0> defPhdrs;
for (SectionCommand *&cmd : sectionCommands) {
auto *sec = dyn_cast<OutputSection>(cmd);
if (!sec)
@@ -1215,7 +1215,7 @@ void LinkerScript::adjustSectionsAfterSorting() {
// Below is an example of such linker script:
// PHDRS { seg PT_LOAD; }
// SECTIONS { .aaa : { *(.aaa) } }
- std::vector<StringRef> defPhdrs;
+ SmallVector<StringRef, 0> defPhdrs;
auto firstPtLoad = llvm::find_if(phdrsCommands, [](const PhdrsCommand &cmd) {
return cmd.type == PT_LOAD;
});
@@ -1245,7 +1245,7 @@ static uint64_t computeBase(uint64_t min, bool allocateHeaders) {
// We check if the headers fit below the first allocated section. If there isn't
// enough space for these sections, we'll remove them from the PT_LOAD segment,
// and we'll also remove the PT_PHDR segment.
-void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &phdrs) {
+void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
uint64_t min = std::numeric_limits<uint64_t>::max();
for (OutputSection *sec : outputSections)
if (sec->flags & SHF_ALLOC)
@@ -1329,8 +1329,8 @@ const Defined *LinkerScript::assignAddresses() {
}
// Creates program headers as instructed by PHDRS linker script command.
-std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
- std::vector<PhdrEntry *> ret;
+SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
+ SmallVector<PhdrEntry *, 0> ret;
// Process PHDRS and FILEHDR keywords because they are not
// real output sections and cannot be added in the following loop.
@@ -1412,8 +1412,8 @@ static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> vec,
// Returns indices of ELF headers containing specific section. Each index is a
// zero based number of ELF header listed within PHDRS {} script block.
-std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *cmd) {
- std::vector<size_t> ret;
+SmallVector<size_t, 0> LinkerScript::getPhdrIndices(OutputSection *cmd) {
+ SmallVector<size_t, 0> ret;
for (StringRef s : cmd->phdrs) {
if (Optional<size_t> idx = getPhdrIndex(phdrsCommands, s))
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 9fafdb64bfaff..c415186f6de92 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -244,7 +244,7 @@ struct ByteCommand : SectionCommand {
};
struct InsertCommand {
- std::vector<StringRef> names;
+ SmallVector<StringRef, 0> names;
bool isAfter;
StringRef where;
};
@@ -287,7 +287,7 @@ class LinkerScript final {
void discardSynthetic(OutputSection &);
- std::vector<size_t> getPhdrIndices(OutputSection *sec);
+ SmallVector<size_t, 0> getPhdrIndices(OutputSection *sec);
std::pair<MemoryRegion *, MemoryRegion *>
findMemoryRegion(OutputSection *sec, MemoryRegion *hint);
@@ -321,12 +321,12 @@ class LinkerScript final {
void adjustSectionsBeforeSorting();
void adjustSectionsAfterSorting();
- std::vector<PhdrEntry *> createPhdrs();
+ SmallVector<PhdrEntry *, 0> createPhdrs();
bool needsInterpSection();
bool shouldKeep(InputSectionBase *s);
const Defined *assignAddresses();
- void allocateHeaders(std::vector<PhdrEntry *> &phdrs);
+ void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
void processSectionCommands();
void processSymbolAssignments();
void declareSymbols();
@@ -337,10 +337,10 @@ class LinkerScript final {
void processInsertCommands();
// SECTIONS command list.
- std::vector<SectionCommand *> sectionCommands;
+ SmallVector<SectionCommand *, 0> sectionCommands;
// PHDRS command list.
- std::vector<PhdrsCommand> phdrsCommands;
+ SmallVector<PhdrsCommand, 0> phdrsCommands;
bool hasSectionsCommand = false;
bool errorOnMissingSection = false;
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index cd53eecd8756a..07ee7d84a2cd3 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -347,7 +347,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *buf) {
}
// Write leading padding.
- std::vector<InputSection *> sections = getInputSections(this);
+ SmallVector<InputSection *, 0> sections = getInputSections(*this);
std::array<uint8_t, 4> filler = getFiller();
bool nonZeroFiller = read32(filler.data()) != 0;
if (nonZeroFiller)
@@ -520,9 +520,9 @@ InputSection *elf::getFirstInputSection(const OutputSection *os) {
return nullptr;
}
-std::vector<InputSection *> elf::getInputSections(const OutputSection *os) {
- std::vector<InputSection *> ret;
- for (SectionCommand *cmd : os->commands)
+SmallVector<InputSection *, 0> elf::getInputSections(const OutputSection &os) {
+ SmallVector<InputSection *, 0> ret;
+ for (SectionCommand *cmd : os.commands)
if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
ret.insert(ret.end(), isd->sections.begin(), isd->sections.end());
return ret;
@@ -550,7 +550,7 @@ std::array<uint8_t, 4> OutputSection::getFiller() {
void OutputSection::checkDynRelAddends(const uint8_t *bufStart) {
assert(config->writeAddends && config->checkDynamicRelocs);
assert(type == SHT_REL || type == SHT_RELA);
- std::vector<InputSection *> sections = getInputSections(this);
+ SmallVector<InputSection *, 0> sections = getInputSections(*this);
parallelForEachN(0, sections.size(), [&](size_t i) {
// When linking with -r or --emit-relocs we might also call this function
// for input .rel[a].<sec> sections which we simply pass through to the
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index fb3eb00599094..4f589d8432e43 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -82,8 +82,8 @@ class OutputSection final : public SectionCommand, public SectionBase {
Expr alignExpr;
Expr lmaExpr;
Expr subalignExpr;
- std::vector<SectionCommand *> commands;
- std::vector<StringRef> phdrs;
+ SmallVector<SectionCommand *, 0> commands;
+ SmallVector<StringRef, 0> phdrs;
llvm::Optional<std::array<uint8_t, 4>> filler;
ConstraintKind constraint = ConstraintKind::NoConstraint;
std::string location;
@@ -112,8 +112,8 @@ class OutputSection final : public SectionCommand, public SectionBase {
private:
// Used for implementation of --compress-debug-sections option.
- std::vector<uint8_t> zDebugHeader;
- llvm::SmallVector<char, 0> compressedData;
+ SmallVector<uint8_t, 0> zDebugHeader;
+ SmallVector<char, 0> compressedData;
std::array<uint8_t, 4> getFiller();
};
@@ -121,7 +121,7 @@ class OutputSection final : public SectionCommand, public SectionBase {
int getPriority(StringRef s);
InputSection *getFirstInputSection(const OutputSection *os);
-std::vector<InputSection *> getInputSections(const OutputSection *os);
+SmallVector<InputSection *, 0> getInputSections(const OutputSection &os);
// All output sections that are handled by the linker specially are
// globally accessible. Writer initializes them, so don't use them
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index d3b0296acab02..49da94e9c52f3 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -94,7 +94,7 @@ class ScriptParser final : ScriptLexer {
OutputSection *readOverlaySectionDescription();
OutputSection *readOutputSectionDescription(StringRef outSec);
std::vector<SectionCommand *> readOverlay();
- std::vector<StringRef> readOutputSectionPhdrs();
+ SmallVector<StringRef, 0> readOutputSectionPhdrs();
std::pair<uint64_t, uint64_t> readInputSectionFlags();
InputSectionDescription *readInputSectionDescription(StringRef tok);
StringMatcher readFilePatterns();
@@ -597,7 +597,7 @@ void ScriptParser::readSections() {
else if (!consume("BEFORE"))
setError("expected AFTER/BEFORE, but got '" + next() + "'");
StringRef where = next();
- std::vector<StringRef> names;
+ SmallVector<StringRef, 0> names;
for (SectionCommand *cmd : v)
if (auto *os = dyn_cast<OutputSection>(cmd))
names.push_back(os->name);
@@ -1452,8 +1452,8 @@ Expr ScriptParser::readParenExpr() {
return e;
}
-std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
- std::vector<StringRef> phdrs;
+SmallVector<StringRef, 0> ScriptParser::readOutputSectionPhdrs() {
+ SmallVector<StringRef, 0> phdrs;
while (!errorCount() && peek().startswith(":")) {
StringRef tok = next();
phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index c35e19cf2fb46..c785d5b48b33a 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1205,7 +1205,7 @@ struct Partition {
SyntheticSection *elfHeader;
SyntheticSection *programHeaders;
- std::vector<PhdrEntry *> phdrs;
+ SmallVector<PhdrEntry *, 0> phdrs;
ARMExidxSyntheticSection *armExidx;
BuildIdSection *buildId;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 6fbb3f7bf471e..acc78dd067341 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -65,7 +65,7 @@ template <class ELFT> class Writer {
void checkExecuteOnly();
void setReservedSymbolSections();
- std::vector<PhdrEntry *> createPhdrs(Partition &part);
+ SmallVector<PhdrEntry *, 0> createPhdrs(Partition &part);
void addPhdrForSection(Partition &part, unsigned shType, unsigned pType,
unsigned pFlags);
void assignFileOffsets();
@@ -100,7 +100,7 @@ template <class ELFT> void elf::writeResult() {
Writer<ELFT>().run();
}
-static void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
+static void removeEmptyPTLoad(SmallVector<PhdrEntry *, 0> &phdrs) {
auto it = std::stable_partition(
phdrs.begin(), phdrs.end(), [&](const PhdrEntry *p) {
if (p->p_type != PT_LOAD)
@@ -1170,9 +1170,9 @@ static bool shouldSkip(SectionCommand *cmd) {
// We want to place orphan sections so that they share as much
// characteristics with their neighbors as possible. For example, if
// both are rw, or both are tls.
-static std::vector<SectionCommand *>::iterator
-findOrphanPos(std::vector<SectionCommand *>::iterator b,
- std::vector<SectionCommand *>::iterator e) {
+static SmallVectorImpl<SectionCommand *>::iterator
+findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
+ SmallVectorImpl<SectionCommand *>::iterator e) {
OutputSection *sec = cast<OutputSection>(*e);
// Find the first element that has as close a rank as possible.
@@ -1332,8 +1332,8 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
static void
sortISDBySectionOrder(InputSectionDescription *isd,
const DenseMap<const InputSectionBase *, int> &order) {
- std::vector<InputSection *> unorderedSections;
- std::vector<std::pair<InputSection *, int>> orderedSections;
+ SmallVector<InputSection *, 0> unorderedSections;
+ SmallVector<std::pair<InputSection *, int>, 0> orderedSections;
uint64_t unorderedSize = 0;
for (InputSection *isec : isd->sections) {
@@ -1766,10 +1766,10 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
// jump to the following section as it is not required.
// 2. If there are two consecutive jump instructions, it checks
// if they can be flipped and one can be deleted.
- for (OutputSection *os : outputSections) {
- if (!(os->flags & SHF_EXECINSTR))
+ for (OutputSection *osec : outputSections) {
+ if (!(osec->flags & SHF_EXECINSTR))
continue;
- std::vector<InputSection *> sections = getInputSections(os);
+ SmallVector<InputSection *, 0> sections = getInputSections(*osec);
std::vector<unsigned> result(sections.size());
// Delete all fall through jump instructions. Also, check if two
// consecutive jump instructions can be flipped so that a fall
@@ -1790,11 +1790,9 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
fixSymbolsAfterShrinking();
- for (OutputSection *os : outputSections) {
- std::vector<InputSection *> sections = getInputSections(os);
- for (InputSection *is : sections)
+ for (OutputSection *osec : outputSections)
+ for (InputSection *is : getInputSections(*osec))
is->trim();
- }
}
// In order to allow users to manipulate linker-synthesized sections,
@@ -2165,11 +2163,12 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
if (!config->executeOnly)
return;
- for (OutputSection *os : outputSections)
- if (os->flags & SHF_EXECINSTR)
- for (InputSection *isec : getInputSections(os))
+ for (OutputSection *osec : outputSections)
+ if (osec->flags & SHF_EXECINSTR)
+ for (InputSection *isec : getInputSections(*osec))
if (!(isec->flags & SHF_EXECINSTR))
- error("cannot place " + toString(isec) + " into " + toString(os->name) +
+ error("cannot place " + toString(isec) + " into " +
+ toString(osec->name) +
": -execute-only does not support intermingling data and code");
}
@@ -2259,8 +2258,8 @@ static uint64_t computeFlags(uint64_t flags) {
// Decide which program headers to create and which sections to include in each
// one.
template <class ELFT>
-std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &part) {
- std::vector<PhdrEntry *> ret;
+SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
+ SmallVector<PhdrEntry *, 0> ret;
auto addHdr = [&](unsigned type, unsigned flags) -> PhdrEntry * {
ret.push_back(make<PhdrEntry>(type, flags));
return ret.back();
More information about the llvm-commits
mailing list