-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Revert "[LLD] Implement --enable-non-contiguous-regions" #92005
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This reverts commit 6731144.
@llvm/pr-subscribers-lld @llvm/pr-subscribers-lld-elf Author: Daniel Thornburgh (mysterymath) ChangesReverts llvm/llvm-project#90007 Broke in merging I think. Patch is 34.40 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92005.diff 17 Files Affected:
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index dbb81412453af..c55b547a733c7 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -238,7 +238,6 @@ struct Config {
bool emitLLVM;
bool emitRelocs;
bool enableNewDtags;
- bool enableNonContiguousRegions;
bool executeOnly;
bool exportDynamic;
bool fixCortexA53Errata843419;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 828499fa05a34..dd33f4bd772f2 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1250,8 +1250,6 @@ static void readConfigs(opt::InputArgList &args) {
config->emitRelocs = args.hasArg(OPT_emit_relocs);
config->enableNewDtags =
args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
- config->enableNonContiguousRegions =
- args.hasArg(OPT_enable_non_contiguous_regions);
config->entry = args.getLastArgValue(OPT_entry);
errorHandler().errorHandlingScript =
@@ -3087,7 +3085,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// sectionBases.
for (SectionCommand *cmd : script->sectionCommands)
if (auto *osd = dyn_cast<OutputDesc>(cmd))
- osd->osec.finalizeInputSections(script.get());
+ osd->osec.finalizeInputSections();
}
// Two input sections with different output sections should not be folded.
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 2a1ccd997f8bc..fa81611e7c9e7 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -161,7 +161,6 @@ uint64_t SectionBase::getOffset(uint64_t offset) const {
}
case Regular:
case Synthetic:
- case Spill:
return cast<InputSection>(this)->outSecOff + offset;
case EHFrame: {
// Two code paths may reach here. First, clang_rt.crtbegin.o and GCC
@@ -310,12 +309,6 @@ std::string InputSectionBase::getObjMsg(uint64_t off) const {
.str();
}
-PotentialSpillSection::PotentialSpillSection(const InputSectionBase &source,
- InputSectionDescription &isd)
- : InputSection(source.file, source.flags, source.type, source.addralign, {},
- source.name, SectionBase::Spill),
- isd(&isd) {}
-
InputSection InputSection::discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
InputSection::InputSection(InputFile *f, uint64_t flags, uint32_t type,
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 58e5306fd6dcd..1fb7077ca435b 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -48,7 +48,7 @@ template <class ELFT> struct RelsOrRelas {
// sections.
class SectionBase {
public:
- enum Kind { Regular, Synthetic, Spill, EHFrame, Merge, Output };
+ enum Kind { Regular, Synthetic, EHFrame, Merge, Output };
Kind kind() const { return (Kind)sectionKind; }
@@ -382,8 +382,7 @@ class InputSection : public InputSectionBase {
static bool classof(const SectionBase *s) {
return s->kind() == SectionBase::Regular ||
- s->kind() == SectionBase::Synthetic ||
- s->kind() == SectionBase::Spill;
+ s->kind() == SectionBase::Synthetic;
}
// Write this section to a mmap'ed file, assuming Buf is pointing to
@@ -426,26 +425,6 @@ class InputSection : public InputSectionBase {
template <class ELFT> void copyShtGroup(uint8_t *buf);
};
-// A marker for a potential spill location for another input section. This
-// broadly acts as if it were the original section until address assignment.
-// Then it is either replaced with the real input section or removed.
-class PotentialSpillSection : public InputSection {
-public:
- // The containing input section description; used to quickly replace this stub
- // with the actual section.
- InputSectionDescription *isd;
-
- // Next potential spill location for the same source input section.
- PotentialSpillSection *next = nullptr;
-
- PotentialSpillSection(const InputSectionBase &source,
- InputSectionDescription &isd);
-
- static bool classof(const SectionBase *sec) {
- return sec->kind() == InputSectionBase::Spill;
- }
-};
-
static_assert(sizeof(InputSection) <= 160, "InputSection is too big");
class SyntheticSection : public InputSection {
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 3ba59c112b8a8..c0a5014817b9c 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -304,9 +304,6 @@ getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
void LinkerScript::processInsertCommands() {
SmallVector<OutputDesc *, 0> moves;
for (const InsertCommand &cmd : insertCommands) {
- if (config->enableNonContiguousRegions)
- error("INSERT cannot be used with --enable-non-contiguous-regions");
-
for (StringRef name : cmd.names) {
// If base is empty, it may have been discarded by
// adjustOutputSections(). We do not handle such output sections.
@@ -489,12 +486,10 @@ static void sortInputSections(MutableArrayRef<InputSectionBase *> vec,
// Compute and remember which sections the InputSectionDescription matches.
SmallVector<InputSectionBase *, 0>
LinkerScript::computeInputSections(const InputSectionDescription *cmd,
- ArrayRef<InputSectionBase *> sections,
- const OutputSection &outCmd) {
+ ArrayRef<InputSectionBase *> sections) {
SmallVector<InputSectionBase *, 0> ret;
SmallVector<size_t, 0> indexes;
DenseSet<size_t> seen;
- DenseSet<InputSectionBase *> spills;
auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
llvm::sort(MutableArrayRef<size_t>(indexes).slice(begin, end - begin));
for (size_t i = begin; i != end; ++i)
@@ -510,10 +505,10 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
size_t sizeBeforeCurrPat = ret.size();
for (size_t i = 0, e = sections.size(); i != e; ++i) {
- // Skip if the section is dead or has been matched by a previous pattern
- // in this input section description.
+ // Skip if the section is dead or has been matched by a previous input
+ // section description or a previous pattern.
InputSectionBase *sec = sections[i];
- if (!sec->isLive() || seen.contains(i))
+ if (!sec->isLive() || sec->parent || seen.contains(i))
continue;
// For --emit-relocs we have to ignore entries like
@@ -534,29 +529,6 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
(sec->flags & cmd->withoutFlags) != 0)
continue;
- if (sec->parent) {
- // Skip if not allowing multiple matches.
- if (!config->enableNonContiguousRegions)
- continue;
-
- // Disallow spilling into /DISCARD/; special handling would be needed
- // for this in address assignment, and the semantics are nebulous.
- if (outCmd.name == "/DISCARD/")
- continue;
-
- // Skip if the section's first match was /DISCARD/; such sections are
- // always discarded.
- if (sec->parent->name == "/DISCARD/")
- continue;
-
- // Skip if the section was already matched by a different input section
- // description within this output section.
- if (sec->parent == &outCmd)
- continue;
-
- spills.insert(sec);
- }
-
ret.push_back(sec);
indexes.push_back(i);
seen.insert(i);
@@ -583,30 +555,6 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
// Matched sections after the last SORT* are sorted by (--sort-alignment,
// input order).
sortByPositionThenCommandLine(sizeAfterPrevSort, ret.size());
-
- // The flag --enable-non-contiguous-regions may cause sections to match an
- // InputSectionDescription in more than one OutputSection. Matches after the
- // first were collected in the spills set, so replace these with potential
- // spill sections.
- if (!spills.empty()) {
- for (InputSectionBase *&sec : ret) {
- if (!spills.contains(sec))
- continue;
-
- // Append the spill input section to the list for the input section,
- // creating it if necessary.
- PotentialSpillSection *pss = make<PotentialSpillSection>(
- *sec, const_cast<InputSectionDescription &>(*cmd));
- auto [it, inserted] =
- potentialSpillLists.try_emplace(sec, PotentialSpillList{pss, pss});
- if (!inserted) {
- PotentialSpillSection *&tail = it->second.tail;
- tail = tail->next = pss;
- }
- sec = pss;
- }
- }
-
return ret;
}
@@ -629,7 +577,7 @@ void LinkerScript::discardSynthetic(OutputSection &outCmd) {
part.armExidx->exidxSections.end());
for (SectionCommand *cmd : outCmd.commands)
if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
- for (InputSectionBase *s : computeInputSections(isd, secs, outCmd))
+ for (InputSectionBase *s : computeInputSections(isd, secs))
discard(*s);
}
}
@@ -640,7 +588,7 @@ LinkerScript::createInputSectionList(OutputSection &outCmd) {
for (SectionCommand *cmd : outCmd.commands) {
if (auto *isd = dyn_cast<InputSectionDescription>(cmd)) {
- isd->sectionBases = computeInputSections(isd, ctx.inputSections, outCmd);
+ isd->sectionBases = computeInputSections(isd, ctx.inputSections);
for (InputSectionBase *s : isd->sectionBases)
s->parent = &outCmd;
ret.insert(ret.end(), isd->sectionBases.begin(), isd->sectionBases.end());
@@ -696,9 +644,6 @@ void LinkerScript::processSectionCommands() {
// Process OVERWRITE_SECTIONS first so that it can overwrite the main script
// or orphans.
- if (config->enableNonContiguousRegions && !overwriteSections.empty())
- error("OVERWRITE_SECTIONS cannot be used with "
- "--enable-non-contiguous-regions");
DenseMap<CachedHashStringRef, OutputDesc *> map;
size_t i = 0;
for (OutputDesc *osd : overwriteSections) {
@@ -1121,12 +1066,8 @@ void LinkerScript::assignOffsets(OutputSection *sec) {
// Handle a single input section description command.
// It calculates and assigns the offsets for each section and also
// updates the output section size.
-
- auto §ions = cast<InputSectionDescription>(cmd)->sections;
- for (InputSection *isec : sections) {
+ for (InputSection *isec : cast<InputSectionDescription>(cmd)->sections) {
assert(isec->getParent() == sec);
- if (isa<PotentialSpillSection>(isec))
- continue;
const uint64_t pos = dot;
dot = alignToPowerOf2(dot, isec->addralign);
isec->outSecOff = dot - sec->addr;
@@ -1423,114 +1364,6 @@ const Defined *LinkerScript::assignAddresses() {
return getChangedSymbolAssignment(oldValues);
}
-static bool hasRegionOverflowed(MemoryRegion *mr) {
- if (!mr)
- return false;
- return mr->curPos - mr->getOrigin() > mr->getLength();
-}
-
-// Spill input sections in reverse order of address assignment to (potentially)
-// bring memory regions out of overflow. The size savings of a spill can only be
-// estimated, since general linker script arithmetic may occur afterwards.
-// Under-estimates may cause unnecessary spills, but over-estimates can always
-// be corrected on the next pass.
-bool LinkerScript::spillSections() {
- if (!config->enableNonContiguousRegions)
- return false;
-
- bool spilled = false;
- for (SectionCommand *cmd : reverse(sectionCommands)) {
- auto *od = dyn_cast<OutputDesc>(cmd);
- if (!od)
- continue;
- OutputSection *osec = &od->osec;
- if (!osec->memRegion)
- continue;
-
- // Input sections that have replaced a potential spill and should be removed
- // from their input section description.
- DenseSet<InputSection *> spilledInputSections;
-
- for (SectionCommand *cmd : reverse(osec->commands)) {
- if (!hasRegionOverflowed(osec->memRegion) &&
- !hasRegionOverflowed(osec->lmaRegion))
- break;
-
- auto *isd = dyn_cast<InputSectionDescription>(cmd);
- if (!isd)
- continue;
- for (InputSection *isec : reverse(isd->sections)) {
- // Potential spill locations cannot be spilled.
- if (isa<PotentialSpillSection>(isec))
- continue;
-
- // Find the next potential spill location and remove it from the list.
- auto it = potentialSpillLists.find(isec);
- if (it == potentialSpillLists.end())
- continue;
- PotentialSpillList &list = it->second;
- PotentialSpillSection *spill = list.head;
- if (spill->next)
- list.head = spill->next;
- else
- potentialSpillLists.erase(isec);
-
- // Replace the next spill location with the spilled section and adjust
- // its properties to match the new location. Note that the alignment of
- // the spill section may have diverged from the original due to e.g. a
- // SUBALIGN. Correct assignment requires the spill's alignment to be
- // used, not the original.
- spilledInputSections.insert(isec);
- *llvm::find(spill->isd->sections, spill) = isec;
- isec->parent = spill->parent;
- isec->addralign = spill->addralign;
-
- // Record the (potential) reduction in the region's end position.
- osec->memRegion->curPos -= isec->getSize();
- if (osec->lmaRegion)
- osec->lmaRegion->curPos -= isec->getSize();
-
- // Spilling continues until the end position no longer overflows the
- // region. Then, another round of address assignment will either confirm
- // the spill's success or lead to yet more spilling.
- if (!hasRegionOverflowed(osec->memRegion) &&
- !hasRegionOverflowed(osec->lmaRegion))
- break;
- }
-
- // Remove any spilled input sections to complete their move.
- if (!spilledInputSections.empty()) {
- spilled = true;
- llvm::erase_if(isd->sections, [&](InputSection *isec) {
- return spilledInputSections.contains(isec);
- });
- }
- }
- }
-
- return spilled;
-}
-
-// Erase any potential spill sections that were not used.
-void LinkerScript::erasePotentialSpillSections() {
- if (potentialSpillLists.empty())
- return;
-
- // Collect the set of input section descriptions that contain potential
- // spills.
- DenseSet<InputSectionDescription *> isds;
- for (const auto &[_, list] : potentialSpillLists)
- for (PotentialSpillSection *s = list.head; s; s = s->next)
- isds.insert(s->isd);
-
- for (InputSectionDescription *isd : isds)
- llvm::erase_if(isd->sections, [](InputSection *s) {
- return isa<PotentialSpillSection>(s);
- });
-
- potentialSpillLists.clear();
-}
-
// Creates program headers as instructed by PHDRS linker script command.
SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
SmallVector<PhdrEntry *, 0> ret;
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 734d4e7498aa2..b09cd12c46f99 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -10,7 +10,6 @@
#define LLD_ELF_LINKER_SCRIPT_H
#include "Config.h"
-#include "InputSection.h"
#include "Writer.h"
#include "lld/Common/LLVM.h"
#include "lld/Common/Strings.h"
@@ -288,8 +287,7 @@ class LinkerScript final {
SmallVector<InputSectionBase *, 0>
computeInputSections(const InputSectionDescription *,
- ArrayRef<InputSectionBase *>,
- const OutputSection &outCmd);
+ ArrayRef<InputSectionBase *>);
SmallVector<InputSectionBase *, 0> createInputSectionList(OutputSection &cmd);
@@ -335,8 +333,6 @@ class LinkerScript final {
bool shouldKeep(InputSectionBase *s);
const Defined *assignAddresses();
- bool spillSections();
- void erasePotentialSpillSections();
void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
void processSectionCommands();
void processSymbolAssignments();
@@ -404,15 +400,6 @@ class LinkerScript final {
//
// then provideMap should contain the mapping: 'v' -> ['a', 'b', 'c']
llvm::MapVector<StringRef, SmallVector<StringRef, 0>> provideMap;
-
- // List of potential spill locations (PotentialSpillSection) for an input
- // section.
- struct PotentialSpillList {
- // Never nullptr.
- PotentialSpillSection *head;
- PotentialSpillSection *tail;
- };
- llvm::DenseMap<InputSectionBase *, PotentialSpillList> potentialSpillLists;
};
struct ScriptWrapper {
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 883a6079bf507..b9e05a4b1fd5c 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -197,9 +197,6 @@ def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">;
def enable_new_dtags: F<"enable-new-dtags">,
HelpText<"Enable new dynamic tags (default)">;
-def enable_non_contiguous_regions : FF<"enable-non-contiguous-regions">,
- HelpText<"Spill input sections to later matching output sections to avoid memory region overflow">;
-
def end_group: F<"end-group">,
HelpText<"Ignored for compatibility with GNU unless you pass --warn-backrefs">;
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index fcb4c4387aa97..9c667241360f6 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -186,7 +186,7 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef name,
// new synthetic sections at the location of the first input section
// that it replaces. It then finalizes each synthetic section in order
// to compute an output offset for each piece of each input section.
-void OutputSection::finalizeInputSections(LinkerScript *script) {
+void OutputSection::finalizeInputSections() {
std::vector<MergeSyntheticSection *> mergeSections;
for (SectionCommand *cmd : commands) {
auto *isd = dyn_cast<InputSectionDescription>(cmd);
@@ -226,11 +226,6 @@ void OutputSection::finalizeInputSections(LinkerScript *script) {
i = std::prev(mergeSections.end());
syn->entsize = ms->entsize;
isd->sections.push_back(syn);
- // The merge synthetic section inherits the potential spill locations of
- // its first contained section.
- auto it = script->potentialSpillLists.find(ms);
- if (it != script->potentialSpillLists.end())
- script->potentialSpillLists.try_emplace(syn, it->second);
}
(*i)->addSection(ms);
}
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 78fede48a23f2..421a0181feb5d 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -75,7 +75,7 @@ class OutputSection final : public SectionBase {
void recordSection(InputSectionBase *isec);
void commitSection(InputSection *isec);
- void finalizeInputSections(LinkerScript *script = nullptr);
+ void finalizeInputSections();
// The following members are normally only used in linker scripts.
MemoryRegion *memRegion = nullptr;
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 298c714adb3b4..7b9ada40c0f67 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -4074,13 +4074,6 @@ static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
// InputSection with the highest address and any InputSections that have
// mergeable .ARM.exidx table entries are removed from it.
void ARMExidxSyntheticSection::finalizeContents() {
- // Ensure that any fixed-point iterations after the first see the original set
- // of sections.
- if (!originalExecutableSections.empty())
- executableSections = originalExecutableSections;
- else if (config->enableNonContiguousRegions)
- originalExecutableSections = executableSections;
-
// The executableSections and exidxSections that we use to derive the final
// contents of this SyntheticSection are populated before
// processSectionCommands() and ICF. A /DISCARD/ entry in SECTIONS command or
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 34949025a45f7..995fd4b344b07 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1255,10 +1255,6 @@ class ARMExidxSyntheticSection : public SyntheticSection {
// either find the .ARM.exidx section or know that we need to generate one.
SmallVector<InputSection *, 0> executableSections;
- // Value of executableSecitons before finalizeContents(), so that it can be
- /...
[truncated]
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Reverts #90007
Broke in merging I think.