[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.
This commit is contained in:
parent
12a5854a51
commit
cbfe89f0ec
@ -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))
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
@ -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,
|
||||
@ -110,6 +113,7 @@ public:
|
||||
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.
|
||||
@ -166,6 +170,7 @@ private:
|
||||
std::vector<Regex> ExcludeRe;
|
||||
DenseSet<const BasicBlock *> ExecBlocks;
|
||||
StringMap<bool> InstrumentedFiles;
|
||||
vfs::FileSystem &VFS;
|
||||
};
|
||||
|
||||
struct BBInfo {
|
||||
@ -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());
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -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 {
|
||||
@ -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);
|
||||
}
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user