COFF: Cache raw pointers to relocation tables.

Getting an iterator to the relocation table is very hot operation
in the linker. We do that not only to apply relocations but also
to mark live sections and to do ICF.

libObject's interface is slow. By caching pointers to the first
relocation table entries makes the linker 6% faster to self-link.

We probably need to fix libObject as well.

llvm-svn: 240603
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 84854ab..9ee6846 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -58,10 +58,8 @@
   memcpy(Buf + FileOff, Data.data(), Data.size());
 
   // Apply relocations.
-  for (const auto &I : getSectionRef().relocations()) {
-    const coff_relocation *Rel = File->getCOFFObj()->getCOFFRelocation(I);
+  for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E; ++Rel)
     applyReloc(Buf, Rel);
-  }
 }
 
 void SectionChunk::mark() {
@@ -69,8 +67,8 @@
   Live = true;
 
   // Mark all symbols listed in the relocation table for this section.
-  for (const auto &I : getSectionRef().relocations()) {
-    const coff_relocation *Rel = File->getCOFFObj()->getCOFFRelocation(I);
+  for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E;
+       ++Rel) {
     SymbolBody *B = File->getSymbolBody(Rel->SymbolTableIndex);
     if (auto *Def = dyn_cast<Defined>(B))
       Def->markLive();
@@ -120,11 +118,11 @@
 // which need to be fixed by the loader if load-time relocation is needed.
 // Only called when base relocation is enabled.
 void SectionChunk::getBaserels(std::vector<uint32_t> *Res, Defined *ImageBase) {
-  for (const auto &I : getSectionRef().relocations()) {
+  for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E;
+       ++Rel) {
     // ADDR64 relocations contain absolute addresses.
     // Symbol __ImageBase is special -- it's an absolute symbol, but its
     // address never changes even if image is relocated.
-    const coff_relocation *Rel = File->getCOFFObj()->getCOFFRelocation(I);
     if (Rel->Type != IMAGE_REL_AMD64_ADDR64)
       continue;
     SymbolBody *Body = File->getSymbolBody(Rel->SymbolTableIndex);
@@ -156,12 +154,6 @@
   }
 }
 
-SectionRef SectionChunk::getSectionRef() const {
-  DataRefImpl Ref;
-  Ref.p = uintptr_t(Header);
-  return SectionRef(Ref, File->getCOFFObj());
-}
-
 StringRef SectionChunk::getDebugName() {
   return Sym->getName();
 }
@@ -196,12 +188,10 @@
     return false;
 
   // Compare relocations
-  auto Range1 = getSectionRef().relocations();
-  auto Range2 = X->getSectionRef().relocations();
-  auto End = Range1.end();
-  for (auto I = Range1.begin(), J = Range2.begin(); I != End; ++I, ++J) {
-    const coff_relocation *Rel1 = File->getCOFFObj()->getCOFFRelocation(*I);
-    const coff_relocation *Rel2 = X->File->getCOFFObj()->getCOFFRelocation(*J);
+  const coff_relocation *Rel1 = relBegin();
+  const coff_relocation *End = relEnd();
+  const coff_relocation *Rel2 = X->relBegin();
+  for (; Rel1 != End; ++Rel1, ++Rel2) {
     if (Rel1->Type != Rel2->Type)
       return false;
     if (Rel1->VirtualAddress != Rel2->VirtualAddress)
@@ -230,6 +220,22 @@
   Live = false;
 }
 
+const coff_relocation *SectionChunk::relBegin() const {
+  if (!Reloc) {
+    DataRefImpl Ref;
+    Ref.p = uintptr_t(Header);
+    SectionRef Sref(Ref, File->getCOFFObj());
+    relocation_iterator It = Sref.relocation_begin();
+    Reloc = File->getCOFFObj()->getCOFFRelocation(*It);
+  }
+  return Reloc;
+}
+
+const coff_relocation *SectionChunk::relEnd() const {
+  const coff_relocation *I = relBegin();
+  return I + Header->NumberOfRelocations;
+}
+
 CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
   // Common symbols are aligned on natural boundaries up to 32 bytes.
   // This is what MSVC link.exe does.