Skip to content

Commit cbfe89f

Browse files
authored
[llvm][clang] Use the VFS in GCOVProfilerPass (#161260)
This PR starts using the correct VFS in `GCOVProfilerPass` instead of using the real FS directly. This matches compiler's behavior for other input files.
1 parent 12a5854 commit cbfe89f

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,8 +1090,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
10901090
if (std::optional<GCOVOptions> Options =
10911091
getGCOVOptions(CodeGenOpts, LangOpts))
10921092
PB.registerPipelineStartEPCallback(
1093-
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
1094-
MPM.addPass(GCOVProfilerPass(*Options));
1093+
[this, Options](ModulePassManager &MPM, OptimizationLevel Level) {
1094+
MPM.addPass(
1095+
GCOVProfilerPass(*Options, CI.getVirtualFileSystemPtr()));
10951096
});
10961097
if (std::optional<InstrProfOptions> Options =
10971098
getInstrProfOptions(CodeGenOpts, LangOpts))

llvm/include/llvm/Transforms/Instrumentation/GCOVProfiler.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@ namespace llvm {
2020
/// The gcov-style instrumentation pass
2121
class GCOVProfilerPass : public PassInfoMixin<GCOVProfilerPass> {
2222
public:
23-
GCOVProfilerPass(const GCOVOptions &Options = GCOVOptions::getDefault()) : GCOVOpts(Options) { }
23+
GCOVProfilerPass(
24+
const GCOVOptions &Options = GCOVOptions::getDefault(),
25+
IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem())
26+
: GCOVOpts(Options), VFS(std::move(VFS)) {}
2427
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
2528

2629
private:
2730
GCOVOptions GCOVOpts;
31+
IntrusiveRefCntPtr<vfs::FileSystem> VFS;
2832
};
2933

3034
} // namespace llvm

llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "llvm/Support/FileSystem.h"
3636
#include "llvm/Support/Path.h"
3737
#include "llvm/Support/Regex.h"
38+
#include "llvm/Support/VirtualFileSystem.h"
3839
#include "llvm/Support/raw_ostream.h"
3940
#include "llvm/Transforms/Instrumentation/CFGMST.h"
4041
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
@@ -92,8 +93,10 @@ class GCOVFunction;
9293

9394
class GCOVProfiler {
9495
public:
95-
GCOVProfiler() : GCOVProfiler(GCOVOptions::getDefault()) {}
96-
GCOVProfiler(const GCOVOptions &Opts) : Options(Opts) {}
96+
GCOVProfiler()
97+
: GCOVProfiler(GCOVOptions::getDefault(), *vfs::getRealFileSystem()) {}
98+
GCOVProfiler(const GCOVOptions &Opts, vfs::FileSystem &VFS)
99+
: Options(Opts), VFS(VFS) {}
97100
bool
98101
runOnModule(Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
99102
function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
@@ -110,6 +113,7 @@ class GCOVProfiler {
110113
os->write_zeros(4 - s.size() % 4);
111114
}
112115
void writeBytes(const char *Bytes, int Size) { os->write(Bytes, Size); }
116+
vfs::FileSystem &getVirtualFileSystem() const { return VFS; }
113117

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

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

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

@@ -455,7 +460,7 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
455460
if (FilterRe.empty() && ExcludeRe.empty()) {
456461
return true;
457462
}
458-
SmallString<128> Filename = getFilename(F.getSubprogram());
463+
SmallString<128> Filename = getFilename(F.getSubprogram(), VFS);
459464
auto It = InstrumentedFiles.find(Filename);
460465
if (It != InstrumentedFiles.end()) {
461466
return It->second;
@@ -467,7 +472,7 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
467472
// Path can be
468473
// /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/*.h so for
469474
// such a case we must get the real_path.
470-
if (sys::fs::real_path(Filename, RealPath)) {
475+
if (VFS.getRealPath(Filename, RealPath)) {
471476
// real_path can fail with path like "foo.c".
472477
RealFilename = Filename;
473478
} else {
@@ -524,9 +529,10 @@ std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
524529
SmallString<128> Filename = CU->getFilename();
525530
sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda");
526531
StringRef FName = sys::path::filename(Filename);
527-
SmallString<128> CurPath;
528-
if (sys::fs::current_path(CurPath))
532+
ErrorOr<std::string> CWD = VFS.getCurrentWorkingDirectory();
533+
if (!CWD)
529534
return std::string(FName);
535+
SmallString<128> CurPath{*CWD};
530536
sys::path::append(CurPath, FName);
531537
return std::string(CurPath);
532538
}
@@ -554,7 +560,7 @@ bool GCOVProfiler::runOnModule(
554560
PreservedAnalyses GCOVProfilerPass::run(Module &M,
555561
ModuleAnalysisManager &AM) {
556562

557-
GCOVProfiler Profiler(GCOVOpts);
563+
GCOVProfiler Profiler(GCOVOpts, *VFS);
558564
FunctionAnalysisManager &FAM =
559565
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
560566

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

794800
BranchProbabilityInfo *BPI = GetBPI(F);
795801
BlockFrequencyInfo *BFI = GetBFI(F);
@@ -881,7 +887,7 @@ bool GCOVProfiler::emitProfileNotes(
881887
if (SP != getDISubprogram(Scope))
882888
continue;
883889

884-
GCOVLines &Lines = Block.getFile(getFilename(Loc->getScope()));
890+
GCOVLines &Lines = Block.getFile(getFilename(Loc->getScope(), VFS));
885891
Lines.addLine(Loc.getLine());
886892
}
887893
Line = 0;

0 commit comments

Comments
 (0)