Skip to content

Commit 516e301

Browse files
[NFC][Profile] Access profile through VirtualFileSystem
Make the access to profile data going through virtual file system so the inputs can be remapped. In the context of the caching, it can make sure we capture the inputs and provided an immutable input as profile data. Reviewed By: akyrtzi, benlangmuir Differential Revision: https://reviews.llvm.org/D139052
1 parent 62bd944 commit 516e301

34 files changed

+359
-185
lines changed

clang/include/clang/CodeGen/BackendUtil.h

+5
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
namespace llvm {
1717
class BitcodeModule;
1818
template <typename T> class Expected;
19+
template <typename T> class IntrusiveRefCntPtr;
1920
class Module;
2021
class MemoryBufferRef;
22+
namespace vfs {
23+
class FileSystem;
24+
} // namespace vfs
2125
}
2226

2327
namespace clang {
@@ -40,6 +44,7 @@ namespace clang {
4044
const CodeGenOptions &CGOpts,
4145
const TargetOptions &TOpts, const LangOptions &LOpts,
4246
StringRef TDesc, llvm::Module *M, BackendAction Action,
47+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
4348
std::unique_ptr<raw_pwrite_stream> OS);
4449

4550
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,

clang/lib/CodeGen/BackendUtil.cpp

+30-25
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "llvm/Support/TimeProfiler.h"
5353
#include "llvm/Support/Timer.h"
5454
#include "llvm/Support/ToolOutputFile.h"
55+
#include "llvm/Support/VirtualFileSystem.h"
5556
#include "llvm/Support/raw_ostream.h"
5657
#include "llvm/Target/TargetMachine.h"
5758
#include "llvm/Target/TargetOptions.h"
@@ -123,6 +124,7 @@ class EmitAssemblyHelper {
123124
const clang::TargetOptions &TargetOpts;
124125
const LangOptions &LangOpts;
125126
Module *TheModule;
127+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
126128

127129
Timer CodeGenerationTime;
128130

@@ -187,9 +189,10 @@ class EmitAssemblyHelper {
187189
const HeaderSearchOptions &HeaderSearchOpts,
188190
const CodeGenOptions &CGOpts,
189191
const clang::TargetOptions &TOpts,
190-
const LangOptions &LOpts, Module *M)
192+
const LangOptions &LOpts, Module *M,
193+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
191194
: Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
192-
TargetOpts(TOpts), LangOpts(LOpts), TheModule(M),
195+
TargetOpts(TOpts), LangOpts(LOpts), TheModule(M), VFS(std::move(VFS)),
193196
CodeGenerationTime("codegen", "Code Generation Time"),
194197
TargetTriple(TheModule->getTargetTriple()) {}
195198

@@ -767,32 +770,33 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
767770

768771
if (CodeGenOpts.hasProfileIRInstr())
769772
// -fprofile-generate.
770-
PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty()
771-
? getDefaultProfileGenName()
772-
: CodeGenOpts.InstrProfileOutput,
773-
"", "", PGOOptions::IRInstr, PGOOptions::NoCSAction,
774-
CodeGenOpts.DebugInfoForProfiling);
773+
PGOOpt = PGOOptions(
774+
CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName()
775+
: CodeGenOpts.InstrProfileOutput,
776+
"", "", nullptr, PGOOptions::IRInstr, PGOOptions::NoCSAction,
777+
CodeGenOpts.DebugInfoForProfiling);
775778
else if (CodeGenOpts.hasProfileIRUse()) {
776779
// -fprofile-use.
777780
auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
778781
: PGOOptions::NoCSAction;
779-
PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
780-
CodeGenOpts.ProfileRemappingFile, PGOOptions::IRUse,
781-
CSAction, CodeGenOpts.DebugInfoForProfiling);
782+
PGOOpt =
783+
PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
784+
CodeGenOpts.ProfileRemappingFile, VFS, PGOOptions::IRUse,
785+
CSAction, CodeGenOpts.DebugInfoForProfiling);
782786
} else if (!CodeGenOpts.SampleProfileFile.empty())
783787
// -fprofile-sample-use
784788
PGOOpt = PGOOptions(
785789
CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile,
786-
PGOOptions::SampleUse, PGOOptions::NoCSAction,
790+
VFS, PGOOptions::SampleUse, PGOOptions::NoCSAction,
787791
CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);
788792
else if (CodeGenOpts.PseudoProbeForProfiling)
789793
// -fpseudo-probe-for-profiling
790-
PGOOpt =
791-
PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
792-
CodeGenOpts.DebugInfoForProfiling, true);
794+
PGOOpt = PGOOptions("", "", "", nullptr, PGOOptions::NoAction,
795+
PGOOptions::NoCSAction,
796+
CodeGenOpts.DebugInfoForProfiling, true);
793797
else if (CodeGenOpts.DebugInfoForProfiling)
794798
// -fdebug-info-for-profiling
795-
PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
799+
PGOOpt = PGOOptions("", "", "", nullptr, PGOOptions::NoAction,
796800
PGOOptions::NoCSAction, true);
797801

798802
// Check to see if we want to generate a CS profile.
@@ -810,12 +814,13 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
810814
: CodeGenOpts.InstrProfileOutput;
811815
PGOOpt->CSAction = PGOOptions::CSIRInstr;
812816
} else
813-
PGOOpt = PGOOptions("",
814-
CodeGenOpts.InstrProfileOutput.empty()
815-
? getDefaultProfileGenName()
816-
: CodeGenOpts.InstrProfileOutput,
817-
"", PGOOptions::NoAction, PGOOptions::CSIRInstr,
818-
CodeGenOpts.DebugInfoForProfiling);
817+
PGOOpt =
818+
PGOOptions("",
819+
CodeGenOpts.InstrProfileOutput.empty()
820+
? getDefaultProfileGenName()
821+
: CodeGenOpts.InstrProfileOutput,
822+
"", nullptr, PGOOptions::NoAction, PGOOptions::CSIRInstr,
823+
CodeGenOpts.DebugInfoForProfiling);
819824
}
820825
if (TM)
821826
TM->setPGOOption(PGOOpt);
@@ -1219,9 +1224,9 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
12191224
const HeaderSearchOptions &HeaderOpts,
12201225
const CodeGenOptions &CGOpts,
12211226
const clang::TargetOptions &TOpts,
1222-
const LangOptions &LOpts,
1223-
StringRef TDesc, Module *M,
1224-
BackendAction Action,
1227+
const LangOptions &LOpts, StringRef TDesc,
1228+
Module *M, BackendAction Action,
1229+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
12251230
std::unique_ptr<raw_pwrite_stream> OS) {
12261231

12271232
llvm::TimeTraceScope TimeScope("Backend");
@@ -1264,7 +1269,7 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
12641269
}
12651270
}
12661271

1267-
EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M);
1272+
EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M, VFS);
12681273
AsmHelper.EmitAssembly(Action, std::move(OS));
12691274

12701275
// Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's

clang/lib/CodeGen/CodeGenAction.cpp

+12-11
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ namespace clang {
115115
const LangOptions &LangOpts;
116116
std::unique_ptr<raw_pwrite_stream> AsmOutStream;
117117
ASTContext *Context;
118+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
118119

119120
Timer LLVMIRGeneration;
120121
unsigned LLVMIRGenerationRefCount;
@@ -147,7 +148,7 @@ namespace clang {
147148

148149
public:
149150
BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
150-
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
151+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
151152
const HeaderSearchOptions &HeaderSearchOpts,
152153
const PreprocessorOptions &PPOpts,
153154
const CodeGenOptions &CodeGenOpts,
@@ -158,10 +159,10 @@ namespace clang {
158159
CoverageSourceInfo *CoverageInfo = nullptr)
159160
: Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
160161
CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
161-
AsmOutStream(std::move(OS)), Context(nullptr),
162+
AsmOutStream(std::move(OS)), Context(nullptr), FS(VFS),
162163
LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
163164
LLVMIRGenerationRefCount(0),
164-
Gen(CreateLLVMCodeGen(Diags, InFile, std::move(FS), HeaderSearchOpts,
165+
Gen(CreateLLVMCodeGen(Diags, InFile, std::move(VFS), HeaderSearchOpts,
165166
PPOpts, CodeGenOpts, C, CoverageInfo)),
166167
LinkModules(std::move(LinkModules)) {
167168
TimerIsEnabled = CodeGenOpts.TimePasses;
@@ -173,7 +174,7 @@ namespace clang {
173174
// to use the clang diagnostic handler for IR input files. It avoids
174175
// initializing the OS field.
175176
BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
176-
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
177+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
177178
const HeaderSearchOptions &HeaderSearchOpts,
178179
const PreprocessorOptions &PPOpts,
179180
const CodeGenOptions &CodeGenOpts,
@@ -183,10 +184,10 @@ namespace clang {
183184
CoverageSourceInfo *CoverageInfo = nullptr)
184185
: Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
185186
CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
186-
Context(nullptr),
187+
Context(nullptr), FS(VFS),
187188
LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
188189
LLVMIRGenerationRefCount(0),
189-
Gen(CreateLLVMCodeGen(Diags, "", std::move(FS), HeaderSearchOpts,
190+
Gen(CreateLLVMCodeGen(Diags, "", std::move(VFS), HeaderSearchOpts,
190191
PPOpts, CodeGenOpts, C, CoverageInfo)),
191192
LinkModules(std::move(LinkModules)), CurLinkModule(Module) {
192193
TimerIsEnabled = CodeGenOpts.TimePasses;
@@ -381,7 +382,7 @@ namespace clang {
381382

382383
EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
383384
LangOpts, C.getTargetInfo().getDataLayoutString(),
384-
getModule(), Action, std::move(AsmOutStream));
385+
getModule(), Action, FS, std::move(AsmOutStream));
385386

386387
Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
387388

@@ -1238,10 +1239,10 @@ void CodeGenAction::ExecuteAction() {
12381239
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
12391240
std::move(*OptRecordFileOrErr);
12401241

1241-
EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts,
1242-
TargetOpts, CI.getLangOpts(),
1243-
CI.getTarget().getDataLayoutString(), TheModule.get(), BA,
1244-
std::move(OS));
1242+
EmitBackendOutput(
1243+
Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, TargetOpts,
1244+
CI.getLangOpts(), CI.getTarget().getDataLayoutString(), TheModule.get(),
1245+
BA, CI.getFileManager().getVirtualFileSystemPtr(), std::move(OS));
12451246
if (OptRecordFile)
12461247
OptRecordFile->keep();
12471248
}

clang/lib/CodeGen/CodeGenModule.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ CodeGenModule::CodeGenModule(ASTContext &C,
107107
const CodeGenOptions &CGO, llvm::Module &M,
108108
DiagnosticsEngine &diags,
109109
CoverageSourceInfo *CoverageInfo)
110-
: Context(C), LangOpts(C.getLangOpts()), FS(std::move(FS)),
111-
HeaderSearchOpts(HSO), PreprocessorOpts(PPO), CodeGenOpts(CGO),
112-
TheModule(M), Diags(diags), Target(C.getTargetInfo()),
113-
ABI(createCXXABI(*this)), VMContext(M.getContext()), Types(*this),
114-
VTables(*this), SanitizerMD(new SanitizerMetadata(*this)) {
110+
: Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO),
111+
PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
112+
Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
113+
VMContext(M.getContext()), Types(*this), VTables(*this),
114+
SanitizerMD(new SanitizerMetadata(*this)) {
115115

116116
// Initialize the type cache.
117117
llvm::LLVMContext &LLVMContext = M.getContext();
@@ -185,7 +185,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
185185

186186
if (CodeGenOpts.hasProfileClangUse()) {
187187
auto ReaderOrErr = llvm::IndexedInstrProfReader::create(
188-
CodeGenOpts.ProfileInstrumentUsePath, CodeGenOpts.ProfileRemappingFile);
188+
CodeGenOpts.ProfileInstrumentUsePath, *FS,
189+
CodeGenOpts.ProfileRemappingFile);
189190
// We're checking for profile read errors in CompilerInvocation, so if
190191
// there was an error it should've already been caught. If it hasn't been
191192
// somehow, trip an assertion.

clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ class PCHContainerGenerator : public ASTConsumer {
320320
clang::EmitBackendOutput(
321321
Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts,
322322
Ctx.getTargetInfo().getDataLayoutString(), M.get(),
323-
BackendAction::Backend_EmitLL,
323+
BackendAction::Backend_EmitLL, FS,
324324
std::make_unique<llvm::raw_svector_ostream>(Buffer));
325325
llvm::dbgs() << Buffer;
326326
});
@@ -329,7 +329,7 @@ class PCHContainerGenerator : public ASTConsumer {
329329
clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
330330
LangOpts,
331331
Ctx.getTargetInfo().getDataLayoutString(), M.get(),
332-
BackendAction::Backend_EmitObj, std::move(OS));
332+
BackendAction::Backend_EmitObj, FS, std::move(OS));
333333

334334
// Free the memory for the temporary buffer.
335335
llvm::SmallVector<char, 0> Empty;

clang/lib/Frontend/CompilerInvocation.cpp

+15-6
Original file line numberDiff line numberDiff line change
@@ -1304,8 +1304,9 @@ static std::string serializeXRayInstrumentationBundle(const XRayInstrSet &S) {
13041304
// Set the profile kind using fprofile-instrument-use-path.
13051305
static void setPGOUseInstrumentor(CodeGenOptions &Opts,
13061306
const Twine &ProfileName,
1307+
llvm::vfs::FileSystem &FS,
13071308
DiagnosticsEngine &Diags) {
1308-
auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName);
1309+
auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName, FS);
13091310
if (auto E = ReaderOrErr.takeError()) {
13101311
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
13111312
"Error in reading profile %0: %1");
@@ -1724,9 +1725,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
17241725
: codegenoptions::DebugTemplateNamesKind::Mangled);
17251726
}
17261727

1727-
if (!Opts.ProfileInstrumentUsePath.empty())
1728-
setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath, Diags);
1729-
17301728
if (const Arg *A = Args.getLastArg(OPT_ftime_report, OPT_ftime_report_EQ)) {
17311729
Opts.TimePasses = true;
17321730

@@ -1962,8 +1960,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
19621960
Opts.OptimizationRemarkAnalysis.hasValidPattern();
19631961

19641962
bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
1965-
bool UsingProfile = UsingSampleProfile ||
1966-
(Opts.getProfileUse() != CodeGenOptions::ProfileNone);
1963+
bool UsingProfile =
1964+
UsingSampleProfile || !Opts.ProfileInstrumentUsePath.empty();
19671965

19681966
if (Opts.DiagnosticsWithHotness && !UsingProfile &&
19691967
// An IR file will contain PGO as metadata
@@ -4563,6 +4561,17 @@ bool CompilerInvocation::CreateFromArgsImpl(
45634561
append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
45644562
}
45654563

4564+
// Set PGOOptions. Need to create a temporary VFS to read the profile
4565+
// to determine the PGO type.
4566+
if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty()) {
4567+
auto FS =
4568+
createVFSFromOverlayFiles(Res.getHeaderSearchOpts().VFSOverlayFiles,
4569+
Diags, llvm::vfs::getRealFileSystem());
4570+
setPGOUseInstrumentor(Res.getCodeGenOpts(),
4571+
Res.getCodeGenOpts().ProfileInstrumentUsePath, *FS,
4572+
Diags);
4573+
}
4574+
45664575
FixupInvocation(Res, Diags, Args, DashX);
45674576

45684577
return Diags.getNumErrors() == NumErrorsBefore;

llvm/include/llvm/CodeGen/MIRSampleProfile.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef LLVM_CODEGEN_MIRSAMPLEPROFILE_H
1515
#define LLVM_CODEGEN_MIRSAMPLEPROFILE_H
1616

17+
#include "llvm/ADT/IntrusiveRefCntPtr.h"
1718
#include "llvm/ADT/StringRef.h"
1819
#include "llvm/CodeGen/MachineFunctionPass.h"
1920
#include "llvm/Support/Discriminator.h"
@@ -26,6 +27,10 @@ class MachineBlockFrequencyInfo;
2627
class MachineFunction;
2728
class Module;
2829

30+
namespace vfs {
31+
class FileSystem;
32+
} // namespace vfs
33+
2934
using namespace sampleprof;
3035

3136
class MIRProfileLoader;
@@ -41,7 +46,8 @@ class MIRProfileLoaderPass : public MachineFunctionPass {
4146
/// FS bits will only use the '1' bits in the Mask.
4247
MIRProfileLoaderPass(std::string FileName = "",
4348
std::string RemappingFileName = "",
44-
FSDiscriminatorPass P = FSDiscriminatorPass::Pass1);
49+
FSDiscriminatorPass P = FSDiscriminatorPass::Pass1,
50+
IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
4551

4652
/// getMachineFunction - Return the last machine function computed.
4753
const MachineFunction *getMachineFunction() const { return MF; }

llvm/include/llvm/CodeGen/Passes.h

+9-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ class Pass;
3131
class TargetMachine;
3232
class raw_ostream;
3333

34+
template <typename T> class IntrusiveRefCntPtr;
35+
namespace vfs {
36+
class FileSystem;
37+
} // namespace vfs
38+
3439
} // End llvm namespace
3540

3641
// List of target independent CodeGen pass IDs.
@@ -551,9 +556,10 @@ namespace llvm {
551556
createMIRAddFSDiscriminatorsPass(sampleprof::FSDiscriminatorPass P);
552557

553558
/// Read Flow Sensitive Profile.
554-
FunctionPass *createMIRProfileLoaderPass(std::string File,
555-
std::string RemappingFile,
556-
sampleprof::FSDiscriminatorPass P);
559+
FunctionPass *
560+
createMIRProfileLoaderPass(std::string File, std::string RemappingFile,
561+
sampleprof::FSDiscriminatorPass P,
562+
IntrusiveRefCntPtr<vfs::FileSystem> FS);
557563

558564
/// Creates MIR Debugify pass. \see MachineDebugify.cpp
559565
ModulePass *createDebugifyMachineModulePass();

llvm/include/llvm/Passes/PassBuilder.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class StringRef;
3232
class AAManager;
3333
class TargetMachine;
3434
class ModuleSummaryIndex;
35+
template <typename T> class IntrusiveRefCntPtr;
36+
namespace vfs {
37+
class FileSystem;
38+
} // namespace vfs
3539

3640
/// Tunable parameters for passes in the default pipelines.
3741
class PipelineTuningOptions {
@@ -567,7 +571,8 @@ class PassBuilder {
567571
/// Add PGOInstrumenation passes for O0 only.
568572
void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
569573
bool IsCS, std::string ProfileFile,
570-
std::string ProfileRemappingFile);
574+
std::string ProfileRemappingFile,
575+
IntrusiveRefCntPtr<vfs::FileSystem> FS);
571576

572577
/// Returns PIC. External libraries can use this to register pass
573578
/// instrumentation callbacks.
@@ -607,7 +612,8 @@ class PassBuilder {
607612
void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
608613
bool RunProfileGen, bool IsCS, std::string ProfileFile,
609614
std::string ProfileRemappingFile,
610-
ThinOrFullLTOPhase LTOPhase);
615+
ThinOrFullLTOPhase LTOPhase,
616+
IntrusiveRefCntPtr<vfs::FileSystem> FS);
611617
void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel);
612618

613619
// Extension Point callbacks

0 commit comments

Comments
 (0)