COFF: Use section content checksum for ICF.

Previously, we calculated our own hash values for section contents.
Of coruse that's slow because we had to access all bytes in sections.
Fortunately, COFF objects usually contain hash values for COMDAT
sections. We can use that to speed up Identical COMDAT Folding.

llvm-svn: 246869
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index dc6de56..e5f5289 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -183,6 +183,10 @@
   // and this chunk is considrered as dead.
   SectionChunk *Ptr;
 
+  // The CRC of the contents as described in the COFF spec 4.5.5.
+  // Auxiliary Format 5: Section Definitions. Used for ICF.
+  uint32_t Checksum = 0;
+
 private:
   ArrayRef<uint8_t> getContents() const;
 
diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp
index 4ec8f68..1c23722 100644
--- a/lld/COFF/ICF.cpp
+++ b/lld/COFF/ICF.cpp
@@ -44,7 +44,7 @@
                       NumRelocs,
                       uint32_t(Header->SizeOfRawData),
                       std::distance(Relocs.end(), Relocs.begin()),
-                      hash_combine_range(A.data(), A.data() + A.size()));
+                      Checksum);
 }
 
 // Returns true if this and a given chunk are identical COMDAT sections.
@@ -58,6 +58,8 @@
     return false;
   if (NumRelocs != X->NumRelocs)
     return false;
+  if (Checksum != X->Checksum)
+    return false;
 
   // Compare data
   if (getContents() != X->getContents())
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index a8a35a5..a8537ec 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -225,13 +225,14 @@
   if (!SC)
     return nullptr;
 
-  // Handle associative sections
+  // Handle section definitions
   if (IsFirst && AuxP) {
     auto *Aux = reinterpret_cast<const coff_aux_section_definition *>(AuxP);
     if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
       if (auto *ParentSC = cast_or_null<SectionChunk>(
               SparseChunks[Aux->getNumber(Sym.isBigObj())]))
         ParentSC->addAssociative(SC);
+    SC->Checksum = Aux->CheckSum;
   }
 
   auto *B = new (Alloc) DefinedRegular(this, Sym, SC);