diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 12 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenPGO.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.cpp | 55 | ||||
-rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.h | 2 |
4 files changed, 66 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 5040965161c..1f0dd73e65b 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3198,10 +3198,20 @@ void CodeGenModule::ClearUnusedCoverageMapping(const Decl *D) { } void CodeGenModule::EmitDeferredUnusedCoverageMappings() { + std::vector<const Decl *> DeferredDecls; for (const auto I : DeferredEmptyCoverageMappingDecls) { if (!I.second) continue; - const auto *D = I.first; + DeferredDecls.push_back(I.first); + } + // Sort the declarations by their location to make sure that the tests get a + // predictable order for the coverage mapping for the unused declarations. + if (CodeGenOpts.DumpCoverageMapping) + std::sort(DeferredDecls.begin(), DeferredDecls.end(), + [] (const Decl *LHS, const Decl *RHS) { + return LHS->getLocStart() < RHS->getLocStart(); + }); + for (const auto *D : DeferredDecls) { switch (D->getKind()) { case Decl::CXXConversion: case Decl::CXXMethod: diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index e6dbad856c3..7fb64b85a05 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -169,7 +169,7 @@ llvm::GlobalVariable *CodeGenPGO::buildDataVar() { // Create coverage mapping data variable. if (!CoverageMapping.empty()) CGM.getCoverageMapping()->addFunctionMappingRecord(Name, - getFuncName().size(), + getFuncName(), CoverageMapping); // Hide all these symbols so that we correctly get a copy for each diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 526d30f20b7..836d09f7343 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -18,6 +18,7 @@ #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/ProfileData/CoverageMapping.h" #include "llvm/ProfileData/CoverageMappingWriter.h" +#include "llvm/ProfileData/CoverageMappingReader.h" #include "llvm/Support/FileSystem.h" using namespace clang; @@ -1052,8 +1053,36 @@ static StringRef getCoverageSection(const CodeGenModule &CGM) { return isMachO(CGM) ? "__DATA,__llvm_covmap" : "__llvm_covmap"; } +static void dump(llvm::raw_ostream &OS, const CoverageMappingRecord &Function) { + OS << Function.FunctionName << ":\n"; + CounterMappingContext Ctx(Function.Expressions); + for (const auto &R : Function.MappingRegions) { + OS.indent(2); + switch (R.Kind) { + case CounterMappingRegion::CodeRegion: + break; + case CounterMappingRegion::ExpansionRegion: + OS << "Expansion,"; + break; + case CounterMappingRegion::SkippedRegion: + OS << "Skipped,"; + break; + } + + OS << "File " << R.FileID << ", " << R.LineStart << ":" + << R.ColumnStart << " -> " << R.LineEnd << ":" << R.ColumnEnd + << " = "; + Ctx.dump(R.Count); + OS << " (HasCodeBefore = " << R.HasCodeBefore; + if (R.Kind == CounterMappingRegion::ExpansionRegion) + OS << ", Expanded file = " << R.ExpandedFileID; + + OS << ")\n"; + } +} + void CoverageMappingModuleGen::addFunctionMappingRecord( - llvm::GlobalVariable *FunctionName, unsigned FunctionNameSize, + llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue, const std::string &CoverageMapping) { llvm::LLVMContext &Ctx = CGM.getLLVMContext(); auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); @@ -1066,11 +1095,33 @@ void CoverageMappingModuleGen::addFunctionMappingRecord( llvm::Constant *FunctionRecordVals[] = { llvm::ConstantExpr::getBitCast(FunctionName, Int8PtrTy), - llvm::ConstantInt::get(Int32Ty, FunctionNameSize), + llvm::ConstantInt::get(Int32Ty, FunctionNameValue.size()), llvm::ConstantInt::get(Int32Ty, CoverageMapping.size())}; FunctionRecords.push_back(llvm::ConstantStruct::get( FunctionRecordTy, makeArrayRef(FunctionRecordVals))); CoverageMappings += CoverageMapping; + + if (CGM.getCodeGenOpts().DumpCoverageMapping) { + // Dump the coverage mapping data for this function by decoding the + // encoded data. This allows us to dump the mapping regions which were + // also processed by the CoverageMappingWriter which performs + // additional minimization operations such as reducing the number of + // expressions. + std::vector<StringRef> Filenames; + std::vector<CounterExpression> Expressions; + std::vector<CounterMappingRegion> Regions; + llvm::SmallVector<StringRef, 16> FilenameRefs; + FilenameRefs.resize(FileEntries.size()); + for (const auto &Entry : FileEntries) + FilenameRefs[Entry.second] = Entry.first->getName(); + RawCoverageMappingReader Reader(FunctionNameValue, CoverageMapping, + FilenameRefs, + Filenames, Expressions, Regions); + CoverageMappingRecord FunctionRecord; + if (Reader.read(FunctionRecord)) + return; + dump(llvm::outs(), FunctionRecord); + } } void CoverageMappingModuleGen::emit() { diff --git a/clang/lib/CodeGen/CoverageMappingGen.h b/clang/lib/CodeGen/CoverageMappingGen.h index e77dedb925d..5a73a47fee8 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.h +++ b/clang/lib/CodeGen/CoverageMappingGen.h @@ -68,7 +68,7 @@ public: /// \brief Add a function's coverage mapping record to the collection of the /// function mapping records. void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName, - unsigned FunctionNameSize, + StringRef FunctionNameValue, const std::string &CoverageMapping); /// \brief Emit the coverage mapping data for a translation unit. |