summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.cpp134
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.h18
-rw-r--r--clang/test/CoverageMapping/abspath.cpp4
-rw-r--r--clang/test/CoverageMapping/ir.c25
-rw-r--r--clang/test/Profile/def-assignop.cpp7
-rw-r--r--clang/test/Profile/def-ctors.cpp10
-rw-r--r--clang/test/Profile/def-dtors.cpp10
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() {
OpenPOWER on IntegriCloud