diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.cpp | 134 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.h | 18 | ||||
| -rw-r--r-- | clang/test/CoverageMapping/abspath.cpp | 4 | ||||
| -rw-r--r-- | clang/test/CoverageMapping/ir.c | 25 | ||||
| -rw-r--r-- | clang/test/Profile/def-assignop.cpp | 7 | ||||
| -rw-r--r-- | clang/test/Profile/def-ctors.cpp | 10 | ||||
| -rw-r--r-- | clang/test/Profile/def-dtors.cpp | 10 | 
7 files changed, 72 insertions, 136 deletions
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 02840bf771c..bdecff39c88 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -13,8 +13,6 @@  #include "CoverageMappingGen.h"  #include "CodeGenFunction.h"  #include "clang/AST/StmtVisitor.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Frontend/FrontendDiagnostic.h"  #include "clang/Lex/Lexer.h"  #include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/StringExtras.h" @@ -26,10 +24,6 @@  #include "llvm/Support/FileSystem.h"  #include "llvm/Support/Path.h" -// This selects the coverage mapping format defined when `InstrProfData.inc` -// is textually included. -#define COVMAP_V3 -  using namespace clang;  using namespace CodeGen;  using namespace llvm::coverage; @@ -1278,6 +1272,12 @@ struct CounterCoverageMappingBuilder    }  }; +std::string getCoverageSection(const CodeGenModule &CGM) { +  return llvm::getInstrProfSectionName( +      llvm::IPSK_covmap, +      CGM.getContext().getTargetInfo().getTriple().getObjectFormat()); +} +  std::string normalizeFilename(StringRef Filename) {    llvm::SmallString<256> Path(Filename);    llvm::sys::fs::make_absolute(Path); @@ -1317,71 +1317,30 @@ static void dump(llvm::raw_ostream &OS, StringRef FunctionName,    }  } -static std::string getInstrProfSection(const CodeGenModule &CGM, -                                       llvm::InstrProfSectKind SK) { -  return llvm::getInstrProfSectionName( -      SK, CGM.getContext().getTargetInfo().getTriple().getObjectFormat()); -} - -void CoverageMappingModuleGen::emitFunctionMappingRecord( -    const FunctionInfo &Info, uint64_t FilenamesRef) { +void CoverageMappingModuleGen::addFunctionMappingRecord( +    llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash, +    const std::string &CoverageMapping, bool IsUsed) {    llvm::LLVMContext &Ctx = CGM.getLLVMContext(); - -  // Assign a name to the function record. This is used to merge duplicates. -  std::string FuncRecordName = "__covrec_" + llvm::utohexstr(Info.NameHash); - -  // A dummy description for a function included-but-not-used in a TU can be -  // replaced by full description provided by a different TU. The two kinds of -  // descriptions play distinct roles: therefore, assign them different names -  // to prevent `linkonce_odr` merging. -  if (Info.IsUsed) -    FuncRecordName += "u"; - -  // Create the function record type. -  const uint64_t NameHash = Info.NameHash; -  const uint64_t FuncHash = Info.FuncHash; -  const std::string &CoverageMapping = Info.CoverageMapping; +  if (!FunctionRecordTy) {  #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType, -  llvm::Type *FunctionRecordTypes[] = { -#include "llvm/ProfileData/InstrProfData.inc" -  }; -  auto *FunctionRecordTy = -      llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes), -                            /*isPacked=*/true); +    llvm::Type *FunctionRecordTypes[] = { +      #include "llvm/ProfileData/InstrProfData.inc" +    }; +    FunctionRecordTy = +        llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes), +                              /*isPacked=*/true); +  } -  // Create the function record constant. -#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init, +  #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,    llvm::Constant *FunctionRecordVals[] = {        #include "llvm/ProfileData/InstrProfData.inc"    }; -  auto *FuncRecordConstant = llvm::ConstantStruct::get( -      FunctionRecordTy, makeArrayRef(FunctionRecordVals)); - -  // Create the function record global. -  auto *FuncRecord = new llvm::GlobalVariable( -      CGM.getModule(), FunctionRecordTy, /*isConstant=*/true, -      llvm::GlobalValue::LinkOnceODRLinkage, FuncRecordConstant, -      FuncRecordName); -  FuncRecord->setVisibility(llvm::GlobalValue::HiddenVisibility); -  FuncRecord->setSection(getInstrProfSection(CGM, llvm::IPSK_covfun)); -  FuncRecord->setAlignment(llvm::Align(8)); -  if (CGM.supportsCOMDAT()) -    FuncRecord->setComdat(CGM.getModule().getOrInsertComdat(FuncRecordName)); - -  // Make sure the data doesn't get deleted. -  CGM.addUsedGlobal(FuncRecord); -} - -void CoverageMappingModuleGen::addFunctionMappingRecord( -    llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash, -    const std::string &CoverageMapping, bool IsUsed) { -  llvm::LLVMContext &Ctx = CGM.getLLVMContext(); -  const uint64_t NameHash = llvm::IndexedInstrProf::ComputeHash(NameValue); -  FunctionRecords.push_back({NameHash, FuncHash, CoverageMapping, IsUsed}); - +  FunctionRecords.push_back(llvm::ConstantStruct::get( +      FunctionRecordTy, makeArrayRef(FunctionRecordVals)));    if (!IsUsed)      FunctionNames.push_back(          llvm::ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx))); +  CoverageMappings.push_back(CoverageMapping);    if (CGM.getCodeGenOpts().DumpCoverageMapping) {      // Dump the coverage mapping data for this function by decoding the @@ -1426,22 +1385,37 @@ void CoverageMappingModuleGen::emit() {      FilenameRefs[I] = FilenameStrs[I];    } -  std::string Filenames; -  { -    llvm::raw_string_ostream OS(Filenames); -    CoverageFilenamesSectionWriter(FilenameRefs).write(OS); +  std::string FilenamesAndCoverageMappings; +  llvm::raw_string_ostream OS(FilenamesAndCoverageMappings); +  CoverageFilenamesSectionWriter(FilenameRefs).write(OS); + +  // Stream the content of CoverageMappings to OS while keeping +  // memory consumption under control. +  size_t CoverageMappingSize = 0; +  for (auto &S : CoverageMappings) { +    CoverageMappingSize += S.size(); +    OS << S; +    S.clear(); +    S.shrink_to_fit();    } -  auto *FilenamesVal = -      llvm::ConstantDataArray::getString(Ctx, Filenames, false); -  const int64_t FilenamesRef = llvm::IndexedInstrProf::ComputeHash(Filenames); +  CoverageMappings.clear(); +  CoverageMappings.shrink_to_fit(); -  // Emit the function records. -  for (const FunctionInfo &Info : FunctionRecords) -    emitFunctionMappingRecord(Info, FilenamesRef); +  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; +    OS.write_zeros(8 - Rem); +  } +  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); -  const unsigned NRecords = 0; -  const size_t FilenamesSize = Filenames.size(); -  const unsigned CoverageMappingSize = 0;    llvm::Type *CovDataHeaderTypes[] = {  #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,  #include "llvm/ProfileData/InstrProfData.inc" @@ -1456,16 +1430,18 @@ void CoverageMappingModuleGen::emit() {        CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));    // Create the coverage data record -  llvm::Type *CovDataTypes[] = {CovDataHeaderTy, FilenamesVal->getType()}; +  llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy, +                                FilenamesAndMappingsVal->getType()};    auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes)); -  llvm::Constant *TUDataVals[] = {CovDataHeaderVal, FilenamesVal}; +  llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal, +                                  FilenamesAndMappingsVal};    auto CovDataVal =        llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));    auto CovData = new llvm::GlobalVariable( -      CGM.getModule(), CovDataTy, true, llvm::GlobalValue::PrivateLinkage, +      CGM.getModule(), CovDataTy, true, llvm::GlobalValue::InternalLinkage,        CovDataVal, llvm::getCoverageMappingVarName()); -  CovData->setSection(getInstrProfSection(CGM, llvm::IPSK_covmap)); +  CovData->setSection(getCoverageSection(CGM));    CovData->setAlignment(llvm::Align(8));    // Make sure the data doesn't get deleted. diff --git a/clang/lib/CodeGen/CoverageMappingGen.h b/clang/lib/CodeGen/CoverageMappingGen.h index 5d79d1e6567..3bf51f59047 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.h +++ b/clang/lib/CodeGen/CoverageMappingGen.h @@ -47,27 +47,17 @@ class CodeGenModule;  /// Organizes the cross-function state that is used while generating  /// code coverage mapping data.  class CoverageMappingModuleGen { -  /// Information needed to emit a coverage record for a function. -  struct FunctionInfo { -    uint64_t NameHash; -    uint64_t FuncHash; -    std::string CoverageMapping; -    bool IsUsed; -  }; -    CodeGenModule &CGM;    CoverageSourceInfo &SourceInfo;    llvm::SmallDenseMap<const FileEntry *, unsigned, 8> FileEntries; +  std::vector<llvm::Constant *> FunctionRecords;    std::vector<llvm::Constant *> FunctionNames; -  std::vector<FunctionInfo> FunctionRecords; - -  /// Emit a function record. -  void emitFunctionMappingRecord(const FunctionInfo &Info, -                                 uint64_t FilenamesRef); +  llvm::StructType *FunctionRecordTy; +  std::vector<std::string> CoverageMappings;  public:    CoverageMappingModuleGen(CodeGenModule &CGM, CoverageSourceInfo &SourceInfo) -      : CGM(CGM), SourceInfo(SourceInfo) {} +      : CGM(CGM), SourceInfo(SourceInfo), FunctionRecordTy(nullptr) {}    CoverageSourceInfo &getSourceInfo() const {      return SourceInfo; diff --git a/clang/test/CoverageMapping/abspath.cpp b/clang/test/CoverageMapping/abspath.cpp index 1c415691651..892dff8de01 100644 --- a/clang/test/CoverageMapping/abspath.cpp +++ b/clang/test/CoverageMapping/abspath.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false -emit-llvm -main-file-name abspath.cpp %S/Inputs/../abspath.cpp -o - | FileCheck -check-prefix=RMDOTS %s +// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -main-file-name abspath.cpp %S/Inputs/../abspath.cpp -o - | FileCheck -check-prefix=RMDOTS %s  // RMDOTS: @__llvm_coverage_mapping = {{.*}}"\01  // RMDOTS-NOT: Inputs @@ -6,7 +6,7 @@  // RUN: mkdir -p %t/test && cd %t/test  // RUN: echo "void f1() {}" > f1.c -// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false -emit-llvm -main-file-name abspath.cpp ../test/f1.c -o - | FileCheck -check-prefix=RELPATH %s +// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -main-file-name abspath.cpp ../test/f1.c -o - | FileCheck -check-prefix=RELPATH %s  // RELPATH: @__llvm_coverage_mapping = {{.*}}"\01  // RELPATH: {{[/\\].*(/|\\\\)test(/|\\\\)f1}}.c diff --git a/clang/test/CoverageMapping/ir.c b/clang/test/CoverageMapping/ir.c index f5ba39c7472..469b2992ecd 100644 --- a/clang/test/CoverageMapping/ir.c +++ b/clang/test/CoverageMapping/ir.c @@ -1,31 +1,12 @@  // Check the data structures emitted by coverage mapping -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false | FileCheck %s -check-prefixes=COMMON,DARWIN -// RUN: %clang_cc1 -triple x86_64--windows-msvc -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false | FileCheck %s -check-prefixes=COMMON,WINDOWS +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping | FileCheck %s -static inline void unused() {} -void foo(void) {} +void foo(void) { }  int main(void) {    foo();    return 0;  } -// Check the function records. Two of the record names should come in the 'used' -// flavor, and one should not. - -// DARWIN: [[FuncRecord1:@__covrec_[0-9A-F]+u]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section "__LLVM_COV,__llvm_covfun", align 8 -// DARWIN: [[FuncRecord2:@__covrec_[0-9A-F]+u]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section "__LLVM_COV,__llvm_covfun", align 8 -// DARWIN: [[FuncRecord3:@__covrec_[0-9A-F]+]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section "__LLVM_COV,__llvm_covfun", align 8 -// DARWIN: @__llvm_coverage_mapping = private constant { { i32, i32, i32, i32 }, [{{.*}} x i8] } { {{.*}} }, section "__LLVM_COV,__llvm_covmap", align 8 - -// WINDOWS: [[FuncRecord1:@__covrec_[0-9A-F]+u]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section ".lcovfun$M", comdat, align 8 -// WINDOWS: [[FuncRecord2:@__covrec_[0-9A-F]+u]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section ".lcovfun$M", comdat, align 8 -// WINDOWS: [[FuncRecord3:@__covrec_[0-9A-F]+]] = linkonce_odr hidden constant <{ i64, i32, i64, i64, [{{.*}} x i8] }> <{ {{.*}} }>, section ".lcovfun$M", comdat, align 8 -// WINDOWS: @__llvm_coverage_mapping = private constant { { i32, i32, i32, i32 }, [{{.*}} x i8] } { {{.*}} }, section ".lcovmap$M", align 8 - -// COMMON: @llvm.used = appending global [{{.*}} x i8*] -// COMMON-SAME: [[FuncRecord1]] -// COMMON-SAME: [[FuncRecord2]] -// COMMON-SAME: [[FuncRecord3]] -// COMMON-SAME: @__llvm_coverage_mapping +// CHECK: @__llvm_coverage_mapping = internal constant { { i32, i32, i32, i32 }, [2 x <{ i64, i32, i64 }>], [{{[0-9]+}} x i8] } { { i32, i32, i32, i32 } { i32 2, i32 {{[0-9]+}}, i32 {{[0-9]+}}, i32 {{[0-9]+}} }, [2 x <{ i64, i32, i64 }>] [<{{.*}}> <{{.*}}>, <{{.*}}> <{{.*}}>] diff --git a/clang/test/Profile/def-assignop.cpp b/clang/test/Profile/def-assignop.cpp index d17654f3142..2d453364a55 100644 --- a/clang/test/Profile/def-assignop.cpp +++ b/clang/test/Profile/def-assignop.cpp @@ -18,12 +18,9 @@ struct A {    // PGOGEN: {{.*}}add{{.*}}%pgocount, 1    // PGOGEN: store{{.*}}@__profc__ZN1AaSEOS_ -  // Check that coverage mapping includes 3 function records including the +  // Check that coverage mapping includes 6 function records including the    // defaulted copy and move operators: A::operator= -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 } +  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 }, [3 x <{{.*}}>],    B b;  }; diff --git a/clang/test/Profile/def-ctors.cpp b/clang/test/Profile/def-ctors.cpp index 0179bc92dbb..1b52d559e01 100644 --- a/clang/test/Profile/def-ctors.cpp +++ b/clang/test/Profile/def-ctors.cpp @@ -20,15 +20,11 @@ struct Derived : public Base {    // PGOGEN-DAG: {{.*}}add{{.*}}%pgocount, 1    // PGOGEN-DAG: store{{.*}}@__profc__ZN7DerivedC2Ev -  // Check that coverage mapping has 5 function records including +  // Check that coverage mapping has 6 function records including    // the defaulted Derived::Derived(const Derived), and Derived::Derived()    // methds. -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 } +  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 }, [5 x +  // <{{.*}}>],  };  Derived dd; diff --git a/clang/test/Profile/def-dtors.cpp b/clang/test/Profile/def-dtors.cpp index dc87508fe7c..bfa535634d1 100644 --- a/clang/test/Profile/def-dtors.cpp +++ b/clang/test/Profile/def-dtors.cpp @@ -16,14 +16,10 @@ struct Derived : public Base {    // PGOGEN: {{.*}}add{{.*}}%pgocount, 1    // PGOGEN: store{{.*}}@__profc__ZN7DerivedD2Ev -  // Check that coverage mapping has 5 function records including +  // Check that coverage mapping has 6 function records including    // the default destructor in the derived class. -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: section "__llvm_covfun", comdat -  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 } +  // COVMAP: @__llvm_coverage_mapping = {{.*}} { { i32, i32, i32, i32 }, [5 x +  // <{{.*}}>],  };  int main() {  | 

