r214752 - Add coverage mapping generation.

Alex L arphaman at gmail.com
Mon Aug 4 12:15:12 PDT 2014


My fix reverted in r214757.


2014-08-04 12:11 GMT-07:00 David Blaikie <dblaikie at gmail.com>:

> Ah, sorry - thanks :)
>
> On Mon, Aug 4, 2014 at 12:10 PM, Alex L <arphaman at gmail.com> wrote:
> > I actually fixed it in r214757, now there are two :)
> > I will revert mine
> >
> >
> > 2014-08-04 12:08 GMT-07:00 David Blaikie <dblaikie at gmail.com>:
> >>
> >> CMake build fixed in  r214758
> >>
> >> On Mon, Aug 4, 2014 at 11:41 AM, Alex Lorenz <arphaman at gmail.com>
> wrote:
> >> > Author: arphaman
> >> > Date: Mon Aug  4 13:41:51 2014
> >> > New Revision: 214752
> >> >
> >> > URL: http://llvm.org/viewvc/llvm-project?rev=214752&view=rev
> >> > Log:
> >> > Add coverage mapping generation.
> >> >
> >> > This patch adds the '-fcoverage-mapping' option which
> >> > allows clang to generate the coverage mapping information
> >> > that can be used to provide code coverage analysis using
> >> > the execution counts obtained from the instrumentation
> >> > based profiling (-fprofile-instr-generate).
> >> >
> >> > Added:
> >> >     cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
> >> >     cfe/trunk/lib/CodeGen/CoverageMappingGen.h
> >> > Modified:
> >> >     cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h
> >> >     cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
> >> >     cfe/trunk/include/clang/Driver/Options.td
> >> >     cfe/trunk/include/clang/Frontend/CodeGenOptions.def
> >> >     cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp
> >> >     cfe/trunk/lib/CodeGen/CodeGenAction.cpp
> >> >     cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> >> >     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >> >     cfe/trunk/lib/CodeGen/CodeGenModule.h
> >> >     cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
> >> >     cfe/trunk/lib/CodeGen/CodeGenPGO.h
> >> >     cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
> >> >     cfe/trunk/lib/Driver/Tools.cpp
> >> >     cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> >> >
> >> > Modified: cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h (original)
> >> > +++ cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h Mon Aug  4
> >> > 13:41:51 2014
> >> > @@ -39,6 +39,7 @@ class CXXRecordDecl;
> >> >  class CodeGenOptions;
> >> >  class DiagnosticsEngine;
> >> >  class ObjCMethodDecl;
> >> > +class CoverageSourceInfo;
> >> >
> >> >  namespace CodeGen {
> >> >  class CGFunctionInfo;
> >> > @@ -47,7 +48,8 @@ class CodeGenModule;
> >> >  class CodeGenABITypes
> >> >  {
> >> >  public:
> >> > -  CodeGenABITypes(ASTContext &C, llvm::Module &M, const
> >> > llvm::DataLayout &TD);
> >> > +  CodeGenABITypes(ASTContext &C, llvm::Module &M, const
> >> > llvm::DataLayout &TD,
> >> > +                  CoverageSourceInfo *CoverageInfo = nullptr);
> >> >    ~CodeGenABITypes();
> >> >
> >> >    /// These methods all forward to methods in the private
> >> > implementation class
> >> >
> >> > Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)
> >> > +++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Mon Aug  4
> 13:41:51
> >> > 2014
> >> > @@ -24,6 +24,7 @@ namespace llvm {
> >> >
> >> >  namespace clang {
> >> >    class DiagnosticsEngine;
> >> > +  class CoverageSourceInfo;
> >> >    class LangOptions;
> >> >    class CodeGenOptions;
> >> >    class TargetOptions;
> >> > @@ -44,7 +45,8 @@ namespace clang {
> >> >                                     const std::string &ModuleName,
> >> >                                     const CodeGenOptions &CGO,
> >> >                                     const TargetOptions &TO,
> >> > -                                   llvm::LLVMContext& C);
> >> > +                                   llvm::LLVMContext& C,
> >> > +                                   CoverageSourceInfo *CoverageInfo =
> >> > nullptr);
> >> >  }
> >> >
> >> >  #endif
> >> >
> >> > Modified: cfe/trunk/include/clang/Driver/Options.td
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/include/clang/Driver/Options.td (original)
> >> > +++ cfe/trunk/include/clang/Driver/Options.td Mon Aug  4 13:41:51 2014
> >> > @@ -408,6 +408,9 @@ def fprofile_instr_use : Flag<["-"], "fp
> >> >  def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
> >> >      Group<f_Group>, Flags<[CC1Option]>,
> >> >      HelpText<"Use instrumentation data for profile-guided
> >> > optimization">;
> >> > +def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">,
> >> > +    Group<f_Group>, Flags<[CC1Option]>,
> >> > +    HelpText<"Generate coverage mapping to enable code coverage
> >> > analysis">;
> >> >
> >> >  def fblocks : Flag<["-"], "fblocks">, Group<f_Group>,
> >> > Flags<[CC1Option]>,
> >> >    HelpText<"Enable the 'blocks' language feature">;
> >> >
> >> > Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)
> >> > +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Mon Aug  4
> >> > 13:41:51 2014
> >> > @@ -88,6 +88,8 @@ VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///
> >> >
> >> >  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.
> >> >
> >> >    /// If -fpcc-struct-return or -freg-struct-return is specified.
> >> >  ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind,
> 2,
> >> > SRCK_Default)
> >> >
> >> > Modified: cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp (original)
> >> > +++ cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp Mon Aug  4 13:41:51 2014
> >> > @@ -26,9 +26,11 @@ using namespace CodeGen;
> >> >
> >> >  CodeGenABITypes::CodeGenABITypes(ASTContext &C,
> >> >                                   llvm::Module &M,
> >> > -                                 const llvm::DataLayout &TD)
> >> > +                                 const llvm::DataLayout &TD,
> >> > +                                 CoverageSourceInfo *CoverageInfo)
> >> >    : CGO(new CodeGenOptions),
> >> > -    CGM(new CodeGen::CodeGenModule(C, *CGO, M, TD,
> C.getDiagnostics()))
> >> > {
> >> > +    CGM(new CodeGen::CodeGenModule(C, *CGO, M, TD,
> C.getDiagnostics(),
> >> > +                                   CoverageInfo)) {
> >> >  }
> >> >
> >> >  CodeGenABITypes::~CodeGenABITypes()
> >> >
> >> > Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)
> >> > +++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Mon Aug  4 13:41:51 2014
> >> > @@ -7,6 +7,7 @@
> >> >  //
> >> >
> >> >
> //===----------------------------------------------------------------------===//
> >> >
> >> > +#include "CoverageMappingGen.h"
> >> >  #include "clang/CodeGen/CodeGenAction.h"
> >> >  #include "clang/AST/ASTConsumer.h"
> >> >  #include "clang/AST/ASTContext.h"
> >> > @@ -15,6 +16,7 @@
> >> >  #include "clang/Basic/FileManager.h"
> >> >  #include "clang/Basic/SourceManager.h"
> >> >  #include "clang/Basic/TargetInfo.h"
> >> > +#include "clang/Lex/Preprocessor.h"
> >> >  #include "clang/CodeGen/BackendUtil.h"
> >> >  #include "clang/CodeGen/ModuleBuilder.h"
> >> >  #include "clang/Frontend/CompilerInstance.h"
> >> > @@ -59,11 +61,13 @@ namespace clang {
> >> >                      const TargetOptions &targetopts,
> >> >                      const LangOptions &langopts, bool TimePasses,
> >> >                      const std::string &infile, llvm::Module
> >> > *LinkModule,
> >> > -                    raw_ostream *OS, LLVMContext &C)
> >> > +                    raw_ostream *OS, LLVMContext &C,
> >> > +                    CoverageSourceInfo *CoverageInfo = nullptr)
> >> >          : Diags(_Diags), Action(action), CodeGenOpts(compopts),
> >> >            TargetOpts(targetopts), LangOpts(langopts),
> AsmOutStream(OS),
> >> >            Context(), LLVMIRGeneration("LLVM IR Generation Time"),
> >> > -          Gen(CreateLLVMCodeGen(Diags, infile, compopts, targetopts,
> >> > C)),
> >> > +          Gen(CreateLLVMCodeGen(Diags, infile, compopts,
> >> > +                                targetopts, C, CoverageInfo)),
> >> >            LinkModule(LinkModule) {
> >> >        llvm::TimePassesIsEnabled = TimePasses;
> >> >      }
> >> > @@ -636,10 +640,17 @@ ASTConsumer *CodeGenAction::CreateASTCon
> >> >      LinkModuleToUse = ModuleOrErr.get();
> >> >    }
> >> >
> >> > +  CoverageSourceInfo *CoverageInfo = nullptr;
> >> > +  // Add the preprocessor callback only when the coverage mapping is
> >> > generated.
> >> > +  if (CI.getCodeGenOpts().CoverageMapping) {
> >> > +    CoverageInfo = new CoverageSourceInfo;
> >> > +    CI.getPreprocessor().addPPCallbacks(CoverageInfo);
> >> > +  }
> >> >    BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(),
> >> > CI.getCodeGenOpts(),
> >> >                                     CI.getTargetOpts(),
> >> > CI.getLangOpts(),
> >> >                                     CI.getFrontendOpts().ShowTimers,
> >> > InFile,
> >> > -                                   LinkModuleToUse, OS.release(),
> >> > *VMContext);
> >> > +                                   LinkModuleToUse, OS.release(),
> >> > *VMContext,
> >> > +                                   CoverageInfo);
> >> >    return BEConsumer;
> >> >  }
> >> >
> >> >
> >> > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
> >> > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Aug  4 13:41:51 2014
> >> > @@ -829,6 +829,7 @@ void CodeGenFunction::GenerateCode(Globa
> >> >    StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc,
> >> > BodyRange.getBegin());
> >> >
> >> >    // Generate the body of the function.
> >> > +  PGO.checkGlobalDecl(GD);
> >> >    PGO.assignRegionCounters(GD.getDecl(), CurFn);
> >> >    if (isa<CXXDestructorDecl>(FD))
> >> >      EmitDestructorBody(Args);
> >> >
> >> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> >> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Aug  4 13:41:51 2014
> >> > @@ -21,6 +21,7 @@
> >> >  #include "CGOpenMPRuntime.h"
> >> >  #include "CodeGenFunction.h"
> >> >  #include "CodeGenPGO.h"
> >> > +#include "CoverageMappingGen.h"
> >> >  #include "CodeGenTBAA.h"
> >> >  #include "TargetInfo.h"
> >> >  #include "clang/AST/ASTContext.h"
> >> > @@ -74,7 +75,8 @@ static CGCXXABI *createCXXABI(CodeGenMod
> >> >
> >> >  CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions
> &CGO,
> >> >                               llvm::Module &M, const llvm::DataLayout
> >> > &TD,
> >> > -                             DiagnosticsEngine &diags)
> >> > +                             DiagnosticsEngine &diags,
> >> > +                             CoverageSourceInfo *CoverageInfo)
> >> >      : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO),
> >> > TheModule(M),
> >> >        Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()),
> >> >        ABI(createCXXABI(*this)), VMContext(M.getContext()),
> >> > TBAA(nullptr),
> >> > @@ -146,6 +148,11 @@ CodeGenModule::CodeGenModule(ASTContext
> >> >        getDiags().Report(DiagID) << EC.message();
> >> >      }
> >> >    }
> >> > +
> >> > +  // If coverage mapping generation is enabled, create the
> >> > +  // CoverageMappingModuleGen object.
> >> > +  if (CodeGenOpts.CoverageMapping)
> >> > +    CoverageMapping.reset(new CoverageMappingModuleGen(*this,
> >> > *CoverageInfo));
> >> >  }
> >> >
> >> >  CodeGenModule::~CodeGenModule() {
> >> > @@ -344,6 +351,9 @@ void CodeGenModule::Release() {
> >> >    EmitCtorList(GlobalDtors, "llvm.global_dtors");
> >> >    EmitGlobalAnnotations();
> >> >    EmitStaticExternCAliases();
> >> > +  EmitDeferredUnusedCoverageMappings();
> >> > +  if (CoverageMapping)
> >> > +    CoverageMapping->emit();
> >> >    emitLLVMUsed();
> >> >
> >> >    if (CodeGenOpts.Autolink &&
> >> > @@ -2989,6 +2999,9 @@ void CodeGenModule::EmitTopLevelDecl(Dec
> >> >        return;
> >> >
> >> >      EmitGlobal(cast<FunctionDecl>(D));
> >> > +    // Always provide some coverage mapping
> >> > +    // even for the functions that aren't emitted.
> >> > +    AddDeferredUnusedCoverageMapping(D);
> >> >      break;
> >> >
> >> >    case Decl::Var:
> >> > @@ -3138,6 +3151,80 @@ void CodeGenModule::EmitTopLevelDecl(Dec
> >> >    }
> >> >  }
> >> >
> >> > +void CodeGenModule::AddDeferredUnusedCoverageMapping(Decl *D) {
> >> > +  // Do we need to generate coverage mapping?
> >> > +  if (!CodeGenOpts.CoverageMapping)
> >> > +    return;
> >> > +  switch (D->getKind()) {
> >> > +  case Decl::CXXConversion:
> >> > +  case Decl::CXXMethod:
> >> > +  case Decl::Function:
> >> > +  case Decl::ObjCMethod:
> >> > +  case Decl::CXXConstructor:
> >> > +  case Decl::CXXDestructor: {
> >> > +    if (!cast<FunctionDecl>(D)->hasBody())
> >> > +      return;
> >> > +    auto I = DeferredEmptyCoverageMappingDecls.find(D);
> >> > +    if (I == DeferredEmptyCoverageMappingDecls.end())
> >> > +      DeferredEmptyCoverageMappingDecls[D] = true;
> >> > +    break;
> >> > +  }
> >> > +  default:
> >> > +    break;
> >> > +  };
> >> > +}
> >> > +
> >> > +void CodeGenModule::ClearUnusedCoverageMapping(const Decl *D) {
> >> > +  // Do we need to generate coverage mapping?
> >> > +  if (!CodeGenOpts.CoverageMapping)
> >> > +    return;
> >> > +  if (const auto *Fn = dyn_cast<FunctionDecl>(D)) {
> >> > +    if (Fn->isTemplateInstantiation())
> >> > +
> >> > ClearUnusedCoverageMapping(Fn->getTemplateInstantiationPattern());
> >> > +  }
> >> > +  auto I = DeferredEmptyCoverageMappingDecls.find(D);
> >> > +  if (I == DeferredEmptyCoverageMappingDecls.end())
> >> > +    DeferredEmptyCoverageMappingDecls[D] = false;
> >> > +  else
> >> > +    I->second = false;
> >> > +}
> >> > +
> >> > +void CodeGenModule::EmitDeferredUnusedCoverageMappings() {
> >> > +  for (const auto I : DeferredEmptyCoverageMappingDecls) {
> >> > +    if (!I.second)
> >> > +      continue;
> >> > +    const auto *D = I.first;
> >> > +    switch (D->getKind()) {
> >> > +    case Decl::CXXConversion:
> >> > +    case Decl::CXXMethod:
> >> > +    case Decl::Function:
> >> > +    case Decl::ObjCMethod: {
> >> > +      CodeGenPGO PGO(*this);
> >> > +      GlobalDecl GD(cast<FunctionDecl>(D));
> >> > +      PGO.emitEmptyCounterMapping(D, getMangledName(GD),
> >> > +                                  getFunctionLinkage(GD));
> >> > +      break;
> >> > +    }
> >> > +    case Decl::CXXConstructor: {
> >> > +      CodeGenPGO PGO(*this);
> >> > +      GlobalDecl GD(cast<CXXConstructorDecl>(D), Ctor_Base);
> >> > +      PGO.emitEmptyCounterMapping(D, getMangledName(GD),
> >> > +                                  getFunctionLinkage(GD));
> >> > +      break;
> >> > +    }
> >> > +    case Decl::CXXDestructor: {
> >> > +      CodeGenPGO PGO(*this);
> >> > +      GlobalDecl GD(cast<CXXDestructorDecl>(D), Dtor_Base);
> >> > +      PGO.emitEmptyCounterMapping(D, getMangledName(GD),
> >> > +                                  getFunctionLinkage(GD));
> >> > +      break;
> >> > +    }
> >> > +    default:
> >> > +      break;
> >> > +    };
> >> > +  }
> >> > +}
> >> > +
> >> >  /// Turns the given pointer into a constant.
> >> >  static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context,
> >> >                                            const void *Ptr) {
> >> >
> >> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
> >> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Aug  4 13:41:51 2014
> >> > @@ -73,6 +73,7 @@ class DiagnosticsEngine;
> >> >  class AnnotateAttr;
> >> >  class CXXDestructorDecl;
> >> >  class Module;
> >> > +class CoverageSourceInfo;
> >> >
> >> >  namespace CodeGen {
> >> >
> >> > @@ -87,6 +88,7 @@ class CGOpenMPRuntime;
> >> >  class CGCUDARuntime;
> >> >  class BlockFieldFlags;
> >> >  class FunctionArgList;
> >> > +class CoverageMappingModuleGen;
> >> >
> >> >  struct OrderGlobalInits {
> >> >    unsigned int priority;
> >> > @@ -477,10 +479,15 @@ class CodeGenModule : public CodeGenType
> >> >    std::unique_ptr<SanitizerMetadata> SanitizerMD;
> >> >
> >> >    /// @}
> >> > +
> >> > +  llvm::DenseMap<const Decl *, bool>
> DeferredEmptyCoverageMappingDecls;
> >> > +
> >> > +  std::unique_ptr<CoverageMappingModuleGen> CoverageMapping;
> >> >  public:
> >> >    CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts,
> >> >                  llvm::Module &M, const llvm::DataLayout &TD,
> >> > -                DiagnosticsEngine &Diags);
> >> > +                DiagnosticsEngine &Diags,
> >> > +                CoverageSourceInfo *CoverageInfo = nullptr);
> >> >
> >> >    ~CodeGenModule();
> >> >
> >> > @@ -529,6 +536,10 @@ public:
> >> >    InstrProfStats &getPGOStats() { return PGOStats; }
> >> >    llvm::IndexedInstrProfReader *getPGOReader() const { return
> >> > PGOReader.get(); }
> >> >
> >> > +  CoverageMappingModuleGen *getCoverageMapping() const {
> >> > +    return CoverageMapping.get();
> >> > +  }
> >> > +
> >> >    llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {
> >> >      return StaticLocalDeclMap[D];
> >> >    }
> >> > @@ -815,6 +826,18 @@ public:
> >> >    /// Emit code for a single top level declaration.
> >> >    void EmitTopLevelDecl(Decl *D);
> >> >
> >> > +  /// \brief Stored a deferred empty coverage mapping for an unused
> >> > +  /// and thus uninstrumented top level declaration.
> >> > +  void AddDeferredUnusedCoverageMapping(Decl *D);
> >> > +
> >> > +  /// \brief Remove the deferred empty coverage mapping as this
> >> > +  /// declaration is actually instrumented.
> >> > +  void ClearUnusedCoverageMapping(const Decl *D);
> >> > +
> >> > +  /// \brief Emit all the deferred coverage mappings
> >> > +  /// for the uninstrumented functions.
> >> > +  void EmitDeferredUnusedCoverageMappings();
> >> > +
> >> >    /// Tell the consumer that this variable has been instantiated.
> >> >    void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);
> >> >
> >> >
> >> > Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
> >> > +++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Mon Aug  4 13:41:51 2014
> >> > @@ -13,6 +13,7 @@
> >> >
> >> >  #include "CodeGenPGO.h"
> >> >  #include "CodeGenFunction.h"
> >> > +#include "CoverageMappingGen.h"
> >> >  #include "clang/AST/RecursiveASTVisitor.h"
> >> >  #include "clang/AST/StmtVisitor.h"
> >> >  #include "llvm/IR/MDBuilder.h"
> >> > @@ -24,8 +25,9 @@
> >> >  using namespace clang;
> >> >  using namespace CodeGen;
> >> >
> >> > -void CodeGenPGO::setFuncName(llvm::Function *Fn) {
> >> > -  RawFuncName = Fn->getName();
> >> > +void CodeGenPGO::setFuncName(StringRef Name,
> >> > +                             llvm::GlobalValue::LinkageTypes
> Linkage) {
> >> > +  RawFuncName = Name;
> >> >
> >> >    // Function names may be prefixed with a binary '1' to indicate
> >> >    // that the backend should not modify the symbols due to any
> platform
> >> > @@ -33,7 +35,7 @@ void CodeGenPGO::setFuncName(llvm::Funct
> >> >    if (RawFuncName[0] == '\1')
> >> >      RawFuncName = RawFuncName.substr(1);
> >> >
> >> > -  if (!Fn->hasLocalLinkage()) {
> >> > +  if (!llvm::GlobalValue::isLocalLinkage(Linkage)) {
> >> >      PrefixedFuncName.reset(new std::string(RawFuncName));
> >> >      return;
> >> >    }
> >> > @@ -49,6 +51,27 @@ void CodeGenPGO::setFuncName(llvm::Funct
> >> >    PrefixedFuncName->append(RawFuncName);
> >> >  }
> >> >
> >> > +void CodeGenPGO::setFuncName(llvm::Function *Fn) {
> >> > +  setFuncName(Fn->getName(), Fn->getLinkage());
> >> > +}
> >> > +
> >> > +void CodeGenPGO::setVarLinkage(llvm::GlobalValue::LinkageTypes
> Linkage)
> >> > {
> >> > +  // Set the linkage for variables based on the function linkage.
> >> > Usually, we
> >> > +  // want to match it, but available_externally and extern_weak both
> >> > have the
> >> > +  // wrong semantics.
> >> > +  VarLinkage = Linkage;
> >> > +  switch (VarLinkage) {
> >> > +  case llvm::GlobalValue::ExternalWeakLinkage:
> >> > +    VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
> >> > +    break;
> >> > +  case llvm::GlobalValue::AvailableExternallyLinkage:
> >> > +    VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
> >> > +    break;
> >> > +  default:
> >> > +    break;
> >> > +  }
> >> > +}
> >> > +
> >> >  static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
> >> >    return
> >> > CGM.getModule().getFunction("__llvm_profile_register_functions");
> >> >  }
> >> > @@ -120,37 +143,48 @@ llvm::GlobalVariable *CodeGenPGO::buildD
> >> >    auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
> >> >    auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
> >> >    auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
> >> > -  llvm::Type *DataTypes[] = {
> >> > -    Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
> >> > -  };
> >> > -  auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
> >> > -  llvm::Constant *DataVals[] = {
> >> > -    llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
> >> > -    llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
> >> > -    llvm::ConstantInt::get(Int64Ty, FunctionHash),
> >> > -    llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
> >> > -    llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
> >> > -  };
> >> > -  auto *Data =
> >> > -    new llvm::GlobalVariable(CGM.getModule(), DataTy, true,
> VarLinkage,
> >> > -                             llvm::ConstantStruct::get(DataTy,
> >> > DataVals),
> >> > -                             getFuncVarName("data"));
> >> > -
> >> > -  // All the data should be packed into an array in its own section.
> >> > -  Data->setSection(getDataSection(CGM));
> >> > -  Data->setAlignment(8);
> >> > +  llvm::GlobalVariable *Data = nullptr;
> >> > +  if (RegionCounters) {
> >> > +    llvm::Type *DataTypes[] = {
> >> > +      Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
> >> > +    };
> >> > +    auto *DataTy = llvm::StructType::get(Ctx,
> makeArrayRef(DataTypes));
> >> > +    llvm::Constant *DataVals[] = {
> >> > +      llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
> >> > +      llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
> >> > +      llvm::ConstantInt::get(Int64Ty, FunctionHash),
> >> > +      llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
> >> > +      llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
> >> > +    };
> >> > +    Data =
> >> > +      new llvm::GlobalVariable(CGM.getModule(), DataTy, true,
> >> > VarLinkage,
> >> > +                               llvm::ConstantStruct::get(DataTy,
> >> > DataVals),
> >> > +                               getFuncVarName("data"));
> >> > +
> >> > +    // All the data should be packed into an array in its own
> section.
> >> > +    Data->setSection(getDataSection(CGM));
> >> > +    Data->setAlignment(8);
> >> > +  }
> >> > +
> >> > +  // Create coverage mapping data variable.
> >> > +  if (!CoverageMapping.empty())
> >> > +    CGM.getCoverageMapping()->addFunctionMappingRecord(Name,
> >> > +
> >> > getFuncName().size(),
> >> > +
> >> > CoverageMapping);
> >> >
> >> >    // Hide all these symbols so that we correctly get a copy for each
> >> >    // executable.  The profile format expects names and counters to be
> >> >    // contiguous, so references into shared objects would be invalid.
> >> >    if (!llvm::GlobalValue::isLocalLinkage(VarLinkage)) {
> >> >      Name->setVisibility(llvm::GlobalValue::HiddenVisibility);
> >> > -    Data->setVisibility(llvm::GlobalValue::HiddenVisibility);
> >> > -
>  RegionCounters->setVisibility(llvm::GlobalValue::HiddenVisibility);
> >> > +    if (Data) {
> >> > +      Data->setVisibility(llvm::GlobalValue::HiddenVisibility);
> >> > +
> >> > RegionCounters->setVisibility(llvm::GlobalValue::HiddenVisibility);
> >> > +    }
> >> >    }
> >> >
> >> >    // Make sure the data doesn't get deleted.
> >> > -  CGM.addUsedGlobal(Data);
> >> > +  if (Data) CGM.addUsedGlobal(Data);
> >> >    return Data;
> >> >  }
> >> >
> >> > @@ -807,6 +841,20 @@ static void emitRuntimeHook(CodeGenModul
> >> >    CGM.addUsedGlobal(User);
> >> >  }
> >> >
> >> > +void CodeGenPGO::checkGlobalDecl(GlobalDecl GD) {
> >> > +  // Make sure we only emit coverage mapping for one
> >> > constructor/destructor.
> >> > +  // Clang emits several functions for the constructor and the
> >> > destructor of
> >> > +  // a class. Every function is instrumented, but we only want to
> >> > provide
> >> > +  // coverage for one of them. Because of that we only emit the
> >> > coverage mapping
> >> > +  // for the base constructor/destructor.
> >> > +  if ((isa<CXXConstructorDecl>(GD.getDecl()) &&
> >> > +       GD.getCtorType() != Ctor_Base) ||
> >> > +      (isa<CXXDestructorDecl>(GD.getDecl()) &&
> >> > +       GD.getDtorType() != Dtor_Base)) {
> >> > +    SkipCoverageMapping = true;
> >> > +  }
> >> > +}
> >> > +
> >> >  void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function
> >> > *Fn) {
> >> >    bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
> >> >    llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
> >> > @@ -814,27 +862,16 @@ void CodeGenPGO::assignRegionCounters(co
> >> >      return;
> >> >    if (D->isImplicit())
> >> >      return;
> >> > +  CGM.ClearUnusedCoverageMapping(D);
> >> >    setFuncName(Fn);
> >> > -
> >> > -  // Set the linkage for variables based on the function linkage.
> >> > Usually, we
> >> > -  // want to match it, but available_externally and extern_weak both
> >> > have the
> >> > -  // wrong semantics.
> >> > -  VarLinkage = Fn->getLinkage();
> >> > -  switch (VarLinkage) {
> >> > -  case llvm::GlobalValue::ExternalWeakLinkage:
> >> > -    VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
> >> > -    break;
> >> > -  case llvm::GlobalValue::AvailableExternallyLinkage:
> >> > -    VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
> >> > -    break;
> >> > -  default:
> >> > -    break;
> >> > -  }
> >> > +  setVarLinkage(Fn->getLinkage());
> >> >
> >> >    mapRegionCounters(D);
> >> >    if (InstrumentRegions) {
> >> >      emitRuntimeHook(CGM);
> >> >      emitCounterVariables();
> >> > +    if (CGM.getCodeGenOpts().CoverageMapping)
> >> > +      emitCounterRegionMapping(D);
> >> >    }
> >> >    if (PGOReader) {
> >> >      SourceManager &SM = CGM.getContext().getSourceManager();
> >> > @@ -860,6 +897,45 @@ void CodeGenPGO::mapRegionCounters(const
> >> >    FunctionHash = Walker.Hash.finalize();
> >> >  }
> >> >
> >> > +void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
> >> > +  if (SkipCoverageMapping)
> >> > +    return;
> >> > +  // Don't map the functions inside the system headers
> >> > +  auto Loc = D->getBody()->getLocStart();
> >> > +  if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
> >> > +    return;
> >> > +
> >> > +  llvm::raw_string_ostream OS(CoverageMapping);
> >> > +  CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
> >> > +                                CGM.getContext().getSourceManager(),
> >> > +                                CGM.getLangOpts(),
> >> > RegionCounterMap.get(),
> >> > +                                NumRegionCounters);
> >> > +  MappingGen.emitCounterMapping(D, OS);
> >> > +  OS.flush();
> >> > +}
> >> > +
> >> > +void
> >> > +CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef
> FuncName,
> >> > +                                    llvm::GlobalValue::LinkageTypes
> >> > Linkage) {
> >> > +  if (SkipCoverageMapping)
> >> > +    return;
> >> > +  setFuncName(FuncName, Linkage);
> >> > +  setVarLinkage(Linkage);
> >> > +
> >> > +  // Don't map the functions inside the system headers
> >> > +  auto Loc = D->getBody()->getLocStart();
> >> > +  if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
> >> > +    return;
> >> > +
> >> > +  llvm::raw_string_ostream OS(CoverageMapping);
> >> > +  CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
> >> > +                                CGM.getContext().getSourceManager(),
> >> > +                                CGM.getLangOpts());
> >> > +  MappingGen.emitEmptyMapping(D, OS);
> >> > +  OS.flush();
> >> > +  buildDataVar();
> >> > +}
> >> > +
> >> >  void CodeGenPGO::computeRegionCounts(const Decl *D) {
> >> >    StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
> >> >    ComputeRegionCounts Walker(*StmtCountMap, *this);
> >> >
> >> > Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.h
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CodeGenPGO.h (original)
> >> > +++ cfe/trunk/lib/CodeGen/CodeGenPGO.h Mon Aug  4 13:41:51 2014
> >> > @@ -42,11 +42,16 @@ private:
> >> >    std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>>
> StmtCountMap;
> >> >    std::unique_ptr<std::vector<uint64_t>> RegionCounts;
> >> >    uint64_t CurrentRegionCount;
> >> > +  std::string CoverageMapping;
> >> > +  /// \brief A flag that is set to true when this function doesn't
> need
> >> > +  /// to have coverage mapping data.
> >> > +  bool SkipCoverageMapping;
> >> >
> >> >  public:
> >> >    CodeGenPGO(CodeGenModule &CGM)
> >> >        : CGM(CGM), NumRegionCounters(0), FunctionHash(0),
> >> > -        RegionCounters(nullptr), CurrentRegionCount(0) {}
> >> > +        RegionCounters(nullptr), CurrentRegionCount(0),
> >> > +        SkipCoverageMapping(false) {}
> >> >
> >> >    /// Whether or not we have PGO region data for the current
> function.
> >> > This is
> >> >    /// false both when we have no data at all and when our data has
> been
> >> > @@ -99,6 +104,8 @@ public:
> >> >    llvm::MDNode *createBranchWeights(ArrayRef<uint64_t> Weights);
> >> >    llvm::MDNode *createLoopWeights(const Stmt *Cond, RegionCounter
> >> > &Cnt);
> >> >
> >> > +  /// Check if we need to emit coverage mapping for a given
> declaration
> >> > +  void checkGlobalDecl(GlobalDecl GD);
> >> >    /// Assign counters to regions and configure them for PGO of a
> given
> >> >    /// function. Does nothing if instrumentation is not enabled and
> >> > either
> >> >    /// generates global variables or associates PGO data with each of
> >> > the
> >> > @@ -111,9 +118,14 @@ public:
> >> >    void destroyRegionCounters();
> >> >    /// Emit static initialization code, if any.
> >> >    static llvm::Function *emitInitialization(CodeGenModule &CGM);
> >> > -
> >> > +  /// Emit a coverage mapping range with a counter zero
> >> > +  /// for an unused declaration.
> >> > +  void emitEmptyCounterMapping(const Decl *D, StringRef FuncName,
> >> > +                               llvm::GlobalValue::LinkageTypes
> >> > Linkage);
> >> >  private:
> >> >    void setFuncName(llvm::Function *Fn);
> >> > +  void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes
> >> > Linkage);
> >> > +  void setVarLinkage(llvm::GlobalValue::LinkageTypes Linkage);
> >> >    void mapRegionCounters(const Decl *D);
> >> >    void computeRegionCounts(const Decl *D);
> >> >    void applyFunctionAttributes(llvm::IndexedInstrProfReader
> *PGOReader,
> >> > @@ -122,6 +134,7 @@ private:
> >> >                          bool IsInMainFile);
> >> >    void emitCounterVariables();
> >> >    llvm::GlobalVariable *buildDataVar();
> >> > +  void emitCounterRegionMapping(const Decl *D);
> >> >
> >> >    /// Emit code to increment the counter at the given index
> >> >    void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter);
> >> >
> >> > Added: cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp?rev=214752&view=auto
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp (added)
> >> > +++ cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp Mon Aug  4 13:41:51
> >> > 2014
> >> > @@ -0,0 +1,1166 @@
> >> > +//===--- CoverageMappingGen.cpp - Coverage mapping generation ---*-
> C++
> >> > -*-===//
> >> > +//
> >> > +//                     The LLVM Compiler Infrastructure
> >> > +//
> >> > +// This file is distributed under the University of Illinois Open
> >> > Source
> >> > +// License. See LICENSE.TXT for details.
> >> > +//
> >> >
> >> >
> +//===----------------------------------------------------------------------===//
> >> > +//
> >> > +// Instrumentation-based code coverage mapping generator
> >> > +//
> >> >
> >> >
> +//===----------------------------------------------------------------------===//
> >> > +
> >> > +#include "CoverageMappingGen.h"
> >> > +#include "CodeGenFunction.h"
> >> > +#include "clang/AST/StmtVisitor.h"
> >> > +#include "clang/Lex/Lexer.h"
> >> > +#include "llvm/ProfileData/InstrProfReader.h"
> >> > +#include "llvm/ProfileData/CoverageMapping.h"
> >> > +#include "llvm/ProfileData/CoverageMappingWriter.h"
> >> > +#include "llvm/Support/FileSystem.h"
> >> > +
> >> > +using namespace clang;
> >> > +using namespace CodeGen;
> >> > +using namespace llvm::coverage;
> >> > +
> >> > +void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range) {
> >> > +  SkippedRanges.push_back(Range);
> >> > +}
> >> > +
> >> > +namespace {
> >> > +
> >> > +/// \brief A region of source code that can be mapped to a counter.
> >> > +struct SourceMappingRegion {
> >> > +  enum RegionFlags {
> >> > +    /// \brief This region won't be emitted if it wasn't extended.
> >> > +    /// This is useful so that we won't emit source ranges for single
> >> > tokens
> >> > +    /// that we don't really care that much about, like:
> >> > +    ///   the '(' token in #define MACRO (
> >> > +    IgnoreIfNotExtended = 0x0001,
> >> > +  };
> >> > +
> >> > +  FileID File, MacroArgumentFile;
> >> > +
> >> > +  Counter Count;
> >> > +
> >> > +  /// \brief A statement that initiated the count of Zero.
> >> > +  ///
> >> > +  /// This initiator statement is useful to prevent merging of
> >> > unreachable
> >> > +  /// regions with different statements that caused the counter to
> >> > become
> >> > +  /// unreachable.
> >> > +  const Stmt *UnreachableInitiator;
> >> > +
> >> > +  /// \brief A statement that separates certain mapping regions into
> >> > groups.
> >> > +  ///
> >> > +  /// The group statement is sometimes useful when we are emitting
> the
> >> > source
> >> > +  /// regions not in their correct lexical order, e.g. the regions
> for
> >> > the
> >> > +  /// incrementation expression in the 'for' construct. By marking
> the
> >> > regions
> >> > +  /// in the incrementation expression with the group statement, we
> >> > avoid the
> >> > +  /// merging of the regions from the incrementation expression and
> the
> >> > loop's
> >> > +  /// body.
> >> > +  const Stmt *Group;
> >> > +
> >> > +  /// \brief The region's starting location.
> >> > +  SourceLocation LocStart;
> >> > +
> >> > +  /// \brief The region's ending location.
> >> > +  SourceLocation LocEnd, AlternativeLocEnd;
> >> > +  unsigned Flags;
> >> > +  CounterMappingRegion::RegionKind Kind;
> >> > +
> >> > +  SourceMappingRegion(FileID File, FileID MacroArgumentFile, Counter
> >> > Count,
> >> > +                      const Stmt *UnreachableInitiator, const Stmt
> >> > *Group,
> >> > +                      SourceLocation LocStart, SourceLocation LocEnd,
> >> > +                      unsigned Flags = 0,
> >> > +                      CounterMappingRegion::RegionKind Kind =
> >> > +                          CounterMappingRegion::CodeRegion)
> >> > +      : File(File), MacroArgumentFile(MacroArgumentFile),
> Count(Count),
> >> > +        UnreachableInitiator(UnreachableInitiator), Group(Group),
> >> > +        LocStart(LocStart), LocEnd(LocEnd),
> >> > AlternativeLocEnd(LocStart),
> >> > +        Flags(Flags), Kind(Kind) {}
> >> > +
> >> > +  bool hasFlag(RegionFlags Flag) const { return (Flags & Flag) != 0;
> }
> >> > +
> >> > +  void setFlag(RegionFlags Flag) { Flags |= Flag; }
> >> > +
> >> > +  void clearFlag(RegionFlags Flag) { Flags &= ~Flag; }
> >> > +
> >> > +  /// \brief Return true if two regions can be merged together.
> >> > +  bool isMergeable(SourceMappingRegion &R) {
> >> > +    return File == R.File && MacroArgumentFile == R.MacroArgumentFile
> >> > &&
> >> > +           Count == R.Count && UnreachableInitiator ==
> >> > R.UnreachableInitiator &&
> >> > +           Group == R.Group && Kind == R.Kind;
> >> > +  }
> >> > +
> >> > +  /// \brief Merge two regions by extending the 'this' region to
> cover
> >> > the
> >> > +  /// given region.
> >> > +  void mergeByExtendingTo(SourceMappingRegion &R) {
> >> > +    LocEnd = R.LocEnd;
> >> > +    AlternativeLocEnd = R.LocStart;
> >> > +    if (hasFlag(IgnoreIfNotExtended))
> >> > +      clearFlag(IgnoreIfNotExtended);
> >> > +  }
> >> > +};
> >> > +
> >> > +/// \brief The state of the coverage mapping builder.
> >> > +struct SourceMappingState {
> >> > +  Counter CurrentRegionCount;
> >> > +  const Stmt *CurrentSourceGroup;
> >> > +  const Stmt *CurrentUnreachableRegionInitiator;
> >> > +
> >> > +  SourceMappingState(Counter CurrentRegionCount, const Stmt
> >> > *CurrentSourceGroup,
> >> > +                     const Stmt *CurrentUnreachableRegionInitiator)
> >> > +      : CurrentRegionCount(CurrentRegionCount),
> >> > +        CurrentSourceGroup(CurrentSourceGroup),
> >> > +
> >> > CurrentUnreachableRegionInitiator(CurrentUnreachableRegionInitiator)
> {}
> >> > +};
> >> > +
> >> > +/// \brief Provides the common functionality for the different
> >> > +/// coverage mapping region builders.
> >> > +class CoverageMappingBuilder {
> >> > +public:
> >> > +  CoverageMappingModuleGen &CVM;
> >> > +  SourceManager &SM;
> >> > +  const LangOptions &LangOpts;
> >> > +
> >> > +private:
> >> > +  struct FileInfo {
> >> > +    /// \brief The file id that will be used by the coverage mapping
> >> > system.
> >> > +    unsigned CovMappingFileID;
> >> > +    const FileEntry *Entry;
> >> > +
> >> > +    FileInfo(unsigned CovMappingFileID, const FileEntry *Entry)
> >> > +        : CovMappingFileID(CovMappingFileID), Entry(Entry) {}
> >> > +  };
> >> > +
> >> > +  /// \brief This mapping maps clang's FileIDs to file ids used
> >> > +  /// by the coverage mapping system and clang's file entries.
> >> > +  llvm::SmallDenseMap<FileID, FileInfo, 8> FileIDMapping;
> >> > +
> >> > +public:
> >> > +  /// \brief The statement that corresponds to the current source
> >> > group.
> >> > +  const Stmt *CurrentSourceGroup;
> >> > +
> >> > +  /// \brief The statement the initiated the current unreachable
> >> > region.
> >> > +  const Stmt *CurrentUnreachableRegionInitiator;
> >> > +
> >> > +  /// \brief The coverage mapping regions for this function
> >> > +  llvm::SmallVector<CounterMappingRegion, 32> MappingRegions;
> >> > +  /// \brief The source mapping regions for this function.
> >> > +  llvm::SmallVector<SourceMappingRegion, 32> SourceRegions;
> >> > +
> >> > +  CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager
> >> > &SM,
> >> > +                         const LangOptions &LangOpts)
> >> > +      : CVM(CVM), SM(SM), LangOpts(LangOpts),
> >> > +        CurrentSourceGroup(nullptr),
> >> > +        CurrentUnreachableRegionInitiator(nullptr) {}
> >> > +
> >> > +  /// \brief Return the precise end location for the given token.
> >> > +  SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) {
> >> > +    return Lexer::getLocForEndOfToken(SM.getSpellingLoc(Loc), 0, SM,
> >> > LangOpts);
> >> > +  }
> >> > +
> >> > +  /// \brief Create the mapping that maps from the function's file
> ids
> >> > to
> >> > +  /// the indices for the translation unit's filenames.
> >> > +  void createFileIDMapping(SmallVectorImpl<unsigned> &Mapping) {
> >> > +    Mapping.resize(FileIDMapping.size(), 0);
> >> > +    for (const auto &I : FileIDMapping)
> >> > +      Mapping[I.second.CovMappingFileID] =
> >> > CVM.getFileID(I.second.Entry);
> >> > +  }
> >> > +
> >> > +  /// \brief Get the coverage mapping file id that corresponds to the
> >> > given
> >> > +  /// clang file id. If such file id doesn't exist, it gets added to
> >> > the
> >> > +  /// mapping that maps from clang's file ids to coverage mapping
> file
> >> > ids.
> >> > +  /// Return true if there was an error getting the coverage mapping
> >> > file id.
> >> > +  /// An example of an when this function fails is when the region
> >> > tries
> >> > +  /// to get a coverage file id for a location in a built-in macro.
> >> > +  bool getCoverageFileID(SourceLocation LocStart, FileID File,
> >> > +                         FileID SpellingFile, unsigned &Result) {
> >> > +    auto Mapping = FileIDMapping.find(File);
> >> > +    if (Mapping != FileIDMapping.end()) {
> >> > +      Result = Mapping->second.CovMappingFileID;
> >> > +      return false;
> >> > +    }
> >> > +
> >> > +    auto Entry = SM.getFileEntryForID(SpellingFile);
> >> > +    if (!Entry)
> >> > +      return true;
> >> > +
> >> > +    Result = FileIDMapping.size();
> >> > +    FileIDMapping.insert(std::make_pair(File, FileInfo(Result,
> >> > Entry)));
> >> > +    createFileExpansionRegion(LocStart, File);
> >> > +    return false;
> >> > +  }
> >> > +
> >> > +  /// \brief Get the coverage mapping file id that corresponds to the
> >> > given
> >> > +  /// clang file id.
> >> > +  /// Return true if there was an error getting the coverage mapping
> >> > file id.
> >> > +  bool getExistingCoverageFileID(FileID File, unsigned &Result) {
> >> > +    // Make sure that the file is valid.
> >> > +    if (File.isInvalid())
> >> > +      return true;
> >> > +    auto Mapping = FileIDMapping.find(File);
> >> > +    if (Mapping != FileIDMapping.end()) {
> >> > +      Result = Mapping->second.CovMappingFileID;
> >> > +      return false;
> >> > +    }
> >> > +    return true;
> >> > +  }
> >> > +
> >> > +  /// \brief Return true if the given clang's file id has a
> >> > corresponding
> >> > +  /// coverage file id.
> >> > +  bool hasExistingCoverageFileID(FileID File) const {
> >> > +    return FileIDMapping.count(File);
> >> > +  }
> >> > +
> >> > +  /// \brief Gather all the regions that were skipped by the
> >> > preprocessor
> >> > +  /// using the constructs like #if.
> >> > +  void gatherSkippedRegions() {
> >> > +    /// An array of the minimum lineStarts and the maximum lineEnds
> >> > +    /// for mapping regions from the appropriate source files.
> >> > +    llvm::SmallVector<std::pair<unsigned, unsigned>, 8>
> FileLineRanges;
> >> > +    FileLineRanges.resize(
> >> > +        FileIDMapping.size(),
> >> > +        std::make_pair(std::numeric_limits<unsigned>::max(), 0));
> >> > +    for (const auto &R : MappingRegions) {
> >> > +      FileLineRanges[R.FileID].first =
> >> > +          std::min(FileLineRanges[R.FileID].first, R.LineStart);
> >> > +      FileLineRanges[R.FileID].second =
> >> > +          std::max(FileLineRanges[R.FileID].second, R.LineEnd);
> >> > +    }
> >> > +
> >> > +    auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
> >> > +    for (const auto &I : SkippedRanges) {
> >> > +      auto LocStart = I.getBegin();
> >> > +      auto LocEnd = I.getEnd();
> >> > +      auto FileStart = SM.getFileID(LocStart);
> >> > +      if (!hasExistingCoverageFileID(FileStart))
> >> > +        continue;
> >> > +      auto ActualFileStart =
> >> > SM.getDecomposedSpellingLoc(LocStart).first;
> >> > +      if (ActualFileStart !=
> SM.getDecomposedSpellingLoc(LocEnd).first)
> >> > +        // Ignore regions that span across multiple files.
> >> > +        continue;
> >> > +
> >> > +      unsigned CovFileID;
> >> > +      if (getCoverageFileID(LocStart, FileStart, ActualFileStart,
> >> > CovFileID))
> >> > +        continue;
> >> > +      unsigned LineStart = SM.getSpellingLineNumber(LocStart);
> >> > +      unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
> >> > +      unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
> >> > +      unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
> >> > +      CounterMappingRegion Region(Counter(), CovFileID, LineStart,
> >> > ColumnStart,
> >> > +                                  LineEnd, ColumnEnd, false,
> >> > +
>  CounterMappingRegion::SkippedRegion);
> >> > +      // Make sure that we only collect the regions that are inside
> >> > +      // the souce code of this function.
> >> > +      if (Region.LineStart >= FileLineRanges[CovFileID].first &&
> >> > +          Region.LineEnd <= FileLineRanges[CovFileID].second)
> >> > +        MappingRegions.push_back(Region);
> >> > +    }
> >> > +  }
> >> > +
> >> > +  /// \brief Create a mapping region that correponds to an expansion
> of
> >> > +  /// a macro or an embedded include.
> >> > +  void createFileExpansionRegion(SourceLocation Loc, FileID
> >> > ExpandedFile) {
> >> > +    SourceLocation LocStart;
> >> > +    if (Loc.isMacroID())
> >> > +      LocStart = SM.getImmediateExpansionRange(Loc).first;
> >> > +    else {
> >> > +      LocStart = SM.getIncludeLoc(ExpandedFile);
> >> > +      if (LocStart.isInvalid())
> >> > +        return; // This file has no expansion region.
> >> > +    }
> >> > +
> >> > +    auto File = SM.getFileID(LocStart);
> >> > +    auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first;
> >> > +    unsigned CovFileID, ExpandedFileID;
> >> > +    if (getExistingCoverageFileID(ExpandedFile, ExpandedFileID))
> >> > +      return;
> >> > +    if (getCoverageFileID(LocStart, File, SpellingFile, CovFileID))
> >> > +      return;
> >> > +    unsigned LineStart = SM.getSpellingLineNumber(LocStart);
> >> > +    unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
> >> > +    unsigned LineEnd = LineStart;
> >> > +    // Compute the end column manually as Lexer::getLocForEndOfToken
> >> > doesn't
> >> > +    // give the correct result in all cases.
> >> > +    unsigned ColumnEnd =
> >> > +        ColumnStart +
> >> > +        Lexer::MeasureTokenLength(SM.getSpellingLoc(LocStart), SM,
> >> > LangOpts);
> >> > +
> >> > +    MappingRegions.push_back(CounterMappingRegion(
> >> > +        Counter(), CovFileID, LineStart, ColumnStart, LineEnd,
> >> > ColumnEnd,
> >> > +        false, CounterMappingRegion::ExpansionRegion));
> >> > +    MappingRegions.back().ExpandedFileID = ExpandedFileID;
> >> > +  }
> >> > +
> >> > +  /// \brief Enter a source region group that is identified by the
> >> > given
> >> > +  /// statement.
> >> > +  /// It's not possible to enter a group when there is already
> >> > +  /// another group present.
> >> > +  void beginSourceRegionGroup(const Stmt *Group) {
> >> > +    assert(!CurrentSourceGroup);
> >> > +    CurrentSourceGroup = Group;
> >> > +  }
> >> > +
> >> > +  /// \brief Exit the current source region group.
> >> > +  void endSourceRegionGroup() { CurrentSourceGroup = nullptr; }
> >> > +
> >> > +  /// \brief Brings a region that has the same counter and file to
> the
> >> > back
> >> > +  /// of the source regions array.
> >> > +  void bringSimilarRegionBack(Counter Count, FileID File,
> >> > +                              FileID MacroArgumentFile,
> >> > +                              const Stmt *UnreachableInitiator,
> >> > +                              const Stmt *SourceGroup) {
> >> > +    for (size_t I = SourceRegions.size(); I != 0;) {
> >> > +      --I;
> >> > +      if (SourceRegions[I].Count == Count && SourceRegions[I].File ==
> >> > File &&
> >> > +          SourceRegions[I].MacroArgumentFile == MacroArgumentFile &&
> >> > +          SourceRegions[I].UnreachableInitiator ==
> UnreachableInitiator
> >> > &&
> >> > +          SourceRegions[I].Group == SourceGroup) {
> >> > +        if (I != SourceRegions.size() - 1)
> >> > +          std::swap(SourceRegions[I], SourceRegions.back());
> >> > +        return;
> >> > +      }
> >> > +    }
> >> > +  }
> >> > +
> >> > +  /// \brief Associate a counter with a given source code range.
> >> > +  void mapSourceCodeRange(SourceLocation LocStart, SourceLocation
> >> > LocEnd,
> >> > +                          Counter Count, const Stmt
> >> > *UnreachableInitiator,
> >> > +                          const Stmt *SourceGroup, unsigned Flags =
> 0,
> >> > +                          FileID MacroArgumentFile = FileID()) {
> >> > +    if (SM.isMacroArgExpansion(LocStart)) {
> >> > +      // Map the code range with the macro argument's value.
> >> > +      mapSourceCodeRange(SM.getImmediateSpellingLoc(LocStart),
> >> > +                         SM.getImmediateSpellingLoc(LocEnd), Count,
> >> > +                         UnreachableInitiator, SourceGroup, Flags,
> >> > +                         SM.getFileID(LocStart));
> >> > +      // Map the code range where the macro argument is referenced.
> >> > +      SourceLocation
> >> > RefLocStart(SM.getImmediateExpansionRange(LocStart).first);
> >> > +      SourceLocation RefLocEnd(RefLocStart);
> >> > +      if (SM.isMacroArgExpansion(RefLocStart))
> >> > +        mapSourceCodeRange(RefLocStart, RefLocEnd, Count,
> >> > UnreachableInitiator,
> >> > +                           SourceGroup, 0,
> SM.getFileID(RefLocStart));
> >> > +      else
> >> > +        mapSourceCodeRange(RefLocStart, RefLocEnd, Count,
> >> > UnreachableInitiator,
> >> > +                           SourceGroup);
> >> > +      return;
> >> > +    }
> >> > +    auto File = SM.getFileID(LocStart);
> >> > +    // Make sure that the file id is valid.
> >> > +    if (File.isInvalid())
> >> > +      return;
> >> > +    bringSimilarRegionBack(Count, File, MacroArgumentFile,
> >> > UnreachableInitiator,
> >> > +                           SourceGroup);
> >> > +    SourceMappingRegion R(File, MacroArgumentFile, Count,
> >> > UnreachableInitiator,
> >> > +                          SourceGroup, LocStart, LocEnd, Flags);
> >> > +    if (SourceRegions.empty() ||
> !SourceRegions.back().isMergeable(R))
> >> > {
> >> > +      SourceRegions.push_back(R);
> >> > +      return;
> >> > +    }
> >> > +    SourceRegions.back().mergeByExtendingTo(R);
> >> > +  }
> >> > +
> >> > +  void mapSourceCodeRange(SourceLocation LocStart, SourceLocation
> >> > LocEnd,
> >> > +                          Counter Count, unsigned Flags = 0) {
> >> > +    mapSourceCodeRange(LocStart, LocEnd, Count,
> >> > +                       CurrentUnreachableRegionInitiator,
> >> > CurrentSourceGroup,
> >> > +                       Flags);
> >> > +  }
> >> > +
> >> > +  void mapSourceCodeRange(const SourceMappingState &State,
> >> > +                          SourceLocation LocStart, SourceLocation
> >> > LocEnd,
> >> > +                          unsigned Flags = 0) {
> >> > +    mapSourceCodeRange(LocStart, LocEnd, State.CurrentRegionCount,
> >> > +                       State.CurrentUnreachableRegionInitiator,
> >> > +                       State.CurrentSourceGroup, Flags);
> >> > +  }
> >> > +
> >> > +  /// \brief Generate the coverage counter mapping regions from
> >> > collected
> >> > +  /// source regions.
> >> > +  void emitSourceRegions() {
> >> > +    for (const auto &R : SourceRegions) {
> >> > +      SourceLocation LocStart = R.LocStart;
> >> > +      SourceLocation LocEnd = R.LocEnd;
> >> > +      if (SM.getFileID(LocEnd) != R.File)
> >> > +        LocEnd = R.AlternativeLocEnd;
> >> > +
> >> > +      if (R.hasFlag(SourceMappingRegion::IgnoreIfNotExtended) &&
> >> > +          LocStart == LocEnd)
> >> > +        continue;
> >> > +
> >> > +      LocEnd = getPreciseTokenLocEnd(LocEnd);
> >> > +      unsigned LineStart = SM.getSpellingLineNumber(LocStart);
> >> > +      unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
> >> > +      unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
> >> > +      unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
> >> > +
> >> > +      auto SpellingFile =
> >> > SM.getDecomposedSpellingLoc(R.LocStart).first;
> >> > +      unsigned CovFileID;
> >> > +      if (getCoverageFileID(R.LocStart, R.File, SpellingFile,
> >> > CovFileID))
> >> > +        continue;
> >> > +
> >> > +      assert(LineStart <= LineEnd);
> >> > +      MappingRegions.push_back(CounterMappingRegion(
> >> > +          R.Count, CovFileID, LineStart, ColumnStart, LineEnd,
> >> > ColumnEnd,
> >> > +          false, CounterMappingRegion::CodeRegion));
> >> > +    }
> >> > +  }
> >> > +};
> >> > +
> >> > +/// \brief Creates unreachable coverage regions for the functions
> that
> >> > +/// are not emitted.
> >> > +struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
> >> > +  EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM,
> >> > SourceManager &SM,
> >> > +                              const LangOptions &LangOpts)
> >> > +      : CoverageMappingBuilder(CVM, SM, LangOpts) {}
> >> > +
> >> > +  void VisitDecl(const Decl *D) {
> >> > +    if (!D->hasBody())
> >> > +      return;
> >> > +    auto Body = D->getBody();
> >> > +    mapSourceCodeRange(Body->getLocStart(), Body->getLocEnd(),
> >> > Counter());
> >> > +  }
> >> > +
> >> > +  /// \brief Write the mapping data to the output stream
> >> > +  void write(llvm::raw_ostream &OS) {
> >> > +    emitSourceRegions();
> >> > +    SmallVector<unsigned, 16> FileIDMapping;
> >> > +    createFileIDMapping(FileIDMapping);
> >> > +
> >> > +    CoverageMappingWriter Writer(
> >> > +        FileIDMapping, ArrayRef<CounterExpression>(),
> MappingRegions);
> >> > +    Writer.write(OS);
> >> > +  }
> >> > +};
> >> > +
> >> > +/// \brief A StmtVisitor that creates coverage mapping regions which
> >> > map
> >> > +/// from the source code locations to the PGO counters.
> >> > +struct CounterCoverageMappingBuilder
> >> > +    : public CoverageMappingBuilder,
> >> > +      public ConstStmtVisitor<CounterCoverageMappingBuilder> {
> >> > +  /// \brief The map of statements to count values.
> >> > +  llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
> >> > +
> >> > +  Counter CurrentRegionCount;
> >> > +
> >> > +  CounterExpressionBuilder Builder;
> >> > +
> >> > +  /// \brief Return a counter that represents the
> >> > +  /// expression that subracts rhs from lhs.
> >> > +  Counter subtractCounters(Counter LHS, Counter RHS) {
> >> > +    return Builder.subtract(LHS, RHS);
> >> > +  }
> >> > +
> >> > +  /// \brief Return a counter that represents the
> >> > +  /// the exression that adds lhs and rhs.
> >> > +  Counter addCounters(Counter LHS, Counter RHS) {
> >> > +    return Builder.add(LHS, RHS);
> >> > +  }
> >> > +
> >> > +  /// \brief Return the region counter for the given statement.
> >> > +  /// This should only be called on statements that have a dedicated
> >> > counter.
> >> > +  unsigned getRegionCounter(const Stmt *S) { return CounterMap[S]; }
> >> > +
> >> > +  /// \brief Return the region count for the counter at the given
> >> > index.
> >> > +  Counter getRegionCount(unsigned CounterId) {
> >> > +    return Counter::getCounter(CounterId);
> >> > +  }
> >> > +
> >> > +  /// \brief Return the counter value of the current region.
> >> > +  Counter getCurrentRegionCount() { return CurrentRegionCount; }
> >> > +
> >> > +  /// \brief Set the counter value for the current region.
> >> > +  /// This is used to keep track of changes to the most recent
> counter
> >> > +  /// from control flow and non-local exits.
> >> > +  void setCurrentRegionCount(Counter Count) {
> >> > +    CurrentRegionCount = Count;
> >> > +    CurrentUnreachableRegionInitiator = nullptr;
> >> > +  }
> >> > +
> >> > +  /// \brief Indicate that the current region is never reached,
> >> > +  /// and thus should have a counter value of zero.
> >> > +  /// This is important so that subsequent regions can correctly
> track
> >> > +  /// their parent counts.
> >> > +  void setCurrentRegionUnreachable(const Stmt *Initiator) {
> >> > +    CurrentRegionCount = Counter::getZero();
> >> > +    CurrentUnreachableRegionInitiator = Initiator;
> >> > +  }
> >> > +
> >> > +  /// \brief A counter for a particular region.
> >> > +  /// This is the primary interface through
> >> > +  /// which the coverage mapping builder manages counters and their
> >> > values.
> >> > +  class RegionMapper {
> >> > +    CounterCoverageMappingBuilder &Mapping;
> >> > +    Counter Count;
> >> > +    Counter ParentCount;
> >> > +    Counter RegionCount;
> >> > +    Counter Adjust;
> >> > +
> >> > +  public:
> >> > +    RegionMapper(CounterCoverageMappingBuilder *Mapper, const Stmt
> *S)
> >> > +        : Mapping(*Mapper),
> >> > +          Count(Mapper->getRegionCount(Mapper->getRegionCounter(S))),
> >> > +          ParentCount(Mapper->getCurrentRegionCount()) {}
> >> > +
> >> > +    /// Get the value of the counter. In most cases this is the
> number
> >> > of times
> >> > +    /// the region of the counter was entered, but for switch labels
> >> > it's the
> >> > +    /// number of direct jumps to that label.
> >> > +    Counter getCount() const { return Count; }
> >> > +
> >> > +    /// Get the value of the counter with adjustments applied.
> >> > Adjustments occur
> >> > +    /// when control enters or leaves the region abnormally; i.e., if
> >> > there is a
> >> > +    /// jump to a label within the region, or if the function can
> >> > return from
> >> > +    /// within the region. The adjusted count, then, is the value of
> >> > the counter
> >> > +    /// at the end of the region.
> >> > +    Counter getAdjustedCount() const {
> >> > +      return Mapping.addCounters(Count, Adjust);
> >> > +    }
> >> > +
> >> > +    /// Get the value of the counter in this region's parent, i.e.,
> the
> >> > region
> >> > +    /// that was active when this region began. This is useful for
> >> > deriving
> >> > +    /// counts in implicitly counted regions, like the false case of
> a
> >> > condition
> >> > +    /// or the normal exits of a loop.
> >> > +    Counter getParentCount() const { return ParentCount; }
> >> > +
> >> > +    /// Activate the counter by emitting an increment and starting to
> >> > track
> >> > +    /// adjustments. If AddIncomingFallThrough is true, the current
> >> > region count
> >> > +    /// will be added to the counter for the purposes of tracking the
> >> > region.
> >> > +    void beginRegion(bool AddIncomingFallThrough = false) {
> >> > +      RegionCount = Count;
> >> > +      if (AddIncomingFallThrough)
> >> > +        RegionCount =
> >> > +            Mapping.addCounters(RegionCount,
> >> > Mapping.getCurrentRegionCount());
> >> > +      Mapping.setCurrentRegionCount(RegionCount);
> >> > +    }
> >> > +
> >> > +    /// For counters on boolean branches, begins tracking adjustments
> >> > for the
> >> > +    /// uncounted path.
> >> > +    void beginElseRegion() {
> >> > +      RegionCount = Mapping.subtractCounters(ParentCount, Count);
> >> > +      Mapping.setCurrentRegionCount(RegionCount);
> >> > +    }
> >> > +
> >> > +    /// Reset the current region count.
> >> > +    void setCurrentRegionCount(Counter CurrentCount) {
> >> > +      RegionCount = CurrentCount;
> >> > +      Mapping.setCurrentRegionCount(RegionCount);
> >> > +    }
> >> > +
> >> > +    /// Adjust for non-local control flow after emitting a
> >> > subexpression or
> >> > +    /// substatement. This must be called to account for constructs
> >> > such as
> >> > +    /// gotos,
> >> > +    /// labels, and returns, so that we can ensure that our region's
> >> > count is
> >> > +    /// correct in the code that follows.
> >> > +    void adjustForControlFlow() {
> >> > +      Adjust = Mapping.addCounters(
> >> > +          Adjust,
> >> > Mapping.subtractCounters(Mapping.getCurrentRegionCount(),
> >> > +                                           RegionCount));
> >> > +      // Reset the region count in case this is called again later.
> >> > +      RegionCount = Mapping.getCurrentRegionCount();
> >> > +    }
> >> > +
> >> > +    /// Commit all adjustments to the current region. If the region
> is
> >> > a loop,
> >> > +    /// the LoopAdjust value should be the count of all the breaks
> and
> >> > continues
> >> > +    /// from the loop, to compensate for those counts being deducted
> >> > from the
> >> > +    /// adjustments for the body of the loop.
> >> > +    void applyAdjustmentsToRegion() {
> >> > +      Mapping.setCurrentRegionCount(Mapping.addCounters(ParentCount,
> >> > Adjust));
> >> > +    }
> >> > +    void applyAdjustmentsToRegion(Counter LoopAdjust) {
> >> > +      Mapping.setCurrentRegionCount(Mapping.addCounters(
> >> > +          Mapping.addCounters(ParentCount, Adjust), LoopAdjust));
> >> > +    }
> >> > +  };
> >> > +
> >> > +  /// \brief Keep counts of breaks and continues inside loops.
> >> > +  struct BreakContinue {
> >> > +    Counter BreakCount;
> >> > +    Counter ContinueCount;
> >> > +  };
> >> > +  SmallVector<BreakContinue, 8> BreakContinueStack;
> >> > +
> >> > +  CounterCoverageMappingBuilder(
> >> > +      CoverageMappingModuleGen &CVM,
> >> > +      llvm::DenseMap<const Stmt *, unsigned> &CounterMap,
> >> > +      unsigned NumRegionCounters, SourceManager &SM,
> >> > +      const LangOptions &LangOpts)
> >> > +      : CoverageMappingBuilder(CVM, SM, LangOpts),
> >> > CounterMap(CounterMap),
> >> > +        Builder(NumRegionCounters) {}
> >> > +
> >> > +  /// \brief Write the mapping data to the output stream
> >> > +  void write(llvm::raw_ostream &OS) {
> >> > +    emitSourceRegions();
> >> > +    llvm::SmallVector<unsigned, 8> VirtualFileMapping;
> >> > +    createFileIDMapping(VirtualFileMapping);
> >> > +    gatherSkippedRegions();
> >> > +
> >> > +    CoverageMappingWriter Writer(
> >> > +        VirtualFileMapping, Builder.getExpressions(),
> MappingRegions);
> >> > +    Writer.write(OS);
> >> > +  }
> >> > +
> >> > +  /// \brief Return the current source mapping state.
> >> > +  SourceMappingState getCurrentState() const {
> >> > +    return SourceMappingState(CurrentRegionCount, CurrentSourceGroup,
> >> > +                              CurrentUnreachableRegionInitiator);
> >> > +  }
> >> > +
> >> > +  /// \brief Associate the source code range with the current region
> >> > count.
> >> > +  void mapSourceCodeRange(SourceLocation LocStart, SourceLocation
> >> > LocEnd,
> >> > +                          unsigned Flags = 0) {
> >> > +    CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocEnd,
> >> > +                                               CurrentRegionCount,
> >> > Flags);
> >> > +  }
> >> > +
> >> > +  void mapSourceCodeRange(SourceLocation LocStart) {
> >> > +    CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocStart,
> >> > +                                               CurrentRegionCount);
> >> > +  }
> >> > +
> >> > +  /// \brief Associate the source range of a token with the current
> >> > region
> >> > +  /// count.
> >> > +  /// Ignore the source range for this token if it produces a
> distinct
> >> > +  /// mapping region with no other source ranges.
> >> > +  void mapToken(SourceLocation LocStart) {
> >> > +    CoverageMappingBuilder::mapSourceCodeRange(
> >> > +        LocStart, LocStart, CurrentRegionCount,
> >> > +        SourceMappingRegion::IgnoreIfNotExtended);
> >> > +  }
> >> > +
> >> > +  void mapToken(const SourceMappingState &State, SourceLocation
> >> > LocStart) {
> >> > +    CoverageMappingBuilder::mapSourceCodeRange(
> >> > +        State, LocStart, LocStart,
> >> > SourceMappingRegion::IgnoreIfNotExtended);
> >> > +  }
> >> > +
> >> > +  void VisitStmt(const Stmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    for (Stmt::const_child_range I = S->children(); I; ++I) {
> >> > +      if (*I)
> >> > +        this->Visit(*I);
> >> > +    }
> >> > +  }
> >> > +
> >> > +  /// \brief If the given statement is a compound statement,
> >> > +  /// map '}' with the same count as '{'.
> >> > +  void VisitSubStmtRBraceState(const Stmt *S) {
> >> > +    if (!isa<CompoundStmt>(S))
> >> > +      return Visit(S);
> >> > +    const auto *CS = cast<CompoundStmt>(S);
> >> > +    auto State = getCurrentState();
> >> > +    mapSourceCodeRange(CS->getLBracLoc());
> >> > +    for (Stmt::const_child_range I = S->children(); I; ++I) {
> >> > +      if (*I)
> >> > +        this->Visit(*I);
> >> > +    }
> >> > +    CoverageMappingBuilder::mapSourceCodeRange(State,
> >> > CS->getRBracLoc(),
> >> > +                                               CS->getRBracLoc());
> >> > +  }
> >> > +
> >> > +  void VisitDecl(const Decl *D) {
> >> > +    if (!D->hasBody())
> >> > +      return;
> >> > +    // Counter tracks entry to the function body.
> >> > +    auto Body = D->getBody();
> >> > +    RegionMapper Cnt(this, Body);
> >> > +    Cnt.beginRegion();
> >> > +    VisitSubStmtRBraceState(Body);
> >> > +  }
> >> > +
> >> > +  void VisitDeclStmt(const DeclStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    for (Stmt::const_child_range I = static_cast<const Stmt
> >> > *>(S)->children();
> >> > +         I; ++I) {
> >> > +      if (*I)
> >> > +        this->Visit(*I);
> >> > +    }
> >> > +  }
> >> > +
> >> > +  void VisitCompoundStmt(const CompoundStmt *S) {
> >> > +    mapSourceCodeRange(S->getLBracLoc());
> >> > +    for (Stmt::const_child_range I = S->children(); I; ++I) {
> >> > +      if (*I)
> >> > +        this->Visit(*I);
> >> > +    }
> >> > +    mapSourceCodeRange(S->getRBracLoc(), S->getRBracLoc());
> >> > +  }
> >> > +
> >> > +  void VisitReturnStmt(const ReturnStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    if (S->getRetValue())
> >> > +      Visit(S->getRetValue());
> >> > +    setCurrentRegionUnreachable(S);
> >> > +  }
> >> > +
> >> > +  void VisitGotoStmt(const GotoStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    mapToken(S->getLabelLoc());
> >> > +    setCurrentRegionUnreachable(S);
> >> > +  }
> >> > +
> >> > +  void VisitLabelStmt(const LabelStmt *S) {
> >> > +    // Counter tracks the block following the label.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    Cnt.beginRegion();
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    // Can't map the ':' token as its location isn't known.
> >> > +    Visit(S->getSubStmt());
> >> > +  }
> >> > +
> >> > +  void VisitBreakStmt(const BreakStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    assert(!BreakContinueStack.empty() && "break not in a loop or
> >> > switch!");
> >> > +    BreakContinueStack.back().BreakCount = addCounters(
> >> > +        BreakContinueStack.back().BreakCount,
> getCurrentRegionCount());
> >> > +    setCurrentRegionUnreachable(S);
> >> > +  }
> >> > +
> >> > +  void VisitContinueStmt(const ContinueStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    assert(!BreakContinueStack.empty() && "continue stmt not in a
> >> > loop!");
> >> > +    BreakContinueStack.back().ContinueCount = addCounters(
> >> > +        BreakContinueStack.back().ContinueCount,
> >> > getCurrentRegionCount());
> >> > +    setCurrentRegionUnreachable(S);
> >> > +  }
> >> > +
> >> > +  void VisitWhileStmt(const WhileStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    // Counter tracks the body of the loop.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    BreakContinueStack.push_back(BreakContinue());
> >> > +    // Visit the body region first so the break/continue adjustments
> >> > can be
> >> > +    // included when visiting the condition.
> >> > +    Cnt.beginRegion();
> >> > +    VisitSubStmtRBraceState(S->getBody());
> >> > +    Cnt.adjustForControlFlow();
> >> > +
> >> > +    // ...then go back and propagate counts through the condition.
> The
> >> > count
> >> > +    // at the start of the condition is the sum of the incoming
> edges,
> >> > +    // the backedge from the end of the loop body, and the edges from
> >> > +    // continue statements.
> >> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> >> > +    Cnt.setCurrentRegionCount(
> >> > +        addCounters(Cnt.getParentCount(),
> >> > +                    addCounters(Cnt.getAdjustedCount(),
> >> > BC.ContinueCount)));
> >> > +    beginSourceRegionGroup(S->getCond());
> >> > +    Visit(S->getCond());
> >> > +    endSourceRegionGroup();
> >> > +    Cnt.adjustForControlFlow();
> >> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> >> > BC.ContinueCount));
> >> > +  }
> >> > +
> >> > +  void VisitDoStmt(const DoStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    // Counter tracks the body of the loop.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    BreakContinueStack.push_back(BreakContinue());
> >> > +    Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
> >> > +    VisitSubStmtRBraceState(S->getBody());
> >> > +    Cnt.adjustForControlFlow();
> >> > +
> >> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> >> > +    // The count at the start of the condition is equal to the count
> at
> >> > the
> >> > +    // end of the body. The adjusted count does not include either
> the
> >> > +    // fall-through count coming into the loop or the continue count,
> >> > so add
> >> > +    // both of those separately. This is coincidentally the same
> >> > equation as
> >> > +    // with while loops but for different reasons.
> >> > +    Cnt.setCurrentRegionCount(
> >> > +        addCounters(Cnt.getParentCount(),
> >> > +                    addCounters(Cnt.getAdjustedCount(),
> >> > BC.ContinueCount)));
> >> > +    Visit(S->getCond());
> >> > +    Cnt.adjustForControlFlow();
> >> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> >> > BC.ContinueCount));
> >> > +  }
> >> > +
> >> > +  void VisitForStmt(const ForStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    if (S->getInit())
> >> > +      Visit(S->getInit());
> >> > +
> >> > +    // Counter tracks the body of the loop.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    BreakContinueStack.push_back(BreakContinue());
> >> > +    // Visit the body region first. (This is basically the same as a
> >> > while
> >> > +    // loop; see further comments in VisitWhileStmt.)
> >> > +    Cnt.beginRegion();
> >> > +    VisitSubStmtRBraceState(S->getBody());
> >> > +    Cnt.adjustForControlFlow();
> >> > +
> >> > +    // The increment is essentially part of the body but it needs to
> >> > include
> >> > +    // the count for all the continue statements.
> >> > +    if (S->getInc()) {
> >> > +      Cnt.setCurrentRegionCount(addCounters(
> >> > +          getCurrentRegionCount(),
> >> > BreakContinueStack.back().ContinueCount));
> >> > +      beginSourceRegionGroup(S->getInc());
> >> > +      Visit(S->getInc());
> >> > +      endSourceRegionGroup();
> >> > +      Cnt.adjustForControlFlow();
> >> > +    }
> >> > +
> >> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> >> > +
> >> > +    // ...then go back and propagate counts through the condition.
> >> > +    if (S->getCond()) {
> >> > +      Cnt.setCurrentRegionCount(
> >> > +          addCounters(addCounters(Cnt.getParentCount(),
> >> > Cnt.getAdjustedCount()),
> >> > +                      BC.ContinueCount));
> >> > +      beginSourceRegionGroup(S->getCond());
> >> > +      Visit(S->getCond());
> >> > +      endSourceRegionGroup();
> >> > +      Cnt.adjustForControlFlow();
> >> > +    }
> >> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> >> > BC.ContinueCount));
> >> > +  }
> >> > +
> >> > +  void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    Visit(S->getRangeStmt());
> >> > +    Visit(S->getBeginEndStmt());
> >> > +    // Counter tracks the body of the loop.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    BreakContinueStack.push_back(BreakContinue());
> >> > +    // Visit the body region first. (This is basically the same as a
> >> > while
> >> > +    // loop; see further comments in VisitWhileStmt.)
> >> > +    Cnt.beginRegion();
> >> > +    VisitSubStmtRBraceState(S->getBody());
> >> > +    Cnt.adjustForControlFlow();
> >> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> >> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> >> > BC.ContinueCount));
> >> > +  }
> >> > +
> >> > +  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    Visit(S->getElement());
> >> > +    // Counter tracks the body of the loop.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    BreakContinueStack.push_back(BreakContinue());
> >> > +    VisitSubStmtRBraceState(S->getBody());
> >> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> >> > +    Cnt.adjustForControlFlow();
> >> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> >> > BC.ContinueCount));
> >> > +  }
> >> > +
> >> > +  void VisitSwitchStmt(const SwitchStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    Visit(S->getCond());
> >> > +    BreakContinueStack.push_back(BreakContinue());
> >> > +    // Map the '}' for the body to have the same count as the regions
> >> > after
> >> > +    // the switch.
> >> > +    SourceLocation RBracLoc;
> >> > +    if (const auto *CS = dyn_cast<CompoundStmt>(S->getBody())) {
> >> > +      mapSourceCodeRange(CS->getLBracLoc());
> >> > +      setCurrentRegionUnreachable(S);
> >> > +      for (Stmt::const_child_range I = CS->children(); I; ++I) {
> >> > +        if (*I)
> >> > +          this->Visit(*I);
> >> > +      }
> >> > +      RBracLoc = CS->getRBracLoc();
> >> > +    } else {
> >> > +      setCurrentRegionUnreachable(S);
> >> > +      Visit(S->getBody());
> >> > +    }
> >> > +    // If the switch is inside a loop, add the continue counts.
> >> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> >> > +    if (!BreakContinueStack.empty())
> >> > +      BreakContinueStack.back().ContinueCount = addCounters(
> >> > +          BreakContinueStack.back().ContinueCount, BC.ContinueCount);
> >> > +    // Counter tracks the exit block of the switch.
> >> > +    RegionMapper ExitCnt(this, S);
> >> > +    ExitCnt.beginRegion();
> >> > +    if (RBracLoc.isValid())
> >> > +      mapSourceCodeRange(RBracLoc);
> >> > +  }
> >> > +
> >> > +  void VisitCaseStmt(const CaseStmt *S) {
> >> > +    // Counter for this particular case. This counts only jumps from
> >> > the
> >> > +    // switch header and does not include fallthrough from the case
> >> > before
> >> > +    // this one.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    mapToken(S->getColonLoc());
> >> > +    Visit(S->getSubStmt());
> >> > +  }
> >> > +
> >> > +  void VisitDefaultStmt(const DefaultStmt *S) {
> >> > +    // Counter for this default case. This does not include
> fallthrough
> >> > from
> >> > +    // the previous case.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    mapToken(S->getColonLoc());
> >> > +    Visit(S->getSubStmt());
> >> > +  }
> >> > +
> >> > +  void VisitIfStmt(const IfStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    Visit(S->getCond());
> >> > +    mapToken(S->getElseLoc());
> >> > +
> >> > +    // Counter tracks the "then" part of an if statement. The count
> for
> >> > +    // the "else" part, if it exists, will be calculated from this
> >> > counter.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    Cnt.beginRegion();
> >> > +    VisitSubStmtRBraceState(S->getThen());
> >> > +    Cnt.adjustForControlFlow();
> >> > +
> >> > +    if (S->getElse()) {
> >> > +      Cnt.beginElseRegion();
> >> > +      VisitSubStmtRBraceState(S->getElse());
> >> > +      Cnt.adjustForControlFlow();
> >> > +    }
> >> > +    Cnt.applyAdjustmentsToRegion();
> >> > +  }
> >> > +
> >> > +  void VisitCXXTryStmt(const CXXTryStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    Visit(S->getTryBlock());
> >> > +    for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
> >> > +      Visit(S->getHandler(I));
> >> > +    // Counter tracks the continuation block of the try statement.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    Cnt.beginRegion();
> >> > +  }
> >> > +
> >> > +  void VisitCXXCatchStmt(const CXXCatchStmt *S) {
> >> > +    mapSourceCodeRange(S->getLocStart());
> >> > +    // Counter tracks the catch statement's handler block.
> >> > +    RegionMapper Cnt(this, S);
> >> > +    Cnt.beginRegion();
> >> > +    VisitSubStmtRBraceState(S->getHandlerBlock());
> >> > +  }
> >> > +
> >> > +  void VisitAbstractConditionalOperator(const
> >> > AbstractConditionalOperator *E) {
> >> > +    Visit(E->getCond());
> >> > +    mapToken(E->getQuestionLoc());
> >> > +    auto State = getCurrentState();
> >> > +
> >> > +    // Counter tracks the "true" part of a conditional operator. The
> >> > +    // count in the "false" part will be calculated from this
> counter.
> >> > +    RegionMapper Cnt(this, E);
> >> > +    Cnt.beginRegion();
> >> > +    Visit(E->getTrueExpr());
> >> > +    Cnt.adjustForControlFlow();
> >> > +
> >> > +    mapToken(State, E->getColonLoc());
> >> > +
> >> > +    Cnt.beginElseRegion();
> >> > +    Visit(E->getFalseExpr());
> >> > +    Cnt.adjustForControlFlow();
> >> > +
> >> > +    Cnt.applyAdjustmentsToRegion();
> >> > +  }
> >> > +
> >> > +  void VisitBinLAnd(const BinaryOperator *E) {
> >> > +    Visit(E->getLHS());
> >> > +    mapToken(E->getOperatorLoc());
> >> > +    // Counter tracks the right hand side of a logical and operator.
> >> > +    RegionMapper Cnt(this, E);
> >> > +    Cnt.beginRegion();
> >> > +    Visit(E->getRHS());
> >> > +    Cnt.adjustForControlFlow();
> >> > +    Cnt.applyAdjustmentsToRegion();
> >> > +  }
> >> > +
> >> > +  void VisitBinLOr(const BinaryOperator *E) {
> >> > +    Visit(E->getLHS());
> >> > +    mapToken(E->getOperatorLoc());
> >> > +    // Counter tracks the right hand side of a logical or operator.
> >> > +    RegionMapper Cnt(this, E);
> >> > +    Cnt.beginRegion();
> >> > +    Visit(E->getRHS());
> >> > +    Cnt.adjustForControlFlow();
> >> > +    Cnt.applyAdjustmentsToRegion();
> >> > +  }
> >> > +
> >> > +  void VisitParenExpr(const ParenExpr *E) {
> >> > +    mapToken(E->getLParen());
> >> > +    Visit(E->getSubExpr());
> >> > +    mapToken(E->getRParen());
> >> > +  }
> >> > +
> >> > +  void VisitBinaryOperator(const BinaryOperator *E) {
> >> > +    Visit(E->getLHS());
> >> > +    mapToken(E->getOperatorLoc());
> >> > +    Visit(E->getRHS());
> >> > +  }
> >> > +
> >> > +  void VisitUnaryOperator(const UnaryOperator *E) {
> >> > +    bool Postfix = E->isPostfix();
> >> > +    if (!Postfix)
> >> > +      mapToken(E->getOperatorLoc());
> >> > +    Visit(E->getSubExpr());
> >> > +    if (Postfix)
> >> > +      mapToken(E->getOperatorLoc());
> >> > +  }
> >> > +
> >> > +  void VisitMemberExpr(const MemberExpr *E) {
> >> > +    Visit(E->getBase());
> >> > +    mapToken(E->getMemberLoc());
> >> > +  }
> >> > +
> >> > +  void VisitCallExpr(const CallExpr *E) {
> >> > +    Visit(E->getCallee());
> >> > +    for (const auto &Arg : E->arguments())
> >> > +      Visit(Arg);
> >> > +    mapToken(E->getRParenLoc());
> >> > +  }
> >> > +
> >> > +  void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
> >> > +    Visit(E->getLHS());
> >> > +    Visit(E->getRHS());
> >> > +    mapToken(E->getRBracketLoc());
> >> > +  }
> >> > +
> >> > +  void VisitCStyleCastExpr(const CStyleCastExpr *E) {
> >> > +    mapToken(E->getLParenLoc());
> >> > +    mapToken(E->getRParenLoc());
> >> > +    Visit(E->getSubExpr());
> >> > +  }
> >> > +
> >> > +  // Map literals as tokens so that the macros like #define PI 3.14
> >> > +  // won't generate coverage mapping regions.
> >> > +
> >> > +  void VisitIntegerLiteral(const IntegerLiteral *E) {
> >> > +    mapToken(E->getLocStart());
> >> > +  }
> >> > +
> >> > +  void VisitFloatingLiteral(const FloatingLiteral *E) {
> >> > +    mapToken(E->getLocStart());
> >> > +  }
> >> > +
> >> > +  void VisitCharacterLiteral(const CharacterLiteral *E) {
> >> > +    mapToken(E->getLocStart());
> >> > +  }
> >> > +
> >> > +  void VisitStringLiteral(const StringLiteral *E) {
> >> > +    mapToken(E->getLocStart());
> >> > +  }
> >> > +
> >> > +  void VisitImaginaryLiteral(const ImaginaryLiteral *E) {
> >> > +    mapToken(E->getLocStart());
> >> > +  }
> >> > +};
> >> > +}
> >> > +
> >> > +static bool isMachO(const CodeGenModule &CGM) {
> >> > +  return CGM.getTarget().getTriple().isOSBinFormatMachO();
> >> > +}
> >> > +
> >> > +static StringRef getCoverageSection(const CodeGenModule &CGM) {
> >> > +  return isMachO(CGM) ? "__DATA,__llvm_covmap" : "__llvm_covmap";
> >> > +}
> >> > +
> >> > +void CoverageMappingModuleGen::addFunctionMappingRecord(
> >> > +    llvm::GlobalVariable *FunctionName, unsigned FunctionNameSize,
> >> > +    const std::string &CoverageMapping) {
> >> > +  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
> >> > +  auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
> >> > +  auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
> >> > +  if (!FunctionRecordTy) {
> >> > +    llvm::Type *FunctionRecordTypes[] = {Int8PtrTy, Int32Ty,
> Int32Ty};
> >> > +    FunctionRecordTy =
> >> > +        llvm::StructType::get(Ctx,
> makeArrayRef(FunctionRecordTypes));
> >> > +  }
> >> > +
> >> > +  llvm::Constant *FunctionRecordVals[] = {
> >> > +      llvm::ConstantExpr::getBitCast(FunctionName, Int8PtrTy),
> >> > +      llvm::ConstantInt::get(Int32Ty, FunctionNameSize),
> >> > +      llvm::ConstantInt::get(Int32Ty, CoverageMapping.size())};
> >> > +  FunctionRecords.push_back(llvm::ConstantStruct::get(
> >> > +      FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
> >> > +  CoverageMappings += CoverageMapping;
> >> > +}
> >> > +
> >> > +void CoverageMappingModuleGen::emit() {
> >> > +  if (FunctionRecords.empty())
> >> > +    return;
> >> > +  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
> >> > +  auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
> >> > +
> >> > +  // Create the filenames and merge them with coverage mappings
> >> > +  llvm::SmallVector<std::string, 16> FilenameStrs;
> >> > +  llvm::SmallVector<StringRef, 16> FilenameRefs;
> >> > +  FilenameStrs.resize(FileEntries.size());
> >> > +  FilenameRefs.resize(FileEntries.size());
> >> > +  for (const auto &Entry : FileEntries) {
> >> > +    llvm::SmallString<256> Path(Entry.first->getName());
> >> > +    llvm::sys::fs::make_absolute(Path);
> >> > +
> >> > +    auto I = Entry.second;
> >> > +    FilenameStrs[I] = std::move(std::string(Path.begin(),
> Path.end()));
> >> > +    FilenameRefs[I] = FilenameStrs[I];
> >> > +  }
> >> > +
> >> > +  std::string FilenamesAndCoverageMappings;
> >> > +  llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
> >> > +  CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
> >> > +  OS << CoverageMappings;
> >> > +  size_t CoverageMappingSize = CoverageMappings.size();
> >> > +  size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
> >> > +  // Append extra zeroes if necessary to ensure that the size of the
> >> > filenames
> >> > +  // and coverage mappings is a multiple of 8.
> >> > +  if (size_t Rem = OS.str().size() % 8) {
> >> > +    CoverageMappingSize += 8 - Rem;
> >> > +    for (size_t I = 0, S = 8 - Rem; I < S; ++I)
> >> > +      OS << '\0';
> >> > +  }
> >> > +  auto *FilenamesAndMappingsVal =
> >> > +      llvm::ConstantDataArray::getString(Ctx, OS.str(), false);
> >> > +
> >> > +  // Create the deferred function records array
> >> > +  auto RecordsTy =
> >> > +      llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
> >> > +  auto RecordsVal = llvm::ConstantArray::get(RecordsTy,
> >> > FunctionRecords);
> >> > +
> >> > +  // Create the coverage data record
> >> > +  llvm::Type *CovDataTypes[] = {Int32Ty,   Int32Ty,
> >> > +                                Int32Ty,   Int32Ty,
> >> > +                                RecordsTy,
> >> > FilenamesAndMappingsVal->getType()};
> >> > +  auto CovDataTy = llvm::StructType::get(Ctx,
> >> > makeArrayRef(CovDataTypes));
> >> > +  llvm::Constant *TUDataVals[] = {
> >> > +      llvm::ConstantInt::get(Int32Ty, FunctionRecords.size()),
> >> > +      llvm::ConstantInt::get(Int32Ty, FilenamesSize),
> >> > +      llvm::ConstantInt::get(Int32Ty, CoverageMappingSize),
> >> > +      llvm::ConstantInt::get(Int32Ty,
> >> > +                             /*Version=*/CoverageMappingVersion1),
> >> > +      RecordsVal, FilenamesAndMappingsVal};
> >> > +  auto CovDataVal =
> >> > +      llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
> >> > +  auto CovData = new llvm::GlobalVariable(CGM.getModule(), CovDataTy,
> >> > true,
> >> > +
> >> > llvm::GlobalValue::InternalLinkage,
> >> > +                                          CovDataVal,
> >> > +                                          "__llvm_coverage_mapping");
> >> > +
> >> > +  CovData->setSection(getCoverageSection(CGM));
> >> > +  CovData->setAlignment(8);
> >> > +
> >> > +  // Make sure the data doesn't get deleted.
> >> > +  CGM.addUsedGlobal(CovData);
> >> > +}
> >> > +
> >> > +unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) {
> >> > +  auto It = FileEntries.find(File);
> >> > +  if (It != FileEntries.end())
> >> > +    return It->second;
> >> > +  unsigned FileID = FileEntries.size();
> >> > +  FileEntries.insert(std::make_pair(File, FileID));
> >> > +  return FileID;
> >> > +}
> >> > +
> >> > +void CoverageMappingGen::emitCounterMapping(const Decl *D,
> >> > +                                            llvm::raw_ostream &OS) {
> >> > +  assert(CounterMap);
> >> > +  CounterCoverageMappingBuilder Walker(CVM, *CounterMap,
> >> > NumRegionCounters, SM,
> >> > +                                       LangOpts);
> >> > +  Walker.VisitDecl(D);
> >> > +  Walker.write(OS);
> >> > +}
> >> > +
> >> > +void CoverageMappingGen::emitEmptyMapping(const Decl *D,
> >> > +                                          llvm::raw_ostream &OS) {
> >> > +  EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts);
> >> > +  Walker.VisitDecl(D);
> >> > +  Walker.write(OS);
> >> > +}
> >> >
> >> > Added: cfe/trunk/lib/CodeGen/CoverageMappingGen.h
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.h?rev=214752&view=auto
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/CoverageMappingGen.h (added)
> >> > +++ cfe/trunk/lib/CodeGen/CoverageMappingGen.h Mon Aug  4 13:41:51
> 2014
> >> > @@ -0,0 +1,117 @@
> >> > +//===---- CoverageMappingGen.h - Coverage mapping generation ----*-
> C++
> >> > -*-===//
> >> > +//
> >> > +//                     The LLVM Compiler Infrastructure
> >> > +//
> >> > +// This file is distributed under the University of Illinois Open
> >> > Source
> >> > +// License. See LICENSE.TXT for details.
> >> > +//
> >> >
> >> >
> +//===----------------------------------------------------------------------===//
> >> > +//
> >> > +// Instrumentation-based code coverage mapping generator
> >> > +//
> >> >
> >> >
> +//===----------------------------------------------------------------------===//
> >> > +
> >> > +#ifndef CLANG_CODEGEN_COVERAGEMAPPINGGEN_H
> >> > +#define CLANG_CODEGEN_COVERAGEMAPPINGGEN_H
> >> > +
> >> > +#include "clang/Basic/LLVM.h"
> >> > +#include "clang/Basic/SourceLocation.h"
> >> > +#include "clang/Lex/PPCallbacks.h"
> >> > +#include "clang/Frontend/CodeGenOptions.h"
> >> > +#include "llvm/ADT/StringMap.h"
> >> > +#include "llvm/ADT/DenseMap.h"
> >> > +#include "llvm/IR/GlobalValue.h"
> >> > +#include "llvm/Support/raw_ostream.h"
> >> > +
> >> > +namespace clang {
> >> > +
> >> > +class LangOptions;
> >> > +class SourceManager;
> >> > +class FileEntry;
> >> > +class Preprocessor;
> >> > +class Decl;
> >> > +class Stmt;
> >> > +
> >> > +/// \brief Stores additional source code information like skipped
> >> > ranges which
> >> > +/// is required by the coverage mapping generator and is obtained
> from
> >> > +/// the preprocessor.
> >> > +class CoverageSourceInfo : public PPCallbacks {
> >> > +  std::vector<SourceRange> SkippedRanges;
> >> > +public:
> >> > +  ArrayRef<SourceRange> getSkippedRanges() const { return
> >> > SkippedRanges; }
> >> > +
> >> > +  void SourceRangeSkipped(SourceRange Range) override;
> >> > +};
> >> > +
> >> > +namespace CodeGen {
> >> > +
> >> > +class CodeGenModule;
> >> > +
> >> > +/// \brief Organizes the cross-function state that is used while
> >> > generating
> >> > +/// code coverage mapping data.
> >> > +class CoverageMappingModuleGen {
> >> > +  CodeGenModule &CGM;
> >> > +  CoverageSourceInfo &SourceInfo;
> >> > +  llvm::SmallDenseMap<const FileEntry *, unsigned, 8> FileEntries;
> >> > +  std::vector<llvm::Constant *> FunctionRecords;
> >> > +  llvm::StructType *FunctionRecordTy;
> >> > +  std::string CoverageMappings;
> >> > +
> >> > +public:
> >> > +  CoverageMappingModuleGen(CodeGenModule &CGM, CoverageSourceInfo
> >> > &SourceInfo)
> >> > +      : CGM(CGM), SourceInfo(SourceInfo), FunctionRecordTy(nullptr)
> {}
> >> > +
> >> > +  CoverageSourceInfo &getSourceInfo() const {
> >> > +    return SourceInfo;
> >> > +  }
> >> > +
> >> > +  /// \brief Add a function's coverage mapping record to the
> collection
> >> > of the
> >> > +  /// function mapping records.
> >> > +  void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName,
> >> > +                                unsigned FunctionNameSize,
> >> > +                                const std::string &CoverageMapping);
> >> > +
> >> > +  /// \brief Emit the coverage mapping data for a translation unit.
> >> > +  void emit();
> >> > +
> >> > +  /// \brief Return the coverage mapping translation unit file id
> >> > +  /// for the given file.
> >> > +  unsigned getFileID(const FileEntry *File);
> >> > +};
> >> > +
> >> > +/// \brief Organizes the per-function state that is used while
> >> > generating
> >> > +/// code coverage mapping data.
> >> > +class CoverageMappingGen {
> >> > +  CoverageMappingModuleGen &CVM;
> >> > +  SourceManager &SM;
> >> > +  const LangOptions &LangOpts;
> >> > +  llvm::DenseMap<const Stmt *, unsigned> *CounterMap;
> >> > +  unsigned NumRegionCounters;
> >> > +
> >> > +public:
> >> > +  CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager
> &SM,
> >> > +                     const LangOptions &LangOpts)
> >> > +      : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(nullptr),
> >> > +        NumRegionCounters(0) {}
> >> > +
> >> > +  CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager
> &SM,
> >> > +                     const LangOptions &LangOpts,
> >> > +                     llvm::DenseMap<const Stmt *, unsigned>
> >> > *CounterMap,
> >> > +                     unsigned NumRegionCounters)
> >> > +      : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(CounterMap),
> >> > +        NumRegionCounters(NumRegionCounters) {}
> >> > +
> >> > +  /// \brief Emit the coverage mapping data which maps the regions of
> >> > +  /// code to counters that will be used to find the execution
> >> > +  /// counts for those regions.
> >> > +  void emitCounterMapping(const Decl *D, llvm::raw_ostream &OS);
> >> > +
> >> > +  /// \brief Emit the coverage mapping data for an unused function.
> >> > +  /// It creates mapping regions with the counter of zero.
> >> > +  void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS);
> >> > +};
> >> > +
> >> > +} // end namespace CodeGen
> >> > +} // end namespace clang
> >> > +
> >> > +#endif
> >> >
> >> > Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
> >> > +++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Mon Aug  4 13:41:51 2014
> >> > @@ -46,14 +46,18 @@ namespace {
> >> >        }
> >> >      };
> >> >
> >> > +    CoverageSourceInfo *CoverageInfo;
> >> > +
> >> >    protected:
> >> >      std::unique_ptr<llvm::Module> M;
> >> >      std::unique_ptr<CodeGen::CodeGenModule> Builder;
> >> >
> >> >    public:
> >> >      CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string&
> >> > ModuleName,
> >> > -                      const CodeGenOptions &CGO, llvm::LLVMContext&
> C)
> >> > +                      const CodeGenOptions &CGO, llvm::LLVMContext&
> C,
> >> > +                      CoverageSourceInfo *CoverageInfo = nullptr)
> >> >        : Diags(diags), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
> >> > +        CoverageInfo(CoverageInfo),
> >> >          M(new llvm::Module(ModuleName, C)) {}
> >> >
> >> >      virtual ~CodeGeneratorImpl() {}
> >> > @@ -86,7 +90,7 @@ namespace {
> >> >        M->setDataLayout(Ctx->getTargetInfo().getTargetDescription());
> >> >        TD.reset(new
> >> > llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription()));
> >> >        Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts,
> >> > *M, *TD,
> >> > -                                               Diags));
> >> > +                                               Diags, CoverageInfo));
> >> >
> >> >        for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size();
> i <
> >> > e; ++i)
> >> >          HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);
> >> > @@ -136,6 +140,10 @@ namespace {
> >> >        //     void foo() { bar(); }
> >> >        //   } A;
> >> >        DeferredInlineMethodDefinitions.push_back(D);
> >> > +
> >> > +      // Always provide some coverage mapping
> >> > +      // even for the methods that aren't emitted.
> >> > +      Builder->AddDeferredUnusedCoverageMapping(D);
> >> >      }
> >> >
> >> >      /// HandleTagDeclDefinition - This callback is invoked each time
> a
> >> > TagDecl
> >> > @@ -221,6 +229,7 @@ CodeGenerator *clang::CreateLLVMCodeGen(
> >> >                                          const std::string&
> ModuleName,
> >> >                                          const CodeGenOptions &CGO,
> >> >                                          const TargetOptions &/*TO*/,
> >> > -                                        llvm::LLVMContext& C) {
> >> > -  return new CodeGeneratorImpl(Diags, ModuleName, CGO, C);
> >> > +                                        llvm::LLVMContext& C,
> >> > +                                        CoverageSourceInfo
> >> > *CoverageInfo) {
> >> > +  return new CodeGeneratorImpl(Diags, ModuleName, CGO, C,
> >> > CoverageInfo);
> >> >  }
> >> >
> >> > Modified: cfe/trunk/lib/Driver/Tools.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/Driver/Tools.cpp (original)
> >> > +++ cfe/trunk/lib/Driver/Tools.cpp Mon Aug  4 13:41:51 2014
> >> > @@ -3230,6 +3230,14 @@ void Clang::ConstructJob(Compilation &C,
> >> >        Args.hasArg(options::OPT_coverage))
> >> >      CmdArgs.push_back("-femit-coverage-data");
> >> >
> >> > +  if (Args.hasArg(options::OPT_fcoverage_mapping) &&
> >> > +      !Args.hasArg(options::OPT_fprofile_instr_generate))
> >> > +    D.Diag(diag::err_drv_argument_only_allowed_with)
> >> > +      << "-fcoverage-mapping" << "-fprofile-instr-generate";
> >> > +
> >> > +  if (Args.hasArg(options::OPT_fcoverage_mapping))
> >> > +    CmdArgs.push_back("-fcoverage-mapping");
> >> > +
> >> >    if (C.getArgs().hasArg(options::OPT_c) ||
> >> >        C.getArgs().hasArg(options::OPT_S)) {
> >> >      if (Output.isFilename()) {
> >> >
> >> > Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> >> > URL:
> >> >
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=214752&r1=214751&r2=214752&view=diff
> >> >
> >> >
> ==============================================================================
> >> > --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
> >> > +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Mon Aug  4 13:41:51
> >> > 2014
> >> > @@ -403,6 +403,7 @@ static bool ParseCodeGenArgs(CodeGenOpti
> >> >    Opts.SampleProfileFile =
> >> > Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
> >> >    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.AsmVerbose = Args.hasArg(OPT_masm_verbose);
> >> >    Opts.ObjCAutoRefCountExceptions =
> >> > Args.hasArg(OPT_fobjc_arc_exceptions);
> >> >    Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device);
> >> >
> >> >
> >> > _______________________________________________
> >> > cfe-commits mailing list
> >> > cfe-commits at cs.uiuc.edu
> >> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140804/80c9b93b/attachment.html>


More information about the cfe-commits mailing list