]> granicus.if.org Git - clang/commitdiff
Add a cc1 "dump-coverage-mapping" for testing coverage mapping.
authorAlex Lorenz <arphaman@gmail.com>
Fri, 8 Aug 2014 23:41:24 +0000 (23:41 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Fri, 8 Aug 2014 23:41:24 +0000 (23:41 +0000)
Differential Revision: http://reviews.llvm.org/D4799

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215258 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/CC1Options.td
include/clang/Frontend/CodeGenOptions.def
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenPGO.cpp
lib/CodeGen/CoverageMappingGen.cpp
lib/CodeGen/CoverageMappingGen.h
lib/Frontend/CompilerInvocation.cpp

index c3685e0f3091637dd63ceaa3062072c9101a6bc0..ae3001c3d2e74ebadb4a68fbdadccc4e90da2d90 100644 (file)
@@ -179,6 +179,8 @@ def coverage_version_EQ : Joined<["-"], "coverage-version=">,
   HelpText<"Four-byte version string for gcov files.">;
 def test_coverage : Flag<["-"], "test-coverage">,
   HelpText<"Do not generate coverage files or remove coverage changes from IR">;
+def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">,
+  HelpText<"Dump the coverage mapping records, for testing">;
 def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">,
   HelpText<"Use register sized accesses to bit-fields, when possible.">;
 def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
index 3767b4244f5a136f271a80d11416c2b2482ba235..71795a2ed2ab0830e81ec640bf693d64f137cc5a 100644 (file)
@@ -90,6 +90,8 @@ CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate
                                         ///< execution counts to use with PGO.
 CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to
                                    ///< enable code coverage analysis.
+CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping
+                                       ///< regions.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
index 5040965161cbeb12e11f72e9551c1306c8bcca71..1f0dd73e65bbff697e66c55524d950a7f3847387 100644 (file)
@@ -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:
index e6dbad856c39c5ca010e7216265c7496bb93e0b5..7fb64b85a05bc6df885a4ac4c68eff55df3f04e4 100644 (file)
@@ -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
index 526d30f20b7759d90bd8558491437be29d374450..836d09f7343d103bf2063e9533dfc9dd68bf8281 100644 (file)
@@ -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() {
index e77dedb925d53444d053f27a73286ede28f36111..5a73a47fee865aad3c79de2e027bc14634131cfc 100644 (file)
@@ -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.
index 1a67e1376e1a38852daa4702a67462a75c9309f5..7b864bf31fec2f9b6b1d21c870da5ff587da6ef4 100644 (file)
@@ -400,6 +400,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
   Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate);
   Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
   Opts.CoverageMapping = Args.hasArg(OPT_fcoverage_mapping);
+  Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
   Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
   Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
   Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device);