Index: llvm/trunk/include/llvm/Transforms/Instrumentation.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Instrumentation.h +++ llvm/trunk/include/llvm/Transforms/Instrumentation.h @@ -27,6 +27,7 @@ class FunctionPass; class ModulePass; class OptimizationRemarkEmitter; +class Comdat; /// Instrumentation passes often insert conditional checks into entry blocks. /// Call this function before splitting the entry block to move instructions @@ -41,6 +42,11 @@ bool AllowMerging, const char *NamePrefix = ""); +// Returns F.getComdat() if it exists. +// Otherwise creates a new comdat, sets F's comdat, and returns it. +// Returns nullptr on failure. +Comdat *GetOrCreateFunctionComdat(Function &F, const std::string &ModuleId); + // Insert GCOV profiling instrumentation struct GCOVOptions { static GCOVOptions getDefault(); Index: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -70,6 +70,21 @@ return GV; } +Comdat *llvm::GetOrCreateFunctionComdat(Function &F, + const std::string &ModuleId) { + if (auto Comdat = F.getComdat()) return Comdat; + assert(F.hasName()); + Module *M = F.getParent(); + std::string Name = F.getName(); + if (F.hasLocalLinkage()) { + if (ModuleId.empty()) + return nullptr; + Name += ModuleId; + } + F.setComdat(M->getOrInsertComdat(Name)); + return F.getComdat(); +} + /// initializeInstrumentation - Initialize all passes in the TransformUtils /// library. void llvm::initializeInstrumentation(PassRegistry &Registry) { Index: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -220,8 +220,6 @@ MDNode::get(*C, None)); } - Comdat *GetOrCreateFunctionComdat(Function &F); - std::string getSectionName(const std::string &Section) const; std::string getSectionStart(const std::string &Section) const; std::string getSectionEnd(const std::string &Section) const; @@ -590,28 +588,16 @@ return true; } -Comdat *SanitizerCoverageModule::GetOrCreateFunctionComdat(Function &F) { - if (auto Comdat = F.getComdat()) return Comdat; - if (!TargetTriple.isOSBinFormatELF()) return nullptr; - assert(F.hasName()); - std::string Name = F.getName(); - if (F.hasLocalLinkage()) { - if (CurModuleUniqueId.empty()) return nullptr; - Name += CurModuleUniqueId; - } - auto Comdat = CurModule->getOrInsertComdat(Name); - F.setComdat(Comdat); - return Comdat; -} - GlobalVariable *SanitizerCoverageModule::CreateFunctionLocalArrayInSection( size_t NumElements, Function &F, Type *Ty, const char *Section) { ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); auto Array = new GlobalVariable( *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, Constant::getNullValue(ArrayTy), "__sancov_gen_"); - if (auto Comdat = GetOrCreateFunctionComdat(F)) - Array->setComdat(Comdat); + + if (TargetTriple.isOSBinFormatELF()) + if (auto Comdat = GetOrCreateFunctionComdat(F, CurModuleUniqueId)) + Array->setComdat(Comdat); Array->setSection(getSectionName(Section)); Array->setAlignment(Ty->isPointerTy() ? DL->getPointerSize() : Ty->getPrimitiveSizeInBits() / 8);