diff options
| author | Rich Kadel <richkadel@google.com> | 2020-07-02 11:27:15 -0700 |
|---|---|---|
| committer | Rich Kadel <richkadel@google.com> | 2020-07-17 11:49:35 -0700 |
| commit | a6f8b8a2116f0ea7e31d572d3120508678ed8079 (patch) | |
| tree | ea4c018d3684b3990d2d01bc02efa923360c7129 /src/rustllvm/CoverageMappingWrapper.cpp | |
| parent | c2dbebd3d4ad21e80ef4e7535dd1e868aaad7e50 (diff) | |
| download | rust-a6f8b8a2116f0ea7e31d572d3120508678ed8079.tar.gz rust-a6f8b8a2116f0ea7e31d572d3120508678ed8079.zip | |
Generating the coverage map
rustc now generates the coverage map and can support (limited)
coverage report generation, at the function level.
Example:
$ BUILD=$HOME/rust/build/x86_64-unknown-linux-gnu
$ $BUILD/stage1/bin/rustc -Zinstrument-coverage \
$HOME/rust/src/test/run-make-fulldeps/instrument-coverage/main.rs
$ LLVM_PROFILE_FILE="main.profraw" ./main
called
$ $BUILD/llvm/bin/llvm-profdata merge -sparse main.profraw -o main.profdata
$ $BUILD/llvm/bin/llvm-cov show --instr-profile=main.profdata main
1| 1|pub fn will_be_called() {
2| 1| println!("called");
3| 1|}
4| |
5| 0|pub fn will_not_be_called() {
6| 0| println!("should not have been called");
7| 0|}
8| |
9| 1|fn main() {
10| 1| let less = 1;
11| 1| let more = 100;
12| 1|
13| 1| if less < more {
14| 1| will_be_called();
15| 1| } else {
16| 1| will_not_be_called();
17| 1| }
18| 1|}
Diffstat (limited to 'src/rustllvm/CoverageMappingWrapper.cpp')
| -rw-r--r-- | src/rustllvm/CoverageMappingWrapper.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/rustllvm/CoverageMappingWrapper.cpp b/src/rustllvm/CoverageMappingWrapper.cpp new file mode 100644 index 00000000000..c6c4cdb5562 --- /dev/null +++ b/src/rustllvm/CoverageMappingWrapper.cpp @@ -0,0 +1,115 @@ +#include "rustllvm.h" +#include "llvm/ProfileData/Coverage/CoverageMapping.h" +#include "llvm/ProfileData/Coverage/CoverageMappingWriter.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/ADT/ArrayRef.h" + +#include <iostream> + +using namespace llvm; + +extern "C" SmallVectorTemplateBase<coverage::CounterExpression> + *LLVMRustCoverageSmallVectorCounterExpressionCreate() { + return new SmallVector<coverage::CounterExpression, 32>(); +} + +extern "C" void LLVMRustCoverageSmallVectorCounterExpressionDispose( + SmallVectorTemplateBase<coverage::CounterExpression> *Vector) { + delete Vector; +} + +extern "C" void LLVMRustCoverageSmallVectorCounterExpressionAdd( + SmallVectorTemplateBase<coverage::CounterExpression> *Expressions, + coverage::CounterExpression::ExprKind Kind, + unsigned LeftIndex, + unsigned RightIndex) { + auto LHS = coverage::Counter::getCounter(LeftIndex); + auto RHS = coverage::Counter::getCounter(RightIndex); + Expressions->push_back(coverage::CounterExpression { Kind, LHS, RHS }); +} + +extern "C" SmallVectorTemplateBase<coverage::CounterMappingRegion> + *LLVMRustCoverageSmallVectorCounterMappingRegionCreate() { + return new SmallVector<coverage::CounterMappingRegion, 32>(); +} + +extern "C" void LLVMRustCoverageSmallVectorCounterMappingRegionDispose( + SmallVectorTemplateBase<coverage::CounterMappingRegion> *Vector) { + delete Vector; +} + +extern "C" void LLVMRustCoverageSmallVectorCounterMappingRegionAdd( + SmallVectorTemplateBase<coverage::CounterMappingRegion> *MappingRegions, + unsigned Index, + unsigned FileID, + unsigned LineStart, + unsigned ColumnStart, + unsigned LineEnd, + unsigned ColumnEnd) { + auto Counter = coverage::Counter::getCounter(Index); + MappingRegions->push_back(coverage::CounterMappingRegion::makeRegion( + Counter, FileID, LineStart, + ColumnStart, LineEnd, ColumnEnd)); + + // FIXME(richkadel): As applicable, implement additional CounterMappingRegion types using the + // static method alternatives to `coverage::CounterMappingRegion::makeRegion`: + // + // makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart, + // unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) { + // makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart, + // unsigned LineEnd, unsigned ColumnEnd) { + // makeGapRegion(Counter Count, unsigned FileID, unsigned LineStart, + // unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) { +} + +extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( + const char* const Filenames[], + size_t FilenamesLen, + RustStringRef BufferOut) { + SmallVector<StringRef,32> FilenameRefs; + for (size_t i = 0; i < FilenamesLen; i++) { + FilenameRefs.push_back(StringRef(Filenames[i])); + } + auto FilenamesWriter = coverage::CoverageFilenamesSectionWriter( + makeArrayRef(FilenameRefs)); + RawRustStringOstream OS(BufferOut); + FilenamesWriter.write(OS); +} + +extern "C" void LLVMRustCoverageWriteMappingToBuffer( + const unsigned *VirtualFileMappingIDs, + unsigned NumVirtualFileMappingIDs, + const SmallVectorImpl<coverage::CounterExpression> *Expressions, + SmallVectorImpl<coverage::CounterMappingRegion> *MappingRegions, + RustStringRef BufferOut) { + auto CoverageMappingWriter = coverage::CoverageMappingWriter( + makeArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs), + makeArrayRef(*Expressions), + MutableArrayRef<coverage::CounterMappingRegion> { *MappingRegions }); + RawRustStringOstream OS(BufferOut); + CoverageMappingWriter.write(OS); +} + +extern "C" uint64_t LLVMRustCoverageComputeHash(const char *Name) { + StringRef NameRef(Name); + return IndexedInstrProf::ComputeHash(NameRef); +} + +extern "C" void LLVMRustCoverageWriteSectionNameToString(LLVMModuleRef M, + RustStringRef Str) { + Triple TargetTriple(unwrap(M)->getTargetTriple()); + auto name = getInstrProfSectionName(IPSK_covmap, + TargetTriple.getObjectFormat()); + RawRustStringOstream OS(Str); + OS << name; +} + +extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) { + auto name = getCoverageMappingVarName(); + RawRustStringOstream OS(Str); + OS << name; +} + +extern "C" uint32_t LLVMRustCoverageMappingVersion() { + return coverage::CovMapVersion::CurrentVersion; +} |
