[ELF] LinkerScript/OutputSection: change other std::vector members to SmallVector

11+KiB smaller .text with both libc++ and libstdc++ builds.
This commit is contained in:
Fangrui Song 2021-12-26 13:53:47 -08:00
parent 31cfb3f4f6
commit a1c2ee0147
7 changed files with 51 additions and 52 deletions

View File

@ -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))

View File

@ -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 @@ public:
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 @@ public:
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;

View File

@ -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

View File

@ -82,8 +82,8 @@ public:
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 @@ public:
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 @@ private:
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

View File

@ -94,7 +94,7 @@ private:
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));

View File

@ -1205,7 +1205,7 @@ struct Partition {
SyntheticSection *elfHeader;
SyntheticSection *programHeaders;
std::vector<PhdrEntry *> phdrs;
SmallVector<PhdrEntry *, 0> phdrs;
ARMExidxSyntheticSection *armExidx;
BuildIdSection *buildId;

View File

@ -65,7 +65,7 @@ private:
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,12 +1790,10 @@ 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,
// we had to add synthetic sections to the input section list early,
@ -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();