Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1090,8 +1090,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
if (std::optional<GCOVOptions> Options =
getGCOVOptions(CodeGenOpts, LangOpts))
PB.registerPipelineStartEPCallback(
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(GCOVProfilerPass(*Options));
[this, Options](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(
GCOVProfilerPass(*Options, CI.getVirtualFileSystemPtr()));
});
if (std::optional<InstrProfOptions> Options =
getInstrProfOptions(CodeGenOpts, LangOpts))
Expand Down
6 changes: 5 additions & 1 deletion llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ namespace llvm {
/// The gcov-style instrumentation pass
class GCOVProfilerPass : public PassInfoMixin<GCOVProfilerPass> {
public:
GCOVProfilerPass(const GCOVOptions &Options = GCOVOptions::getDefault()) : GCOVOpts(Options) { }
GCOVProfilerPass(
const GCOVOptions &Options = GCOVOptions::getDefault(),
IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem())
: GCOVOpts(Options), VFS(std::move(VFS)) {}
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);

private:
GCOVOptions GCOVOpts;
IntrusiveRefCntPtr<vfs::FileSystem> VFS;
};

} // namespace llvm
Expand Down
30 changes: 18 additions & 12 deletions llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation/CFGMST.h"
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
Expand Down Expand Up @@ -92,8 +93,10 @@ class GCOVFunction;

class GCOVProfiler {
public:
GCOVProfiler() : GCOVProfiler(GCOVOptions::getDefault()) {}
GCOVProfiler(const GCOVOptions &Opts) : Options(Opts) {}
GCOVProfiler()
: GCOVProfiler(GCOVOptions::getDefault(), *vfs::getRealFileSystem()) {}
GCOVProfiler(const GCOVOptions &Opts, vfs::FileSystem &VFS)
: Options(Opts), VFS(VFS) {}
bool
runOnModule(Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
Expand All @@ -110,6 +113,7 @@ class GCOVProfiler {
os->write_zeros(4 - s.size() % 4);
}
void writeBytes(const char *Bytes, int Size) { os->write(Bytes, Size); }
vfs::FileSystem &getVirtualFileSystem() const { return VFS; }

private:
// Create the .gcno files for the Module based on DebugInfo.
Expand Down Expand Up @@ -166,6 +170,7 @@ class GCOVProfiler {
std::vector<Regex> ExcludeRe;
DenseSet<const BasicBlock *> ExecBlocks;
StringMap<bool> InstrumentedFiles;
vfs::FileSystem &VFS;
};

struct BBInfo {
Expand Down Expand Up @@ -214,10 +219,10 @@ static StringRef getFunctionName(const DISubprogram *SP) {
/// Prefer relative paths in the coverage notes. Clang also may split
/// up absolute paths into a directory and filename component. When
/// the relative path doesn't exist, reconstruct the absolute path.
static SmallString<128> getFilename(const DIScope *SP) {
static SmallString<128> getFilename(const DIScope *SP, vfs::FileSystem &VFS) {
SmallString<128> Path;
StringRef RelPath = SP->getFilename();
if (sys::fs::exists(RelPath))
if (VFS.exists(RelPath))
Path = RelPath;
else
sys::path::append(Path, SP->getDirectory(), SP->getFilename());
Expand Down Expand Up @@ -357,7 +362,7 @@ namespace {

void writeOut(uint32_t CfgChecksum) {
write(GCOV_TAG_FUNCTION);
SmallString<128> Filename = getFilename(SP);
SmallString<128> Filename = getFilename(SP, P->getVirtualFileSystem());
uint32_t BlockLen = 3 + wordsOfString(getFunctionName(SP));
BlockLen += 1 + wordsOfString(Filename) + 4;

Expand Down Expand Up @@ -455,7 +460,7 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
if (FilterRe.empty() && ExcludeRe.empty()) {
return true;
}
SmallString<128> Filename = getFilename(F.getSubprogram());
SmallString<128> Filename = getFilename(F.getSubprogram(), VFS);
auto It = InstrumentedFiles.find(Filename);
if (It != InstrumentedFiles.end()) {
return It->second;
Expand All @@ -467,7 +472,7 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
// Path can be
// /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/*.h so for
// such a case we must get the real_path.
if (sys::fs::real_path(Filename, RealPath)) {
if (VFS.getRealPath(Filename, RealPath)) {
// real_path can fail with path like "foo.c".
RealFilename = Filename;
} else {
Expand Down Expand Up @@ -524,9 +529,10 @@ std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
SmallString<128> Filename = CU->getFilename();
sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda");
StringRef FName = sys::path::filename(Filename);
SmallString<128> CurPath;
if (sys::fs::current_path(CurPath))
ErrorOr<std::string> CWD = VFS.getCurrentWorkingDirectory();
if (!CWD)
return std::string(FName);
SmallString<128> CurPath{*CWD};
sys::path::append(CurPath, FName);
return std::string(CurPath);
}
Expand Down Expand Up @@ -554,7 +560,7 @@ bool GCOVProfiler::runOnModule(
PreservedAnalyses GCOVProfilerPass::run(Module &M,
ModuleAnalysisManager &AM) {

GCOVProfiler Profiler(GCOVOpts);
GCOVProfiler Profiler(GCOVOpts, *VFS);
FunctionAnalysisManager &FAM =
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();

Expand Down Expand Up @@ -789,7 +795,7 @@ bool GCOVProfiler::emitProfileNotes(
// Add the function line number to the lines of the entry block
// to have a counter for the function definition.
uint32_t Line = SP->getLine();
auto Filename = getFilename(SP);
auto Filename = getFilename(SP, VFS);

BranchProbabilityInfo *BPI = GetBPI(F);
BlockFrequencyInfo *BFI = GetBFI(F);
Expand Down Expand Up @@ -881,7 +887,7 @@ bool GCOVProfiler::emitProfileNotes(
if (SP != getDISubprogram(Scope))
continue;

GCOVLines &Lines = Block.getFile(getFilename(Loc->getScope()));
GCOVLines &Lines = Block.getFile(getFilename(Loc->getScope(), VFS));
Lines.addLine(Loc.getLine());
}
Line = 0;
Expand Down