Skip to content

Commit 7a5f2fb

Browse files
authored
Revert "[LLD] Implement --enable-non-contiguous-regions (#90007)"
This reverts commit 6731144.
1 parent 6731144 commit 7a5f2fb

17 files changed

+17
-600
lines changed

lld/ELF/Config.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ struct Config {
238238
bool emitLLVM;
239239
bool emitRelocs;
240240
bool enableNewDtags;
241-
bool enableNonContiguousRegions;
242241
bool executeOnly;
243242
bool exportDynamic;
244243
bool fixCortexA53Errata843419;

lld/ELF/Driver.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,8 +1250,6 @@ static void readConfigs(opt::InputArgList &args) {
12501250
config->emitRelocs = args.hasArg(OPT_emit_relocs);
12511251
config->enableNewDtags =
12521252
args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
1253-
config->enableNonContiguousRegions =
1254-
args.hasArg(OPT_enable_non_contiguous_regions);
12551253
config->entry = args.getLastArgValue(OPT_entry);
12561254

12571255
errorHandler().errorHandlingScript =
@@ -3087,7 +3085,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
30873085
// sectionBases.
30883086
for (SectionCommand *cmd : script->sectionCommands)
30893087
if (auto *osd = dyn_cast<OutputDesc>(cmd))
3090-
osd->osec.finalizeInputSections(script.get());
3088+
osd->osec.finalizeInputSections();
30913089
}
30923090

30933091
// Two input sections with different output sections should not be folded.

lld/ELF/InputSection.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ uint64_t SectionBase::getOffset(uint64_t offset) const {
161161
}
162162
case Regular:
163163
case Synthetic:
164-
case Spill:
165164
return cast<InputSection>(this)->outSecOff + offset;
166165
case EHFrame: {
167166
// 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 {
310309
.str();
311310
}
312311

313-
PotentialSpillSection::PotentialSpillSection(const InputSectionBase &source,
314-
InputSectionDescription &isd)
315-
: InputSection(source.file, source.flags, source.type, source.addralign, {},
316-
source.name, SectionBase::Spill),
317-
isd(&isd) {}
318-
319312
InputSection InputSection::discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
320313

321314
InputSection::InputSection(InputFile *f, uint64_t flags, uint32_t type,

lld/ELF/InputSection.h

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ template <class ELFT> struct RelsOrRelas {
4848
// sections.
4949
class SectionBase {
5050
public:
51-
enum Kind { Regular, Synthetic, Spill, EHFrame, Merge, Output };
51+
enum Kind { Regular, Synthetic, EHFrame, Merge, Output };
5252

5353
Kind kind() const { return (Kind)sectionKind; }
5454

@@ -382,8 +382,7 @@ class InputSection : public InputSectionBase {
382382

383383
static bool classof(const SectionBase *s) {
384384
return s->kind() == SectionBase::Regular ||
385-
s->kind() == SectionBase::Synthetic ||
386-
s->kind() == SectionBase::Spill;
385+
s->kind() == SectionBase::Synthetic;
387386
}
388387

389388
// Write this section to a mmap'ed file, assuming Buf is pointing to
@@ -426,26 +425,6 @@ class InputSection : public InputSectionBase {
426425
template <class ELFT> void copyShtGroup(uint8_t *buf);
427426
};
428427

429-
// A marker for a potential spill location for another input section. This
430-
// broadly acts as if it were the original section until address assignment.
431-
// Then it is either replaced with the real input section or removed.
432-
class PotentialSpillSection : public InputSection {
433-
public:
434-
// The containing input section description; used to quickly replace this stub
435-
// with the actual section.
436-
InputSectionDescription *isd;
437-
438-
// Next potential spill location for the same source input section.
439-
PotentialSpillSection *next = nullptr;
440-
441-
PotentialSpillSection(const InputSectionBase &source,
442-
InputSectionDescription &isd);
443-
444-
static bool classof(const SectionBase *sec) {
445-
return sec->kind() == InputSectionBase::Spill;
446-
}
447-
};
448-
449428
static_assert(sizeof(InputSection) <= 160, "InputSection is too big");
450429

451430
class SyntheticSection : public InputSection {

lld/ELF/LinkerScript.cpp

Lines changed: 7 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,6 @@ getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
304304
void LinkerScript::processInsertCommands() {
305305
SmallVector<OutputDesc *, 0> moves;
306306
for (const InsertCommand &cmd : insertCommands) {
307-
if (config->enableNonContiguousRegions)
308-
error("INSERT cannot be used with --enable-non-contiguous-regions");
309-
310307
for (StringRef name : cmd.names) {
311308
// If base is empty, it may have been discarded by
312309
// adjustOutputSections(). We do not handle such output sections.
@@ -489,12 +486,10 @@ static void sortInputSections(MutableArrayRef<InputSectionBase *> vec,
489486
// Compute and remember which sections the InputSectionDescription matches.
490487
SmallVector<InputSectionBase *, 0>
491488
LinkerScript::computeInputSections(const InputSectionDescription *cmd,
492-
ArrayRef<InputSectionBase *> sections,
493-
const OutputSection &outCmd) {
489+
ArrayRef<InputSectionBase *> sections) {
494490
SmallVector<InputSectionBase *, 0> ret;
495491
SmallVector<size_t, 0> indexes;
496492
DenseSet<size_t> seen;
497-
DenseSet<InputSectionBase *> spills;
498493
auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
499494
llvm::sort(MutableArrayRef<size_t>(indexes).slice(begin, end - begin));
500495
for (size_t i = begin; i != end; ++i)
@@ -510,10 +505,10 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
510505
size_t sizeBeforeCurrPat = ret.size();
511506

512507
for (size_t i = 0, e = sections.size(); i != e; ++i) {
513-
// Skip if the section is dead or has been matched by a previous pattern
514-
// in this input section description.
508+
// Skip if the section is dead or has been matched by a previous input
509+
// section description or a previous pattern.
515510
InputSectionBase *sec = sections[i];
516-
if (!sec->isLive() || seen.contains(i))
511+
if (!sec->isLive() || sec->parent || seen.contains(i))
517512
continue;
518513

519514
// For --emit-relocs we have to ignore entries like
@@ -534,29 +529,6 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
534529
(sec->flags & cmd->withoutFlags) != 0)
535530
continue;
536531

537-
if (sec->parent) {
538-
// Skip if not allowing multiple matches.
539-
if (!config->enableNonContiguousRegions)
540-
continue;
541-
542-
// Disallow spilling into /DISCARD/; special handling would be needed
543-
// for this in address assignment, and the semantics are nebulous.
544-
if (outCmd.name == "/DISCARD/")
545-
continue;
546-
547-
// Skip if the section's first match was /DISCARD/; such sections are
548-
// always discarded.
549-
if (sec->parent->name == "/DISCARD/")
550-
continue;
551-
552-
// Skip if the section was already matched by a different input section
553-
// description within this output section.
554-
if (sec->parent == &outCmd)
555-
continue;
556-
557-
spills.insert(sec);
558-
}
559-
560532
ret.push_back(sec);
561533
indexes.push_back(i);
562534
seen.insert(i);
@@ -583,30 +555,6 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
583555
// Matched sections after the last SORT* are sorted by (--sort-alignment,
584556
// input order).
585557
sortByPositionThenCommandLine(sizeAfterPrevSort, ret.size());
586-
587-
// The flag --enable-non-contiguous-regions may cause sections to match an
588-
// InputSectionDescription in more than one OutputSection. Matches after the
589-
// first were collected in the spills set, so replace these with potential
590-
// spill sections.
591-
if (!spills.empty()) {
592-
for (InputSectionBase *&sec : ret) {
593-
if (!spills.contains(sec))
594-
continue;
595-
596-
// Append the spill input section to the list for the input section,
597-
// creating it if necessary.
598-
PotentialSpillSection *pss = make<PotentialSpillSection>(
599-
*sec, const_cast<InputSectionDescription &>(*cmd));
600-
auto [it, inserted] =
601-
potentialSpillLists.try_emplace(sec, PotentialSpillList{pss, pss});
602-
if (!inserted) {
603-
PotentialSpillSection *&tail = it->second.tail;
604-
tail = tail->next = pss;
605-
}
606-
sec = pss;
607-
}
608-
}
609-
610558
return ret;
611559
}
612560

@@ -629,7 +577,7 @@ void LinkerScript::discardSynthetic(OutputSection &outCmd) {
629577
part.armExidx->exidxSections.end());
630578
for (SectionCommand *cmd : outCmd.commands)
631579
if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
632-
for (InputSectionBase *s : computeInputSections(isd, secs, outCmd))
580+
for (InputSectionBase *s : computeInputSections(isd, secs))
633581
discard(*s);
634582
}
635583
}
@@ -640,7 +588,7 @@ LinkerScript::createInputSectionList(OutputSection &outCmd) {
640588

641589
for (SectionCommand *cmd : outCmd.commands) {
642590
if (auto *isd = dyn_cast<InputSectionDescription>(cmd)) {
643-
isd->sectionBases = computeInputSections(isd, ctx.inputSections, outCmd);
591+
isd->sectionBases = computeInputSections(isd, ctx.inputSections);
644592
for (InputSectionBase *s : isd->sectionBases)
645593
s->parent = &outCmd;
646594
ret.insert(ret.end(), isd->sectionBases.begin(), isd->sectionBases.end());
@@ -696,9 +644,6 @@ void LinkerScript::processSectionCommands() {
696644

697645
// Process OVERWRITE_SECTIONS first so that it can overwrite the main script
698646
// or orphans.
699-
if (config->enableNonContiguousRegions && !overwriteSections.empty())
700-
error("OVERWRITE_SECTIONS cannot be used with "
701-
"--enable-non-contiguous-regions");
702647
DenseMap<CachedHashStringRef, OutputDesc *> map;
703648
size_t i = 0;
704649
for (OutputDesc *osd : overwriteSections) {
@@ -1121,12 +1066,8 @@ void LinkerScript::assignOffsets(OutputSection *sec) {
11211066
// Handle a single input section description command.
11221067
// It calculates and assigns the offsets for each section and also
11231068
// updates the output section size.
1124-
1125-
auto &sections = cast<InputSectionDescription>(cmd)->sections;
1126-
for (InputSection *isec : sections) {
1069+
for (InputSection *isec : cast<InputSectionDescription>(cmd)->sections) {
11271070
assert(isec->getParent() == sec);
1128-
if (isa<PotentialSpillSection>(isec))
1129-
continue;
11301071
const uint64_t pos = dot;
11311072
dot = alignToPowerOf2(dot, isec->addralign);
11321073
isec->outSecOff = dot - sec->addr;
@@ -1423,114 +1364,6 @@ const Defined *LinkerScript::assignAddresses() {
14231364
return getChangedSymbolAssignment(oldValues);
14241365
}
14251366

1426-
static bool hasRegionOverflowed(MemoryRegion *mr) {
1427-
if (!mr)
1428-
return false;
1429-
return mr->curPos - mr->getOrigin() > mr->getLength();
1430-
}
1431-
1432-
// Spill input sections in reverse order of address assignment to (potentially)
1433-
// bring memory regions out of overflow. The size savings of a spill can only be
1434-
// estimated, since general linker script arithmetic may occur afterwards.
1435-
// Under-estimates may cause unnecessary spills, but over-estimates can always
1436-
// be corrected on the next pass.
1437-
bool LinkerScript::spillSections() {
1438-
if (!config->enableNonContiguousRegions)
1439-
return false;
1440-
1441-
bool spilled = false;
1442-
for (SectionCommand *cmd : reverse(sectionCommands)) {
1443-
auto *od = dyn_cast<OutputDesc>(cmd);
1444-
if (!od)
1445-
continue;
1446-
OutputSection *osec = &od->osec;
1447-
if (!osec->memRegion)
1448-
continue;
1449-
1450-
// Input sections that have replaced a potential spill and should be removed
1451-
// from their input section description.
1452-
DenseSet<InputSection *> spilledInputSections;
1453-
1454-
for (SectionCommand *cmd : reverse(osec->commands)) {
1455-
if (!hasRegionOverflowed(osec->memRegion) &&
1456-
!hasRegionOverflowed(osec->lmaRegion))
1457-
break;
1458-
1459-
auto *isd = dyn_cast<InputSectionDescription>(cmd);
1460-
if (!isd)
1461-
continue;
1462-
for (InputSection *isec : reverse(isd->sections)) {
1463-
// Potential spill locations cannot be spilled.
1464-
if (isa<PotentialSpillSection>(isec))
1465-
continue;
1466-
1467-
// Find the next potential spill location and remove it from the list.
1468-
auto it = potentialSpillLists.find(isec);
1469-
if (it == potentialSpillLists.end())
1470-
continue;
1471-
PotentialSpillList &list = it->second;
1472-
PotentialSpillSection *spill = list.head;
1473-
if (spill->next)
1474-
list.head = spill->next;
1475-
else
1476-
potentialSpillLists.erase(isec);
1477-
1478-
// Replace the next spill location with the spilled section and adjust
1479-
// its properties to match the new location. Note that the alignment of
1480-
// the spill section may have diverged from the original due to e.g. a
1481-
// SUBALIGN. Correct assignment requires the spill's alignment to be
1482-
// used, not the original.
1483-
spilledInputSections.insert(isec);
1484-
*llvm::find(spill->isd->sections, spill) = isec;
1485-
isec->parent = spill->parent;
1486-
isec->addralign = spill->addralign;
1487-
1488-
// Record the (potential) reduction in the region's end position.
1489-
osec->memRegion->curPos -= isec->getSize();
1490-
if (osec->lmaRegion)
1491-
osec->lmaRegion->curPos -= isec->getSize();
1492-
1493-
// Spilling continues until the end position no longer overflows the
1494-
// region. Then, another round of address assignment will either confirm
1495-
// the spill's success or lead to yet more spilling.
1496-
if (!hasRegionOverflowed(osec->memRegion) &&
1497-
!hasRegionOverflowed(osec->lmaRegion))
1498-
break;
1499-
}
1500-
1501-
// Remove any spilled input sections to complete their move.
1502-
if (!spilledInputSections.empty()) {
1503-
spilled = true;
1504-
llvm::erase_if(isd->sections, [&](InputSection *isec) {
1505-
return spilledInputSections.contains(isec);
1506-
});
1507-
}
1508-
}
1509-
}
1510-
1511-
return spilled;
1512-
}
1513-
1514-
// Erase any potential spill sections that were not used.
1515-
void LinkerScript::erasePotentialSpillSections() {
1516-
if (potentialSpillLists.empty())
1517-
return;
1518-
1519-
// Collect the set of input section descriptions that contain potential
1520-
// spills.
1521-
DenseSet<InputSectionDescription *> isds;
1522-
for (const auto &[_, list] : potentialSpillLists)
1523-
for (PotentialSpillSection *s = list.head; s; s = s->next)
1524-
isds.insert(s->isd);
1525-
1526-
for (InputSectionDescription *isd : isds)
1527-
llvm::erase_if(isd->sections, [](InputSection *s) {
1528-
return isa<PotentialSpillSection>(s);
1529-
});
1530-
1531-
potentialSpillLists.clear();
1532-
}
1533-
15341367
// Creates program headers as instructed by PHDRS linker script command.
15351368
SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
15361369
SmallVector<PhdrEntry *, 0> ret;

lld/ELF/LinkerScript.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#define LLD_ELF_LINKER_SCRIPT_H
1111

1212
#include "Config.h"
13-
#include "InputSection.h"
1413
#include "Writer.h"
1514
#include "lld/Common/LLVM.h"
1615
#include "lld/Common/Strings.h"
@@ -288,8 +287,7 @@ class LinkerScript final {
288287

289288
SmallVector<InputSectionBase *, 0>
290289
computeInputSections(const InputSectionDescription *,
291-
ArrayRef<InputSectionBase *>,
292-
const OutputSection &outCmd);
290+
ArrayRef<InputSectionBase *>);
293291

294292
SmallVector<InputSectionBase *, 0> createInputSectionList(OutputSection &cmd);
295293

@@ -335,8 +333,6 @@ class LinkerScript final {
335333

336334
bool shouldKeep(InputSectionBase *s);
337335
const Defined *assignAddresses();
338-
bool spillSections();
339-
void erasePotentialSpillSections();
340336
void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
341337
void processSectionCommands();
342338
void processSymbolAssignments();
@@ -404,15 +400,6 @@ class LinkerScript final {
404400
//
405401
// then provideMap should contain the mapping: 'v' -> ['a', 'b', 'c']
406402
llvm::MapVector<StringRef, SmallVector<StringRef, 0>> provideMap;
407-
408-
// List of potential spill locations (PotentialSpillSection) for an input
409-
// section.
410-
struct PotentialSpillList {
411-
// Never nullptr.
412-
PotentialSpillSection *head;
413-
PotentialSpillSection *tail;
414-
};
415-
llvm::DenseMap<InputSectionBase *, PotentialSpillList> potentialSpillLists;
416403
};
417404

418405
struct ScriptWrapper {

0 commit comments

Comments
 (0)