Index: llvm/trunk/include/llvm/ProfileData/InstrProf.h =================================================================== --- llvm/trunk/include/llvm/ProfileData/InstrProf.h +++ llvm/trunk/include/llvm/ProfileData/InstrProf.h @@ -274,6 +274,10 @@ /// declared by users only. void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName); +/// Check if we can use Comdat for profile variables. This will eliminate +/// the duplicated profile variables for Comdat functions. +bool needsComdatForCounter(const Function &F, const Module &M); + const std::error_category &instrprof_category(); enum class instrprof_error { Index: llvm/trunk/lib/ProfileData/InstrProf.cpp =================================================================== --- llvm/trunk/lib/ProfileData/InstrProf.cpp +++ llvm/trunk/lib/ProfileData/InstrProf.cpp @@ -14,6 +14,7 @@ #include "llvm/ProfileData/InstrProf.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Triple.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" @@ -780,4 +781,29 @@ F.setMetadata(getPGOFuncNameMetadataName(), N); } +bool needsComdatForCounter(const Function &F, const Module &M) { + if (F.hasComdat()) + return true; + + Triple TT(M.getTargetTriple()); + if (!TT.isOSBinFormatELF()) + return false; + + // See createPGOFuncNameVar for more details. To avoid link errors, profile + // counters for function with available_externally linkage needs to be changed + // to linkonce linkage. On ELF based systems, this leads to weak symbols to be + // created. Without using comdat, duplicate entries won't be removed by the + // linker leading to increased data segement size and raw profile size. Even + // worse, since the referenced counter from profile per-function data object + // will be resolved to the common strong definition, the profile counts for + // available_externally functions will end up being duplicated in raw profile + // data. This can result in distorted profile as the counts of those dups + // will be accumulated by the profile merger. + GlobalValue::LinkageTypes Linkage = F.getLinkage(); + if (Linkage != GlobalValue::ExternalWeakLinkage && + Linkage != GlobalValue::AvailableExternallyLinkage) + return false; + + return true; +} } // end namespace llvm Index: llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -268,33 +268,6 @@ return F->hasAddressTaken() || F->hasLinkOnceLinkage(); } -static inline bool needsComdatForCounter(Function &F, Module &M) { - - if (F.hasComdat()) - return true; - - Triple TT(M.getTargetTriple()); - if (!TT.isOSBinFormatELF()) - return false; - - // See createPGOFuncNameVar for more details. To avoid link errors, profile - // counters for function with available_externally linkage needs to be changed - // to linkonce linkage. On ELF based systems, this leads to weak symbols to be - // created. Without using comdat, duplicate entries won't be removed by the - // linker leading to increased data segement size and raw profile size. Even - // worse, since the referenced counter from profile per-function data object - // will be resolved to the common strong definition, the profile counts for - // available_externally functions will end up being duplicated in raw profile - // data. This can result in distorted profile as the counts of those dups - // will be accumulated by the profile merger. - GlobalValue::LinkageTypes Linkage = F.getLinkage(); - if (Linkage != GlobalValue::ExternalWeakLinkage && - Linkage != GlobalValue::AvailableExternallyLinkage) - return false; - - return true; -} - static inline Comdat *getOrCreateProfileComdat(Module &M, Function &F, InstrProfIncrementInst *Inc) { if (!needsComdatForCounter(F, M))