[clang] [lld] [lld-macho][draft]Allow folding entries with identical FDE (PR #216895)

Ellis Hoag via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 18 10:27:14 PDT 2026


================
@@ -613,32 +638,33 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
       for (Defined *d : isec->symbols)
         if (d->unwindEntry())
           foldable.push_back(d->unwindEntry());
-
-      // Some sections have embedded addends that foil ICF's hashing / equality
-      // checks. (We can ignore embedded addends when doing ICF because the same
-      // information gets recorded in our Reloc structs.) We therefore create a
-      // mutable copy of the section data and zero out the embedded addends
-      // before performing any hashing / equality checks.
-      if (isFoldableWithAddendsRemoved) {
-        // We have to do this copying serially as the BumpPtrAllocator is not
-        // thread-safe. FIXME: Make a thread-safe allocator.
-        MutableArrayRef<uint8_t> copy = isec->data.copy(bAlloc());
-        for (const Relocation &r : isec->relocs)
-          target->relocateOne(copy.data() + r.offset, r, /*va=*/0,
-                              /*relocVA=*/0);
-        isec->data = copy;
-      }
-    } else if (!isEhFrameSection(isec)) {
-      // EH frames are gathered as foldables from unwindEntry above; give a
-      // unique ID to everything else.
+    } else if (isEhFrameSection(isec)) {
+      // __eh_frame contains two types of records: FDEs and CIEs.
+      // Functions point to FDEs, which are already collected above via unwindEntry().
+      // CIEs are shared headers and are not attached to individual functions.
+      // Collect only CIEs here so they can also be hashed and deduplicated.
+      auto *obj = dyn_cast_or_null<ObjFile>(isec->getFile());
+      if (!onlyCfStrings && obj && !obj->fdes.contains(isec) &&
+          !isec->shouldOmitFromOutput())
+        foldable.push_back(isec);
+    } else {
+      // Give a unique ID to everything else.
       isec->icfEqClass[0] = ++icfUniqueID;
     }
   }
   parallelForEach(foldable, [](ConcatInputSection *isec) {
     assert(isec->icfEqClass[0] == 0); // don't overwrite a unique ID!
+    uint64_t hash;
+    if (isFoldableWithAddendsRemoved(isec)) {
+      SmallVector<uint8_t, 64> stackBuf;
----------------
ellishg wrote:

So it looks like you can avoid `bAlloc()` by allocating the section data on the stack. Neat! But if the section size is larger than 64 bytes, then we will have a heap allocation, right? Do we know that these sections are this small in practice? 

https://github.com/llvm/llvm-project/pull/216895


More information about the cfe-commits mailing list