[lld] [lld-macho][arm64] Enhance safe ICF with thunk-based deduplication (PR #106573)

Kyungwoo Lee via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 4 00:44:00 PDT 2024


================
@@ -251,6 +252,74 @@ void ICF::forEachClassRange(size_t begin, size_t end,
   }
 }
 
+// Given a range of identical icfInputs, replace address significant functions
+// with a thunk that is just a direct branch to the first function in the
+// series. This way we keep only one main body of the function but we still
+// retain the address uniqueness of relevant functions by having them be a
+// direct branch thunk rather than containing a full copy of the actual function
+// body.
+void ICF::applySafeThunksToRange(size_t begin, size_t end) {
+  // If the functions we're dealing with are smaller than the thunk size, then
+  // just leave them all as-is - creating thunks would be a net loss.
+  uint32_t thunkSize = target->getICFSafeThunkSize();
+  if (icfInputs[begin]->data.size() <= thunkSize)
+    return;
+
+  // The standard ICF algorithm will merge all functions in the [begin + 1, end)
+  // range into icfInputs[begin].So, the body of the first function is always
+  // kept, even if it is not keepUnique. To make safe_thunks nicely play with
+  // this behavior, we ensure that the first function in the range is
+  // keepUnique.
+  if (!icfInputs[begin]->keepUnique) {
+    bool haveKeepUnique = false;
+    for (size_t i = begin + 1; i < end; ++i) {
+      if (icfInputs[i]->keepUnique) {
+        std::swap(icfInputs[begin], icfInputs[i]);
+        haveKeepUnique = true;
+        break;
+      }
+    }
+    // If we don't have keepUnique funcs, we can just return
+    if (!haveKeepUnique)
+      return;
+  }
+
+  // When creating a unique ICF thunk, use the first section as the section that
+  // all thunks will branch to.
+  ConcatInputSection *masterIsec = icfInputs[begin];
+
+  static std::mutex thunkInsertionMutex;
+  for (size_t i = begin + 1; i < end; ++i) {
+    ConcatInputSection *isec = icfInputs[i];
+    if (!isec->keepUnique)
+      continue;
----------------
kyulee-com wrote:

Once it's already sorted (mentioned earlier) to iterate `keepUnique` first, you can `break` instead of `continue`.

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


More information about the llvm-commits mailing list