Index: wasm/InputChunks.h =================================================================== --- wasm/InputChunks.h +++ wasm/InputChunks.h @@ -56,8 +56,9 @@ ArrayRef getRelocations() const { return Relocations; } - virtual StringRef getComdat() const = 0; virtual StringRef getName() const = 0; + virtual uint32_t getComdat() const = 0; + StringRef getComdatName() const; size_t NumRelocations() const { return Relocations.size(); } void writeRelocations(llvm::raw_ostream &OS) const; @@ -98,7 +99,7 @@ uint32_t getAlignment() const { return Segment.Data.Alignment; } StringRef getName() const override { return Segment.Data.Name; } - StringRef getComdat() const override { return Segment.Data.Comdat; } + uint32_t getComdat() const override { return Segment.Data.Comdat; } const OutputSegment *OutputSeg = nullptr; int32_t OutputSegmentOffset = 0; @@ -125,7 +126,7 @@ } StringRef getName() const override { return Function->Name; } - StringRef getComdat() const override { return Function->Comdat; } + uint32_t getComdat() const override { return Function->Comdat; } uint32_t getOutputIndex() const { return OutputIndex.getValue(); } bool hasOutputIndex() const { return OutputIndex.hasValue(); } void setOutputIndex(uint32_t Index); @@ -161,7 +162,7 @@ } StringRef getName() const override { return Name; } - StringRef getComdat() const override { return StringRef(); } + uint32_t getComdat() const override { return UINT32_MAX; } void setBody(ArrayRef Body_) { Body = Body_; } Index: wasm/InputChunks.cpp =================================================================== --- wasm/InputChunks.cpp +++ wasm/InputChunks.cpp @@ -27,6 +27,13 @@ return (toString(C->File) + ":(" + C->getName() + ")").str(); } +StringRef InputChunk::getComdatName() const { + uint32_t Index = getComdat(); + if (Index == UINT32_MAX) + return StringRef(); + return File->getWasmObj()->linkingData().Comdats[Index]; +} + void InputChunk::copyRelocations(const WasmSection &Section) { if (Section.Relocations.empty()) return; Index: wasm/InputFiles.h =================================================================== --- wasm/InputFiles.h +++ wasm/InputFiles.h @@ -100,6 +100,7 @@ std::vector TypeMap; std::vector TypeIsUsed; + std::vector UsedComdats; std::vector Segments; std::vector Functions; std::vector Globals; Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -111,6 +111,11 @@ TypeMap.resize(getWasmObj()->types().size()); TypeIsUsed.resize(getWasmObj()->types().size(), false); + ArrayRef Comdats = WasmObj->linkingData().Comdats; + UsedComdats.resize(Comdats.size()); + for (unsigned I = 0; I < Comdats.size(); ++I) + UsedComdats[I] = Symtab->addComdat(Comdats[I]); + // Populate `Segments`. for (const WasmSegment &S : WasmObj->dataSegments()) { InputSegment *Seg = make(S, this); @@ -147,10 +152,10 @@ } bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const { - StringRef S = Chunk->getComdat(); - if (S.empty()) + uint32_t C = Chunk->getComdat(); + if (C == UINT32_MAX) return false; - return !Symtab->addComdat(S, this); + return !UsedComdats[C]; } FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t Index) const { Index: wasm/SymbolTable.h =================================================================== --- wasm/SymbolTable.h +++ wasm/SymbolTable.h @@ -13,7 +13,7 @@ #include "InputFiles.h" #include "Symbols.h" #include "llvm/ADT/CachedHashString.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/Support/raw_ostream.h" using llvm::wasm::WasmGlobalType; @@ -65,7 +65,7 @@ void addLazy(ArchiveFile *F, const Archive::Symbol *Sym); - bool addComdat(StringRef Name, const ObjFile *File); + bool addComdat(StringRef Name); DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags); DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags, @@ -79,7 +79,7 @@ llvm::DenseMap SymMap; std::vector SymVector; - llvm::DenseMap Comdats; + llvm::DenseSet Comdats; }; extern SymbolTable *Symtab; Index: wasm/SymbolTable.cpp =================================================================== --- wasm/SymbolTable.cpp +++ wasm/SymbolTable.cpp @@ -304,6 +304,6 @@ } } -bool SymbolTable::addComdat(StringRef Name, const ObjFile *File) { - return Comdats.insert({Name, File}).first->second == File; +bool SymbolTable::addComdat(StringRef Name) { + return Comdats.insert(CachedHashStringRef(Name)).second; } Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -478,7 +478,7 @@ std::map> Comdats; for (const InputFunction *F : InputFunctions) { - StringRef Comdat = F->getComdat(); + StringRef Comdat = F->getComdatName(); if (!Comdat.empty()) Comdats[Comdat].emplace_back( ComdatEntry{WASM_COMDAT_FUNCTION, F->getOutputIndex()}); @@ -487,10 +487,10 @@ const auto &InputSegments = Segments[I]->InputSegments; if (InputSegments.empty()) continue; - StringRef Comdat = InputSegments[0]->getComdat(); + StringRef Comdat = InputSegments[0]->getComdatName(); #ifndef NDEBUG for (const InputSegment *IS : InputSegments) - assert(IS->getComdat() == Comdat); + assert(IS->getComdatName() == Comdat); #endif if (!Comdat.empty()) Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I});