[lld] e0612c9 - [ELF] Optimize getInputSections. NFC
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 5 23:31:17 PDT 2022
Author: Fangrui Song
Date: 2022-07-05T23:31:09-07:00
New Revision: e0612c91cd16596ffa307952b1a8345c145f9326
URL: https://github.com/llvm/llvm-project/commit/e0612c91cd16596ffa307952b1a8345c145f9326
DIFF: https://github.com/llvm/llvm-project/commit/e0612c91cd16596ffa307952b1a8345c145f9326.diff
LOG: [ELF] Optimize getInputSections. NFC
In the majority of cases (e.g. orphan sections), an OutputSection has at most
one InputSectionDescription (isd). By changing the return type to
ArrayRef<InputSection *> we can just reference the isd->sections. For
OutputSections with more than one InputSectionDescription we use a caller
provided SmallVector to copy the elements as before.
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D129111
Added:
Modified:
lld/ELF/OutputSections.cpp
lld/ELF/OutputSections.h
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index bc940c7e6546..cbde8ac800d3 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -419,7 +419,8 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *buf) {
}
// Write leading padding.
- SmallVector<InputSection *, 0> sections = getInputSections(*this);
+ SmallVector<InputSection *, 0> storage;
+ ArrayRef<InputSection *> sections = getInputSections(*this, storage);
std::array<uint8_t, 4> filler = getFiller();
bool nonZeroFiller = read32(filler.data()) != 0;
if (nonZeroFiller)
@@ -592,12 +593,24 @@ InputSection *elf::getFirstInputSection(const OutputSection *os) {
return nullptr;
}
-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;
+ArrayRef<InputSection *>
+elf::getInputSections(const OutputSection &os,
+ SmallVector<InputSection *, 0> &storage) {
+ ArrayRef<InputSection *> ret;
+ storage.clear();
+ for (SectionCommand *cmd : os.commands) {
+ auto *isd = dyn_cast<InputSectionDescription>(cmd);
+ if (!isd)
+ continue;
+ if (ret.empty()) {
+ ret = isd->sections;
+ } else {
+ if (storage.empty())
+ storage.assign(ret.begin(), ret.end());
+ storage.insert(storage.end(), isd->sections.begin(), isd->sections.end());
+ }
+ }
+ return storage.empty() ? ret : makeArrayRef(storage);
}
// Sorts input sections by section name suffixes, so that .foo.N comes
@@ -622,7 +635,8 @@ 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);
- SmallVector<InputSection *, 0> sections = getInputSections(*this);
+ SmallVector<InputSection *, 0> storage;
+ ArrayRef<InputSection *> sections = getInputSections(*this, storage);
parallelFor(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 020eeaec368e..6bdbcfce7b12 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -134,7 +134,9 @@ struct OutputDesc final : SectionCommand {
int getPriority(StringRef s);
InputSection *getFirstInputSection(const OutputSection *os);
-SmallVector<InputSection *, 0> getInputSections(const OutputSection &os);
+llvm::ArrayRef<InputSection *>
+getInputSections(const OutputSection &os,
+ SmallVector<InputSection *, 0> &storage);
// 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/Writer.cpp b/lld/ELF/Writer.cpp
index 7bfe29eda695..8ac6fc7cb831 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1741,6 +1741,7 @@ static void fixSymbolsAfterShrinking() {
// option is used.
template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
assert(config->optimizeBBJumps);
+ SmallVector<InputSection *, 0> storage;
script->assignAddresses();
// For every output section that has executable input sections, this
@@ -1752,7 +1753,7 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
for (OutputSection *osec : outputSections) {
if (!(osec->flags & SHF_EXECINSTR))
continue;
- SmallVector<InputSection *, 0> sections = getInputSections(*osec);
+ ArrayRef<InputSection *> sections = getInputSections(*osec, storage);
size_t numDeleted = 0;
// Delete all fall through jump instructions. Also, check if two
// consecutive jump instructions can be flipped so that a fall
@@ -1772,7 +1773,7 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
fixSymbolsAfterShrinking();
for (OutputSection *osec : outputSections)
- for (InputSection *is : getInputSections(*osec))
+ for (InputSection *is : getInputSections(*osec, storage))
is->trim();
}
@@ -2165,9 +2166,10 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
if (!config->executeOnly)
return;
+ SmallVector<InputSection *, 0> storage;
for (OutputSection *osec : outputSections)
if (osec->flags & SHF_EXECINSTR)
- for (InputSection *isec : getInputSections(*osec))
+ for (InputSection *isec : getInputSections(*osec, storage))
if (!(isec->flags & SHF_EXECINSTR))
error("cannot place " + toString(isec) + " into " +
toString(osec->name) +
More information about the llvm-commits
mailing list