Skip to content

Commit a1c2ee0

Browse files
committed
[ELF] LinkerScript/OutputSection: change other std::vector members to SmallVector
11+KiB smaller .text with both libc++ and libstdc++ builds.
1 parent 31cfb3f commit a1c2ee0

7 files changed

+51
-52
lines changed

lld/ELF/LinkerScript.cpp

+11-11
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
306306
// Process INSERT [AFTER|BEFORE] commands. For each command, we move the
307307
// specified output section to the designated place.
308308
void LinkerScript::processInsertCommands() {
309-
std::vector<OutputSection *> moves;
309+
SmallVector<OutputSection *, 0> moves;
310310
for (const InsertCommand &cmd : insertCommands) {
311311
for (StringRef name : cmd.names) {
312312
// If base is empty, it may have been discarded by
@@ -490,7 +490,7 @@ SmallVector<InputSectionBase *, 0>
490490
LinkerScript::computeInputSections(const InputSectionDescription *cmd,
491491
ArrayRef<InputSectionBase *> sections) {
492492
SmallVector<InputSectionBase *, 0> ret;
493-
std::vector<size_t> indexes;
493+
SmallVector<size_t, 0> indexes;
494494
DenseSet<size_t> seen;
495495
auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
496496
llvm::sort(MutableArrayRef<size_t>(indexes).slice(begin, end - begin));
@@ -827,7 +827,7 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map,
827827
// Add sections that didn't match any sections command.
828828
void LinkerScript::addOrphanSections() {
829829
StringMap<TinyPtrVector<OutputSection *>> map;
830-
std::vector<OutputSection *> v;
830+
SmallVector<OutputSection *, 0> v;
831831

832832
std::function<void(InputSectionBase *)> add;
833833
add = [&](InputSectionBase *s) {
@@ -1110,7 +1110,7 @@ bool LinkerScript::isDiscarded(const OutputSection *sec) const {
11101110
}
11111111

11121112
static void maybePropagatePhdrs(OutputSection &sec,
1113-
std::vector<StringRef> &phdrs) {
1113+
SmallVector<StringRef, 0> &phdrs) {
11141114
if (sec.phdrs.empty()) {
11151115
// To match the bfd linker script behaviour, only propagate program
11161116
// headers to sections that are allocated.
@@ -1144,7 +1144,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
11441144
// the previous sections. Only a few flags are needed to keep the impact low.
11451145
uint64_t flags = SHF_ALLOC;
11461146

1147-
std::vector<StringRef> defPhdrs;
1147+
SmallVector<StringRef, 0> defPhdrs;
11481148
for (SectionCommand *&cmd : sectionCommands) {
11491149
auto *sec = dyn_cast<OutputSection>(cmd);
11501150
if (!sec)
@@ -1215,7 +1215,7 @@ void LinkerScript::adjustSectionsAfterSorting() {
12151215
// Below is an example of such linker script:
12161216
// PHDRS { seg PT_LOAD; }
12171217
// SECTIONS { .aaa : { *(.aaa) } }
1218-
std::vector<StringRef> defPhdrs;
1218+
SmallVector<StringRef, 0> defPhdrs;
12191219
auto firstPtLoad = llvm::find_if(phdrsCommands, [](const PhdrsCommand &cmd) {
12201220
return cmd.type == PT_LOAD;
12211221
});
@@ -1245,7 +1245,7 @@ static uint64_t computeBase(uint64_t min, bool allocateHeaders) {
12451245
// We check if the headers fit below the first allocated section. If there isn't
12461246
// enough space for these sections, we'll remove them from the PT_LOAD segment,
12471247
// and we'll also remove the PT_PHDR segment.
1248-
void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &phdrs) {
1248+
void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
12491249
uint64_t min = std::numeric_limits<uint64_t>::max();
12501250
for (OutputSection *sec : outputSections)
12511251
if (sec->flags & SHF_ALLOC)
@@ -1329,8 +1329,8 @@ const Defined *LinkerScript::assignAddresses() {
13291329
}
13301330

13311331
// Creates program headers as instructed by PHDRS linker script command.
1332-
std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
1333-
std::vector<PhdrEntry *> ret;
1332+
SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
1333+
SmallVector<PhdrEntry *, 0> ret;
13341334

13351335
// Process PHDRS and FILEHDR keywords because they are not
13361336
// real output sections and cannot be added in the following loop.
@@ -1412,8 +1412,8 @@ static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> vec,
14121412

14131413
// Returns indices of ELF headers containing specific section. Each index is a
14141414
// zero based number of ELF header listed within PHDRS {} script block.
1415-
std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *cmd) {
1416-
std::vector<size_t> ret;
1415+
SmallVector<size_t, 0> LinkerScript::getPhdrIndices(OutputSection *cmd) {
1416+
SmallVector<size_t, 0> ret;
14171417

14181418
for (StringRef s : cmd->phdrs) {
14191419
if (Optional<size_t> idx = getPhdrIndex(phdrsCommands, s))

lld/ELF/LinkerScript.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ struct ByteCommand : SectionCommand {
244244
};
245245

246246
struct InsertCommand {
247-
std::vector<StringRef> names;
247+
SmallVector<StringRef, 0> names;
248248
bool isAfter;
249249
StringRef where;
250250
};
@@ -287,7 +287,7 @@ class LinkerScript final {
287287

288288
void discardSynthetic(OutputSection &);
289289

290-
std::vector<size_t> getPhdrIndices(OutputSection *sec);
290+
SmallVector<size_t, 0> getPhdrIndices(OutputSection *sec);
291291

292292
std::pair<MemoryRegion *, MemoryRegion *>
293293
findMemoryRegion(OutputSection *sec, MemoryRegion *hint);
@@ -321,12 +321,12 @@ class LinkerScript final {
321321
void adjustSectionsBeforeSorting();
322322
void adjustSectionsAfterSorting();
323323

324-
std::vector<PhdrEntry *> createPhdrs();
324+
SmallVector<PhdrEntry *, 0> createPhdrs();
325325
bool needsInterpSection();
326326

327327
bool shouldKeep(InputSectionBase *s);
328328
const Defined *assignAddresses();
329-
void allocateHeaders(std::vector<PhdrEntry *> &phdrs);
329+
void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
330330
void processSectionCommands();
331331
void processSymbolAssignments();
332332
void declareSymbols();
@@ -337,10 +337,10 @@ class LinkerScript final {
337337
void processInsertCommands();
338338

339339
// SECTIONS command list.
340-
std::vector<SectionCommand *> sectionCommands;
340+
SmallVector<SectionCommand *, 0> sectionCommands;
341341

342342
// PHDRS command list.
343-
std::vector<PhdrsCommand> phdrsCommands;
343+
SmallVector<PhdrsCommand, 0> phdrsCommands;
344344

345345
bool hasSectionsCommand = false;
346346
bool errorOnMissingSection = false;

lld/ELF/OutputSections.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *buf) {
347347
}
348348

349349
// Write leading padding.
350-
std::vector<InputSection *> sections = getInputSections(this);
350+
SmallVector<InputSection *, 0> sections = getInputSections(*this);
351351
std::array<uint8_t, 4> filler = getFiller();
352352
bool nonZeroFiller = read32(filler.data()) != 0;
353353
if (nonZeroFiller)
@@ -520,9 +520,9 @@ InputSection *elf::getFirstInputSection(const OutputSection *os) {
520520
return nullptr;
521521
}
522522

523-
std::vector<InputSection *> elf::getInputSections(const OutputSection *os) {
524-
std::vector<InputSection *> ret;
525-
for (SectionCommand *cmd : os->commands)
523+
SmallVector<InputSection *, 0> elf::getInputSections(const OutputSection &os) {
524+
SmallVector<InputSection *, 0> ret;
525+
for (SectionCommand *cmd : os.commands)
526526
if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
527527
ret.insert(ret.end(), isd->sections.begin(), isd->sections.end());
528528
return ret;
@@ -550,7 +550,7 @@ std::array<uint8_t, 4> OutputSection::getFiller() {
550550
void OutputSection::checkDynRelAddends(const uint8_t *bufStart) {
551551
assert(config->writeAddends && config->checkDynamicRelocs);
552552
assert(type == SHT_REL || type == SHT_RELA);
553-
std::vector<InputSection *> sections = getInputSections(this);
553+
SmallVector<InputSection *, 0> sections = getInputSections(*this);
554554
parallelForEachN(0, sections.size(), [&](size_t i) {
555555
// When linking with -r or --emit-relocs we might also call this function
556556
// for input .rel[a].<sec> sections which we simply pass through to the

lld/ELF/OutputSections.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ class OutputSection final : public SectionCommand, public SectionBase {
8282
Expr alignExpr;
8383
Expr lmaExpr;
8484
Expr subalignExpr;
85-
std::vector<SectionCommand *> commands;
86-
std::vector<StringRef> phdrs;
85+
SmallVector<SectionCommand *, 0> commands;
86+
SmallVector<StringRef, 0> phdrs;
8787
llvm::Optional<std::array<uint8_t, 4>> filler;
8888
ConstraintKind constraint = ConstraintKind::NoConstraint;
8989
std::string location;
@@ -112,16 +112,16 @@ class OutputSection final : public SectionCommand, public SectionBase {
112112

113113
private:
114114
// Used for implementation of --compress-debug-sections option.
115-
std::vector<uint8_t> zDebugHeader;
116-
llvm::SmallVector<char, 0> compressedData;
115+
SmallVector<uint8_t, 0> zDebugHeader;
116+
SmallVector<char, 0> compressedData;
117117

118118
std::array<uint8_t, 4> getFiller();
119119
};
120120

121121
int getPriority(StringRef s);
122122

123123
InputSection *getFirstInputSection(const OutputSection *os);
124-
std::vector<InputSection *> getInputSections(const OutputSection *os);
124+
SmallVector<InputSection *, 0> getInputSections(const OutputSection &os);
125125

126126
// All output sections that are handled by the linker specially are
127127
// globally accessible. Writer initializes them, so don't use them

lld/ELF/ScriptParser.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class ScriptParser final : ScriptLexer {
9494
OutputSection *readOverlaySectionDescription();
9595
OutputSection *readOutputSectionDescription(StringRef outSec);
9696
std::vector<SectionCommand *> readOverlay();
97-
std::vector<StringRef> readOutputSectionPhdrs();
97+
SmallVector<StringRef, 0> readOutputSectionPhdrs();
9898
std::pair<uint64_t, uint64_t> readInputSectionFlags();
9999
InputSectionDescription *readInputSectionDescription(StringRef tok);
100100
StringMatcher readFilePatterns();
@@ -597,7 +597,7 @@ void ScriptParser::readSections() {
597597
else if (!consume("BEFORE"))
598598
setError("expected AFTER/BEFORE, but got '" + next() + "'");
599599
StringRef where = next();
600-
std::vector<StringRef> names;
600+
SmallVector<StringRef, 0> names;
601601
for (SectionCommand *cmd : v)
602602
if (auto *os = dyn_cast<OutputSection>(cmd))
603603
names.push_back(os->name);
@@ -1452,8 +1452,8 @@ Expr ScriptParser::readParenExpr() {
14521452
return e;
14531453
}
14541454

1455-
std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1456-
std::vector<StringRef> phdrs;
1455+
SmallVector<StringRef, 0> ScriptParser::readOutputSectionPhdrs() {
1456+
SmallVector<StringRef, 0> phdrs;
14571457
while (!errorCount() && peek().startswith(":")) {
14581458
StringRef tok = next();
14591459
phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));

lld/ELF/SyntheticSections.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ struct Partition {
12051205

12061206
SyntheticSection *elfHeader;
12071207
SyntheticSection *programHeaders;
1208-
std::vector<PhdrEntry *> phdrs;
1208+
SmallVector<PhdrEntry *, 0> phdrs;
12091209

12101210
ARMExidxSyntheticSection *armExidx;
12111211
BuildIdSection *buildId;

lld/ELF/Writer.cpp

+19-20
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ template <class ELFT> class Writer {
6565
void checkExecuteOnly();
6666
void setReservedSymbolSections();
6767

68-
std::vector<PhdrEntry *> createPhdrs(Partition &part);
68+
SmallVector<PhdrEntry *, 0> createPhdrs(Partition &part);
6969
void addPhdrForSection(Partition &part, unsigned shType, unsigned pType,
7070
unsigned pFlags);
7171
void assignFileOffsets();
@@ -100,7 +100,7 @@ template <class ELFT> void elf::writeResult() {
100100
Writer<ELFT>().run();
101101
}
102102

103-
static void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
103+
static void removeEmptyPTLoad(SmallVector<PhdrEntry *, 0> &phdrs) {
104104
auto it = std::stable_partition(
105105
phdrs.begin(), phdrs.end(), [&](const PhdrEntry *p) {
106106
if (p->p_type != PT_LOAD)
@@ -1170,9 +1170,9 @@ static bool shouldSkip(SectionCommand *cmd) {
11701170
// We want to place orphan sections so that they share as much
11711171
// characteristics with their neighbors as possible. For example, if
11721172
// both are rw, or both are tls.
1173-
static std::vector<SectionCommand *>::iterator
1174-
findOrphanPos(std::vector<SectionCommand *>::iterator b,
1175-
std::vector<SectionCommand *>::iterator e) {
1173+
static SmallVectorImpl<SectionCommand *>::iterator
1174+
findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
1175+
SmallVectorImpl<SectionCommand *>::iterator e) {
11761176
OutputSection *sec = cast<OutputSection>(*e);
11771177

11781178
// Find the first element that has as close a rank as possible.
@@ -1332,8 +1332,8 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
13321332
static void
13331333
sortISDBySectionOrder(InputSectionDescription *isd,
13341334
const DenseMap<const InputSectionBase *, int> &order) {
1335-
std::vector<InputSection *> unorderedSections;
1336-
std::vector<std::pair<InputSection *, int>> orderedSections;
1335+
SmallVector<InputSection *, 0> unorderedSections;
1336+
SmallVector<std::pair<InputSection *, int>, 0> orderedSections;
13371337
uint64_t unorderedSize = 0;
13381338

13391339
for (InputSection *isec : isd->sections) {
@@ -1766,10 +1766,10 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
17661766
// jump to the following section as it is not required.
17671767
// 2. If there are two consecutive jump instructions, it checks
17681768
// if they can be flipped and one can be deleted.
1769-
for (OutputSection *os : outputSections) {
1770-
if (!(os->flags & SHF_EXECINSTR))
1769+
for (OutputSection *osec : outputSections) {
1770+
if (!(osec->flags & SHF_EXECINSTR))
17711771
continue;
1772-
std::vector<InputSection *> sections = getInputSections(os);
1772+
SmallVector<InputSection *, 0> sections = getInputSections(*osec);
17731773
std::vector<unsigned> result(sections.size());
17741774
// Delete all fall through jump instructions. Also, check if two
17751775
// consecutive jump instructions can be flipped so that a fall
@@ -1790,11 +1790,9 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
17901790

17911791
fixSymbolsAfterShrinking();
17921792

1793-
for (OutputSection *os : outputSections) {
1794-
std::vector<InputSection *> sections = getInputSections(os);
1795-
for (InputSection *is : sections)
1793+
for (OutputSection *osec : outputSections)
1794+
for (InputSection *is : getInputSections(*osec))
17961795
is->trim();
1797-
}
17981796
}
17991797

18001798
// In order to allow users to manipulate linker-synthesized sections,
@@ -2165,11 +2163,12 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
21652163
if (!config->executeOnly)
21662164
return;
21672165

2168-
for (OutputSection *os : outputSections)
2169-
if (os->flags & SHF_EXECINSTR)
2170-
for (InputSection *isec : getInputSections(os))
2166+
for (OutputSection *osec : outputSections)
2167+
if (osec->flags & SHF_EXECINSTR)
2168+
for (InputSection *isec : getInputSections(*osec))
21712169
if (!(isec->flags & SHF_EXECINSTR))
2172-
error("cannot place " + toString(isec) + " into " + toString(os->name) +
2170+
error("cannot place " + toString(isec) + " into " +
2171+
toString(osec->name) +
21732172
": -execute-only does not support intermingling data and code");
21742173
}
21752174

@@ -2259,8 +2258,8 @@ static uint64_t computeFlags(uint64_t flags) {
22592258
// Decide which program headers to create and which sections to include in each
22602259
// one.
22612260
template <class ELFT>
2262-
std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &part) {
2263-
std::vector<PhdrEntry *> ret;
2261+
SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
2262+
SmallVector<PhdrEntry *, 0> ret;
22642263
auto addHdr = [&](unsigned type, unsigned flags) -> PhdrEntry * {
22652264
ret.push_back(make<PhdrEntry>(type, flags));
22662265
return ret.back();

0 commit comments

Comments
 (0)