@@ -42,11 +42,14 @@ static std::string getInstrProfSection(IRGenModule &IGM,
4242 return llvm::getInstrProfSectionName (SK, IGM.Triple .getObjectFormat ());
4343}
4444
45- void IRGenModule::emitCoverageMapping () {
45+ void IRGenModule::emitCoverageMaps (ArrayRef<const SILCoverageMap *> Mappings) {
46+ // If there aren't any coverage maps, there's nothing to emit.
47+ if (Mappings.empty ())
48+ return ;
49+
4650 SmallVector<llvm::Constant *, 4 > UnusedFuncNames;
47- std::vector<const SILCoverageMap *> Mappings;
48- for (const auto &M : getSILModule ().getCoverageMaps ()) {
49- auto FuncName = M.second ->getPGOFuncName ();
51+ for (const auto *Mapping : Mappings) {
52+ auto FuncName = Mapping->getPGOFuncName ();
5053 auto VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
5154 auto FuncNameVarName = llvm::getPGOFuncNameVarName (FuncName, VarLinkage);
5255
@@ -58,13 +61,8 @@ void IRGenModule::emitCoverageMapping() {
5861 auto *Var = llvm::createPGOFuncNameVar (Module, VarLinkage, FuncName);
5962 UnusedFuncNames.push_back (llvm::ConstantExpr::getBitCast (Var, Int8PtrTy));
6063 }
61- Mappings.push_back (M.second );
6264 }
6365
64- // If there aren't any coverage maps, there's nothing to emit.
65- if (Mappings.empty ())
66- return ;
67-
6866 // Emit the name data for any unused functions.
6967 if (!UnusedFuncNames.empty ()) {
7068 auto NamePtrsTy = llvm::ArrayType::get (Int8PtrTy, UnusedFuncNames.size ());
@@ -80,8 +78,8 @@ void IRGenModule::emitCoverageMapping() {
8078
8179 std::vector<StringRef> Files;
8280 for (const auto &M : Mappings)
83- if (std::find (Files.begin (), Files.end (), M->getFile ()) == Files.end ())
84- Files.push_back (M->getFile ());
81+ if (std::find (Files.begin (), Files.end (), M->getFilename ()) == Files.end ())
82+ Files.push_back (M->getFilename ());
8583
8684 auto remapper = getOptions ().CoveragePrefixMap ;
8785
@@ -115,7 +113,7 @@ void IRGenModule::emitCoverageMapping() {
115113 std::string FuncRecordName = " __covrec_" + llvm::utohexstr (NameHash);
116114
117115 unsigned FileID =
118- std::find (Files.begin (), Files.end (), M->getFile ()) - Files.begin ();
116+ std::find (Files.begin (), Files.end (), M->getFilename ()) - Files.begin ();
119117 std::vector<CounterMappingRegion> Regions;
120118 for (const auto &MR : M->getMappedRegions ())
121119 Regions.emplace_back (CounterMappingRegion::makeRegion (
@@ -194,6 +192,27 @@ void IRGenModule::emitCoverageMapping() {
194192}
195193
196194void IRGenerator::emitCoverageMapping () {
197- for (auto &IGM : *this )
198- IGM.second ->emitCoverageMapping ();
195+ if (SIL.getCoverageMaps ().empty ())
196+ return ;
197+
198+ // Shard the coverage maps across their designated IRGenModules. This is
199+ // necessary to ensure we don't output N copies of a coverage map when doing
200+ // parallel IRGen, where N is the number of output object files.
201+ //
202+ // Note we don't just dump all the coverage maps into the primary IGM as
203+ // that would require creating unecessary name data entries, since the name
204+ // data is likely to already be present in the IGM that contains the entity
205+ // being profiled (unless it has been optimized out). Matching the coverage
206+ // map to its originating SourceFile also matches the behavior of a debug
207+ // build where the files are compiled separately.
208+ llvm::DenseMap<IRGenModule *, std::vector<const SILCoverageMap *>> MapsToEmit;
209+ for (const auto &M : SIL.getCoverageMaps ()) {
210+ auto &Mapping = M.second ;
211+ auto *SF = Mapping->getParentSourceFile ();
212+ MapsToEmit[getGenModule (SF)].push_back (Mapping);
213+ }
214+ for (auto &IGMPair : *this ) {
215+ auto *IGM = IGMPair.second ;
216+ IGM->emitCoverageMaps (MapsToEmit[IGM]);
217+ }
199218}
0 commit comments