From d7dc225888b7f6925099cdb0fe4da77a62dd74d4 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 10 May 2017 19:13:38 +0000 Subject: [PATCH] Use a DenseMap in LinkerScript::getCmd. This improves many-sections.s with a linker script from 22s to 0.9s. llvm-svn: 302708 --- lld/ELF/LinkerScript.cpp | 16 ++++++++++------ lld/ELF/LinkerScript.h | 3 ++- lld/test/ELF/many-sections.s | 5 +++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 3277e65..161909a 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -415,6 +415,7 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { if (OutputSection *Sec = Cmd->Sec) { assert(Sec->SectionIndex == INT_MAX); Sec->SectionIndex = I; + SecToCommand[Sec] = Cmd; } } } @@ -444,6 +445,7 @@ void LinkerScript::fabricateDefaultCommands() { auto *OSCmd = make(Sec->Name); OSCmd->Sec = Sec; + SecToCommand[Sec] = OSCmd; // Prefer user supplied address over additional alignment constraint auto I = Config->SectionStartMap.find(Sec->Name); @@ -488,6 +490,7 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { auto *Cmd = cast(*I); Factory.addInputSec(S, Name, Cmd->Sec); if (OutputSection *Sec = Cmd->Sec) { + SecToCommand[Sec] = Cmd; unsigned Index = std::distance(Opt.Commands.begin(), I); assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index); Sec->SectionIndex = Index; @@ -703,6 +706,7 @@ void LinkerScript::adjustSectionsBeforeSorting() { OutSec->SectionIndex = I; OutputSections->push_back(OutSec); Cmd->Sec = OutSec; + SecToCommand[OutSec] = Cmd; } } @@ -833,6 +837,7 @@ void LinkerScript::placeOrphanSections() { ++CmdIndex; Cmd->Sec = Sec; + SecToCommand[Sec] = Cmd; auto *ISD = make(""); for (InputSection *IS : Sec->Sections) ISD->Sections.push_back(IS); @@ -1025,12 +1030,11 @@ bool LinkerScript::ignoreInterpSection() { return true; } -OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) { - for (BaseCommand *Base : Opt.Commands) - if (auto *Cmd = dyn_cast(Base)) - if (Cmd->Sec == Sec) - return Cmd; - return nullptr; +OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const { + auto I = SecToCommand.find(Sec); + if (I == SecToCommand.end()) + return nullptr; + return I->second; } Optional LinkerScript::getFiller(OutputSection *Sec) { diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index ef7ecba..d0a4d83 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -212,7 +212,8 @@ struct ScriptConfiguration { }; class LinkerScript final { - OutputSectionCommand *getCmd(OutputSection *Sec); + llvm::DenseMap SecToCommand; + OutputSectionCommand *getCmd(OutputSection *Sec) const; void assignSymbol(SymbolAssignment *Cmd, bool InSec); void setDot(Expr E, const Twine &Loc, bool InSec); diff --git a/lld/test/ELF/many-sections.s b/lld/test/ELF/many-sections.s index 77e76c2..ae82868 100644 --- a/lld/test/ELF/many-sections.s +++ b/lld/test/ELF/many-sections.s @@ -14,6 +14,11 @@ // RUN: ld.lld %t -o %t2 // RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s +// Test also with a linker script. +// RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script +// RUN: ld.lld -T %t.script %t -o %t2 +// RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s + // Test that _start is in the correct section. // LINKED: Name: _start // LINKED-NEXT: Value: 0x0 -- 2.7.4