8080#include " SymbolTable.h"
8181#include " Symbols.h"
8282#include " SyntheticSections.h"
83+ #include " llvm/ADT/EquivalenceClasses.h"
8384#include " llvm/BinaryFormat/ELF.h"
8485#include " llvm/Object/ELF.h"
8586#include " llvm/Support/Parallel.h"
@@ -558,7 +559,7 @@ template <class ELFT> void ICF<ELFT>::run() {
558559 return {ctx, ctx.arg .printIcfSections ? DiagLevel::Msg : DiagLevel::None};
559560 };
560561
561- DenseMap <Symbol *, Symbol *> symbolMap ;
562+ EquivalenceClasses <Symbol *> symbolEquivalence ;
562563 // Merge sections by the equivalence class.
563564 // Merge symbols identified as equivalent during ICF
564565 forEachClassRange (0 , sections.size (), [&](size_t begin, size_t end) {
@@ -577,14 +578,7 @@ template <class ELFT> void ICF<ELFT>::run() {
577578 if (syms[i] == replacedSyms[i] || !syms[i]->isGlobal () ||
578579 !replacedSyms[i]->isGlobal ())
579580 continue ;
580- auto [it, inserted] =
581- symbolMap.insert (std::make_pair (replacedSyms[i], syms[i]));
582- print () << " selected symbol: " << syms[i]->getName ().data ()
583- << " ; replaced symbol: " << replacedSyms[i]->getName ().data ();
584- if (!inserted) {
585- print () << " replacement already exists: "
586- << it->getSecond ()->getName ().data ();
587- }
581+ symbolEquivalence.unionSets (syms[i], replacedSyms[i]);
588582 }
589583
590584 // At this point we know sections merged are fully identical and hence
@@ -606,15 +600,23 @@ template <class ELFT> void ICF<ELFT>::run() {
606600 };
607601 for (Symbol *sym : ctx.symtab ->getSymbols ()) {
608602 fold (sym);
609- if (Symbol *s = symbolMap.lookup (sym))
610- ctx.symtab ->redirect (sym, s);
603+ auto it = symbolEquivalence.findLeader (sym);
604+ if (it != symbolEquivalence.member_end () && *it != sym) {
605+ print () << " Redirecting " << sym->getName () << " to " << (*it)->getName ();
606+ ctx.symtab ->redirect (sym, *it);
607+ }
611608 }
612609 parallelForEach (ctx.objectFiles , [&](ELFFileBase *file) {
613610 for (Symbol *sym : file->getLocalSymbols ())
614611 fold (sym);
615- for (Symbol *&sym : file->getMutableGlobalSymbols ())
616- if (Symbol *s = symbolMap.lookup (sym))
617- sym = s;
612+ for (Symbol *&sym : file->getMutableGlobalSymbols ()) {
613+ auto it = symbolEquivalence.findLeader (sym);
614+ if (it != symbolEquivalence.member_end () && *it != sym) {
615+ print () << " Redirecting " << sym->getName () << " to "
616+ << (*it)->getName ();
617+ sym = *it;
618+ }
619+ }
618620 });
619621
620622 // InputSectionDescription::sections is populated by processSectionCommands().
0 commit comments