Delete LinkerScript::getSectionIndex.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 5 May 2017 21:34:26 +0000 (21:34 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 5 May 2017 21:34:26 +0000 (21:34 +0000)
We can set SectionIndex tentatively as we process the linker script
instead of looking it repeatedly.

In general we should try to have as few name lookups as possible.

llvm-svn: 302299

lld/ELF/LinkerScript.cpp
lld/ELF/LinkerScript.h
lld/ELF/OutputSections.cpp
lld/ELF/Writer.cpp

index 2620e69..d9adc60 100644 (file)
@@ -415,6 +415,10 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) {
         cast<InputSection>(S)->OutSecOff = Pos++;
         Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
       }
+      if (OutputSection *Sec = Cmd->Sec) {
+        assert(Sec->SectionIndex == INT_MAX);
+        Sec->SectionIndex = I;
+      }
     }
   }
   CurOutSec = nullptr;
@@ -486,6 +490,11 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
     } else {
       auto *Cmd = cast<OutputSectionCommand>(*I);
       Factory.addInputSec(S, Name, Cmd->Sec);
+      if (OutputSection *Sec = Cmd->Sec) {
+        unsigned Index = std::distance(Opt.Commands.begin(), I);
+        assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
+        Sec->SectionIndex = Index;
+      }
       auto *ISD = make<InputSectionDescription>("");
       ISD->Sections.push_back(S);
       Cmd->Commands.push_back(ISD);
@@ -674,8 +683,9 @@ void LinkerScript::adjustSectionsBeforeSorting() {
   // consequeces and gives us a section to put the symbol in.
   uint64_t Flags = SHF_ALLOC;
   uint32_t Type = SHT_PROGBITS;
-  for (BaseCommand *Base : Opt.Commands) {
-    auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
+
+  for (int I = 0, E = Opt.Commands.size(); I != E; ++I) {
+    auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
     if (!Cmd)
       continue;
     if (OutputSection *Sec = Cmd->Sec) {
@@ -688,6 +698,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
       continue;
 
     auto *OutSec = make<OutputSection>(Cmd->Name, Type, Flags);
+    OutSec->SectionIndex = I;
     OutputSections->push_back(OutSec);
     Cmd->Sec = OutSec;
   }
@@ -1032,12 +1043,17 @@ static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
     llvm_unreachable("unsupported Size argument");
 }
 
-void LinkerScript::writeDataBytes(StringRef Name, uint8_t *Buf) {
-  int I = getSectionIndex(Name);
-  if (I == INT_MAX)
+void LinkerScript::writeDataBytes(OutputSection *Sec, uint8_t *Buf) {
+  auto I = std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
+                        [=](BaseCommand *Base) {
+                          if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
+                            if (Cmd->Sec == Sec)
+                              return true;
+                          return false;
+                        });
+  if (I == Opt.Commands.end())
     return;
-
-  auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
+  auto *Cmd = cast<OutputSectionCommand>(*I);
   for (BaseCommand *Base : Cmd->Commands)
     if (auto *Data = dyn_cast<BytesDataCommand>(Base))
       writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
@@ -1051,18 +1067,6 @@ bool LinkerScript::hasLMA(StringRef Name) {
   return false;
 }
 
-// Returns the index of the given section name in linker script
-// SECTIONS commands. Sections are laid out as the same order as they
-// were in the script. If a given name did not appear in the script,
-// it returns INT_MAX, so that it will be laid out at end of file.
-int LinkerScript::getSectionIndex(StringRef Name) {
-  for (int I = 0, E = Opt.Commands.size(); I != E; ++I)
-    if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]))
-      if (Cmd->Name == Name)
-        return I;
-  return INT_MAX;
-}
-
 ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
   if (S == ".")
     return {CurOutSec, Dot - CurOutSec->Addr};
index 9404f49..7bcd21c 100644 (file)
@@ -270,9 +270,8 @@ public:
   void processNonSectionCommands();
   void synchronize();
   void assignAddresses(std::vector<PhdrEntry> &Phdrs);
-  int getSectionIndex(StringRef Name);
 
-  void writeDataBytes(StringRef Name, uint8_t *Buf);
+  void writeDataBytes(OutputSection *Sec, uint8_t *Buf);
   void addSymbol(SymbolAssignment *Cmd);
   void processCommands(OutputSectionFactory &Factory);
 
index 839f68f..40d5820 100644 (file)
@@ -68,7 +68,8 @@ void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) {
 OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
     : SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type,
                   /*Info*/ 0,
-                  /*Link*/ 0) {}
+                  /*Link*/ 0),
+      SectionIndex(INT_MAX) {}
 
 static bool compareByFilePosition(InputSection *A, InputSection *B) {
   // Synthetic doesn't have link order dependecy, stable_sort will keep it last
@@ -305,7 +306,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
 
   // Linker scripts may have BYTE()-family commands with which you
   // can write arbitrary bytes to the output. Process them if any.
-  Script->writeDataBytes(Name, Buf);
+  Script->writeDataBytes(this, Buf);
 }
 
 static uint64_t getOutFlags(InputSectionBase *S) {
index d78705a..7f00e37 100644 (file)
@@ -745,15 +745,12 @@ static bool compareSectionsNonScript(const OutputSection *A,
 // Output section ordering is determined by this function.
 template <class ELFT>
 static bool compareSections(const OutputSection *A, const OutputSection *B) {
-  // For now, put sections mentioned in a linker script first.
-  int AIndex = Script->getSectionIndex(A->Name);
-  int BIndex = Script->getSectionIndex(B->Name);
-  bool AInScript = AIndex != INT_MAX;
-  bool BInScript = BIndex != INT_MAX;
-  if (AInScript != BInScript)
-    return AInScript;
-  // If both are in the script, use that order.
-  if (AInScript)
+  // For now, put sections mentioned in a linker script
+  // first. Sections not on linker script will have a SectionIndex of
+  // INT_MAX.
+  int AIndex = A->SectionIndex;
+  int BIndex = B->SectionIndex;
+  if (AIndex != BIndex)
     return AIndex < BIndex;
 
   return compareSectionsNonScript<ELFT>(A, B);
@@ -1019,9 +1016,8 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
   auto I = OutputSections.begin();
   auto E = OutputSections.end();
   auto NonScriptI =
-      std::find_if(OutputSections.begin(), E, [](OutputSection *S) {
-        return Script->getSectionIndex(S->Name) == INT_MAX;
-      });
+      std::find_if(OutputSections.begin(), E,
+                   [](OutputSection *S) { return S->SectionIndex == INT_MAX; });
   while (NonScriptI != E) {
     auto BestPos = std::max_element(
         I, NonScriptI, [&](OutputSection *&A, OutputSection *&B) {