namespace llvm {
class BitcodeModule;
template <typename T> class Expected;
+ template <typename T> class IntrusiveRefCntPtr;
class Module;
class MemoryBufferRef;
+ namespace vfs {
+ class FileSystem;
+ } // namespace vfs
}
namespace clang {
const CodeGenOptions &CGOpts,
const TargetOptions &TOpts, const LangOptions &LOpts,
StringRef TDesc, llvm::Module *M, BackendAction Action,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
std::unique_ptr<raw_pwrite_stream> OS);
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
const clang::TargetOptions &TargetOpts;
const LangOptions &LangOpts;
Module *TheModule;
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
Timer CodeGenerationTime;
const HeaderSearchOptions &HeaderSearchOpts,
const CodeGenOptions &CGOpts,
const clang::TargetOptions &TOpts,
- const LangOptions &LOpts, Module *M)
+ const LangOptions &LOpts, Module *M,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
: Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
- TargetOpts(TOpts), LangOpts(LOpts), TheModule(M),
+ TargetOpts(TOpts), LangOpts(LOpts), TheModule(M), VFS(std::move(VFS)),
CodeGenerationTime("codegen", "Code Generation Time"),
TargetTriple(TheModule->getTargetTriple()) {}
if (CodeGenOpts.hasProfileIRInstr())
// -fprofile-generate.
- PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty()
- ? getDefaultProfileGenName()
- : CodeGenOpts.InstrProfileOutput,
- "", "", PGOOptions::IRInstr, PGOOptions::NoCSAction,
- CodeGenOpts.DebugInfoForProfiling);
+ PGOOpt = PGOOptions(
+ CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName()
+ : CodeGenOpts.InstrProfileOutput,
+ "", "", nullptr, PGOOptions::IRInstr, PGOOptions::NoCSAction,
+ CodeGenOpts.DebugInfoForProfiling);
else if (CodeGenOpts.hasProfileIRUse()) {
// -fprofile-use.
auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
: PGOOptions::NoCSAction;
- PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
- CodeGenOpts.ProfileRemappingFile, PGOOptions::IRUse,
- CSAction, CodeGenOpts.DebugInfoForProfiling);
+ PGOOpt =
+ PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
+ CodeGenOpts.ProfileRemappingFile, VFS, PGOOptions::IRUse,
+ CSAction, CodeGenOpts.DebugInfoForProfiling);
} else if (!CodeGenOpts.SampleProfileFile.empty())
// -fprofile-sample-use
PGOOpt = PGOOptions(
CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile,
- PGOOptions::SampleUse, PGOOptions::NoCSAction,
+ VFS, PGOOptions::SampleUse, PGOOptions::NoCSAction,
CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);
else if (CodeGenOpts.PseudoProbeForProfiling)
// -fpseudo-probe-for-profiling
- PGOOpt =
- PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
- CodeGenOpts.DebugInfoForProfiling, true);
+ PGOOpt = PGOOptions("", "", "", nullptr, PGOOptions::NoAction,
+ PGOOptions::NoCSAction,
+ CodeGenOpts.DebugInfoForProfiling, true);
else if (CodeGenOpts.DebugInfoForProfiling)
// -fdebug-info-for-profiling
- PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
+ PGOOpt = PGOOptions("", "", "", nullptr, PGOOptions::NoAction,
PGOOptions::NoCSAction, true);
// Check to see if we want to generate a CS profile.
: CodeGenOpts.InstrProfileOutput;
PGOOpt->CSAction = PGOOptions::CSIRInstr;
} else
- PGOOpt = PGOOptions("",
- CodeGenOpts.InstrProfileOutput.empty()
- ? getDefaultProfileGenName()
- : CodeGenOpts.InstrProfileOutput,
- "", PGOOptions::NoAction, PGOOptions::CSIRInstr,
- CodeGenOpts.DebugInfoForProfiling);
+ PGOOpt =
+ PGOOptions("",
+ CodeGenOpts.InstrProfileOutput.empty()
+ ? getDefaultProfileGenName()
+ : CodeGenOpts.InstrProfileOutput,
+ "", nullptr, PGOOptions::NoAction, PGOOptions::CSIRInstr,
+ CodeGenOpts.DebugInfoForProfiling);
}
if (TM)
TM->setPGOOption(PGOOpt);
const HeaderSearchOptions &HeaderOpts,
const CodeGenOptions &CGOpts,
const clang::TargetOptions &TOpts,
- const LangOptions &LOpts,
- StringRef TDesc, Module *M,
- BackendAction Action,
+ const LangOptions &LOpts, StringRef TDesc,
+ Module *M, BackendAction Action,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
std::unique_ptr<raw_pwrite_stream> OS) {
llvm::TimeTraceScope TimeScope("Backend");
}
}
- EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M);
+ EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M, VFS);
AsmHelper.EmitAssembly(Action, std::move(OS));
// Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
const LangOptions &LangOpts;
std::unique_ptr<raw_pwrite_stream> AsmOutStream;
ASTContext *Context;
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
Timer LLVMIRGeneration;
unsigned LLVMIRGenerationRefCount;
public:
BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
- IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
const HeaderSearchOptions &HeaderSearchOpts,
const PreprocessorOptions &PPOpts,
const CodeGenOptions &CodeGenOpts,
CoverageSourceInfo *CoverageInfo = nullptr)
: Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
- AsmOutStream(std::move(OS)), Context(nullptr),
+ AsmOutStream(std::move(OS)), Context(nullptr), FS(VFS),
LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
LLVMIRGenerationRefCount(0),
- Gen(CreateLLVMCodeGen(Diags, InFile, std::move(FS), HeaderSearchOpts,
+ Gen(CreateLLVMCodeGen(Diags, InFile, std::move(VFS), HeaderSearchOpts,
PPOpts, CodeGenOpts, C, CoverageInfo)),
LinkModules(std::move(LinkModules)) {
TimerIsEnabled = CodeGenOpts.TimePasses;
// to use the clang diagnostic handler for IR input files. It avoids
// initializing the OS field.
BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
- IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
const HeaderSearchOptions &HeaderSearchOpts,
const PreprocessorOptions &PPOpts,
const CodeGenOptions &CodeGenOpts,
CoverageSourceInfo *CoverageInfo = nullptr)
: Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
- Context(nullptr),
+ Context(nullptr), FS(VFS),
LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
LLVMIRGenerationRefCount(0),
- Gen(CreateLLVMCodeGen(Diags, "", std::move(FS), HeaderSearchOpts,
+ Gen(CreateLLVMCodeGen(Diags, "", std::move(VFS), HeaderSearchOpts,
PPOpts, CodeGenOpts, C, CoverageInfo)),
LinkModules(std::move(LinkModules)), CurLinkModule(Module) {
TimerIsEnabled = CodeGenOpts.TimePasses;
EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
LangOpts, C.getTargetInfo().getDataLayoutString(),
- getModule(), Action, std::move(AsmOutStream));
+ getModule(), Action, FS, std::move(AsmOutStream));
Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
std::move(*OptRecordFileOrErr);
- EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts,
- TargetOpts, CI.getLangOpts(),
- CI.getTarget().getDataLayoutString(), TheModule.get(), BA,
- std::move(OS));
+ EmitBackendOutput(
+ Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, TargetOpts,
+ CI.getLangOpts(), CI.getTarget().getDataLayoutString(), TheModule.get(),
+ BA, CI.getFileManager().getVirtualFileSystemPtr(), std::move(OS));
if (OptRecordFile)
OptRecordFile->keep();
}
const CodeGenOptions &CGO, llvm::Module &M,
DiagnosticsEngine &diags,
CoverageSourceInfo *CoverageInfo)
- : Context(C), LangOpts(C.getLangOpts()), FS(std::move(FS)),
- HeaderSearchOpts(HSO), PreprocessorOpts(PPO), CodeGenOpts(CGO),
- TheModule(M), Diags(diags), Target(C.getTargetInfo()),
- ABI(createCXXABI(*this)), VMContext(M.getContext()), Types(*this),
- VTables(*this), SanitizerMD(new SanitizerMetadata(*this)) {
+ : Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO),
+ PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
+ Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
+ VMContext(M.getContext()), Types(*this), VTables(*this),
+ SanitizerMD(new SanitizerMetadata(*this)) {
// Initialize the type cache.
llvm::LLVMContext &LLVMContext = M.getContext();
if (CodeGenOpts.hasProfileClangUse()) {
auto ReaderOrErr = llvm::IndexedInstrProfReader::create(
- CodeGenOpts.ProfileInstrumentUsePath, CodeGenOpts.ProfileRemappingFile);
+ CodeGenOpts.ProfileInstrumentUsePath, *FS,
+ CodeGenOpts.ProfileRemappingFile);
// We're checking for profile read errors in CompilerInvocation, so if
// there was an error it should've already been caught. If it hasn't been
// somehow, trip an assertion.
clang::EmitBackendOutput(
Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts,
Ctx.getTargetInfo().getDataLayoutString(), M.get(),
- BackendAction::Backend_EmitLL,
+ BackendAction::Backend_EmitLL, FS,
std::make_unique<llvm::raw_svector_ostream>(Buffer));
llvm::dbgs() << Buffer;
});
clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
LangOpts,
Ctx.getTargetInfo().getDataLayoutString(), M.get(),
- BackendAction::Backend_EmitObj, std::move(OS));
+ BackendAction::Backend_EmitObj, FS, std::move(OS));
// Free the memory for the temporary buffer.
llvm::SmallVector<char, 0> Empty;
// Set the profile kind using fprofile-instrument-use-path.
static void setPGOUseInstrumentor(CodeGenOptions &Opts,
const Twine &ProfileName,
+ llvm::vfs::FileSystem &FS,
DiagnosticsEngine &Diags) {
- auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName);
+ auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName, FS);
if (auto E = ReaderOrErr.takeError()) {
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"Error in reading profile %0: %1");
: codegenoptions::DebugTemplateNamesKind::Mangled);
}
- if (!Opts.ProfileInstrumentUsePath.empty())
- setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath, Diags);
-
if (const Arg *A = Args.getLastArg(OPT_ftime_report, OPT_ftime_report_EQ)) {
Opts.TimePasses = true;
Opts.OptimizationRemarkAnalysis.hasValidPattern();
bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
- bool UsingProfile = UsingSampleProfile ||
- (Opts.getProfileUse() != CodeGenOptions::ProfileNone);
+ bool UsingProfile =
+ UsingSampleProfile || !Opts.ProfileInstrumentUsePath.empty();
if (Opts.DiagnosticsWithHotness && !UsingProfile &&
// An IR file will contain PGO as metadata
append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
}
+ // Set PGOOptions. Need to create a temporary VFS to read the profile
+ // to determine the PGO type.
+ if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty()) {
+ auto FS =
+ createVFSFromOverlayFiles(Res.getHeaderSearchOpts().VFSOverlayFiles,
+ Diags, llvm::vfs::getRealFileSystem());
+ setPGOUseInstrumentor(Res.getCodeGenOpts(),
+ Res.getCodeGenOpts().ProfileInstrumentUsePath, *FS,
+ Diags);
+ }
+
FixupInvocation(Res, Diags, Args, DashX);
return Diags.getNumErrors() == NumErrorsBefore;
#ifndef LLVM_CODEGEN_MIRSAMPLEPROFILE_H
#define LLVM_CODEGEN_MIRSAMPLEPROFILE_H
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/Discriminator.h"
class MachineFunction;
class Module;
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
using namespace sampleprof;
class MIRProfileLoader;
/// FS bits will only use the '1' bits in the Mask.
MIRProfileLoaderPass(std::string FileName = "",
std::string RemappingFileName = "",
- FSDiscriminatorPass P = FSDiscriminatorPass::Pass1);
+ FSDiscriminatorPass P = FSDiscriminatorPass::Pass1,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
/// getMachineFunction - Return the last machine function computed.
const MachineFunction *getMachineFunction() const { return MF; }
class TargetMachine;
class raw_ostream;
+template <typename T> class IntrusiveRefCntPtr;
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
} // End llvm namespace
// List of target independent CodeGen pass IDs.
createMIRAddFSDiscriminatorsPass(sampleprof::FSDiscriminatorPass P);
/// Read Flow Sensitive Profile.
- FunctionPass *createMIRProfileLoaderPass(std::string File,
- std::string RemappingFile,
- sampleprof::FSDiscriminatorPass P);
+ FunctionPass *
+ createMIRProfileLoaderPass(std::string File, std::string RemappingFile,
+ sampleprof::FSDiscriminatorPass P,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS);
/// Creates MIR Debugify pass. \see MachineDebugify.cpp
ModulePass *createDebugifyMachineModulePass();
class AAManager;
class TargetMachine;
class ModuleSummaryIndex;
+template <typename T> class IntrusiveRefCntPtr;
+namespace vfs {
+class FileSystem;
+} // namespace vfs
/// Tunable parameters for passes in the default pipelines.
class PipelineTuningOptions {
/// Add PGOInstrumenation passes for O0 only.
void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
bool IsCS, std::string ProfileFile,
- std::string ProfileRemappingFile);
+ std::string ProfileRemappingFile,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS);
/// Returns PIC. External libraries can use this to register pass
/// instrumentation callbacks.
void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
bool RunProfileGen, bool IsCS, std::string ProfileFile,
std::string ProfileRemappingFile,
- ThinOrFullLTOPhase LTOPhase);
+ ThinOrFullLTOPhase LTOPhase,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS);
void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel);
// Extension Point callbacks
class BuildIDFetcher;
} // namespace object
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
namespace coverage {
class CoverageMappingReader;
/// Ignores non-instrumented object files unless all are not instrumented.
static Expected<std::unique_ptr<CoverageMapping>>
load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
- ArrayRef<StringRef> Arches = std::nullopt, StringRef CompilationDir = "",
+ vfs::FileSystem &FS, ArrayRef<StringRef> Arches = std::nullopt,
+ StringRef CompilationDir = "",
const object::BuildIDFetcher *BIDFetcher = nullptr);
/// The number of functions that couldn't have their profiles mapped.
class InstrProfReader;
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
/// A file format agnostic iterator over profiling data.
template <class record_type = NamedInstrProfRecord,
class reader_type = InstrProfReader>
/// Factory method to create an appropriately typed reader for the given
/// instrprof file.
static Expected<std::unique_ptr<InstrProfReader>>
- create(const Twine &Path, const InstrProfCorrelator *Correlator = nullptr);
+ create(const Twine &Path, vfs::FileSystem &FS,
+ const InstrProfCorrelator *Correlator = nullptr);
static Expected<std::unique_ptr<InstrProfReader>>
create(std::unique_ptr<MemoryBuffer> Buffer,
/// Factory method to create an indexed reader.
static Expected<std::unique_ptr<IndexedInstrProfReader>>
- create(const Twine &Path, const Twine &RemappingPath = "");
+ create(const Twine &Path, vfs::FileSystem &FS,
+ const Twine &RemappingPath = "");
static Expected<std::unique_ptr<IndexedInstrProfReader>>
create(std::unique_ptr<MemoryBuffer> Buffer,
class raw_ostream;
class Twine;
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
namespace sampleprof {
class SampleProfileReader;
/// Create a remapper from the given remapping file. The remapper will
/// be used for profile read in by Reader.
static ErrorOr<std::unique_ptr<SampleProfileReaderItaniumRemapper>>
- create(const std::string Filename, SampleProfileReader &Reader,
- LLVMContext &C);
+ create(const std::string Filename, vfs::FileSystem &FS,
+ SampleProfileReader &Reader, LLVMContext &C);
/// Create a remapper from the given Buffer. The remapper will
/// be used for profile read in by Reader.
/// Create a remapper underlying if RemapFilename is not empty.
/// Parameter P specifies the FSDiscriminatorPass.
static ErrorOr<std::unique_ptr<SampleProfileReader>>
- create(const std::string Filename, LLVMContext &C,
+ create(const std::string Filename, LLVMContext &C, vfs::FileSystem &FS,
FSDiscriminatorPass P = FSDiscriminatorPass::Base,
const std::string RemapFilename = "");
/// Create a remapper underlying if RemapFilename is not empty.
/// Parameter P specifies the FSDiscriminatorPass.
static ErrorOr<std::unique_ptr<SampleProfileReader>>
- create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C,
+ create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C, vfs::FileSystem &FS,
FSDiscriminatorPass P = FSDiscriminatorPass::Base,
const std::string RemapFilename = "");
#ifndef LLVM_SUPPORT_PGOOPTIONS_H
#define LLVM_SUPPORT_PGOOPTIONS_H
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/Support/Error.h"
namespace llvm {
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
/// A struct capturing PGO tunables.
struct PGOOptions {
enum PGOAction { NoAction, IRInstr, IRUse, SampleUse };
enum CSPGOAction { NoCSAction, CSIRInstr, CSIRUse };
- PGOOptions(std::string ProfileFile = "", std::string CSProfileGenFile = "",
- std::string ProfileRemappingFile = "", PGOAction Action = NoAction,
- CSPGOAction CSAction = NoCSAction,
+ PGOOptions(std::string ProfileFile, std::string CSProfileGenFile,
+ std::string ProfileRemappingFile,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS,
+ PGOAction Action = NoAction, CSPGOAction CSAction = NoCSAction,
bool DebugInfoForProfiling = false,
- bool PseudoProbeForProfiling = false)
- : ProfileFile(ProfileFile), CSProfileGenFile(CSProfileGenFile),
- ProfileRemappingFile(ProfileRemappingFile), Action(Action),
- CSAction(CSAction), DebugInfoForProfiling(DebugInfoForProfiling ||
- (Action == SampleUse &&
- !PseudoProbeForProfiling)),
- PseudoProbeForProfiling(PseudoProbeForProfiling) {
- // Note, we do allow ProfileFile.empty() for Action=IRUse LTO can
- // callback with IRUse action without ProfileFile.
-
- // If there is a CSAction, PGOAction cannot be IRInstr or SampleUse.
- assert(this->CSAction == NoCSAction ||
- (this->Action != IRInstr && this->Action != SampleUse));
-
- // For CSIRInstr, CSProfileGenFile also needs to be nonempty.
- assert(this->CSAction != CSIRInstr || !this->CSProfileGenFile.empty());
-
- // If CSAction is CSIRUse, PGOAction needs to be IRUse as they share
- // a profile.
- assert(this->CSAction != CSIRUse || this->Action == IRUse);
+ bool PseudoProbeForProfiling = false);
+ PGOOptions(const PGOOptions &);
+ ~PGOOptions();
+ PGOOptions &operator=(const PGOOptions &);
- // If neither Action nor CSAction, DebugInfoForProfiling or
- // PseudoProbeForProfiling needs to be true.
- assert(this->Action != NoAction || this->CSAction != NoCSAction ||
- this->DebugInfoForProfiling || this->PseudoProbeForProfiling);
- }
std::string ProfileFile;
std::string CSProfileGenFile;
std::string ProfileRemappingFile;
CSPGOAction CSAction;
bool DebugInfoForProfiling;
bool PseudoProbeForProfiling;
+ IntrusiveRefCntPtr<vfs::FileSystem> FS;
};
} // namespace llvm
#ifndef LLVM_TRANSFORMS_IPO_SAMPLEPROFILE_H
#define LLVM_TRANSFORMS_IPO_SAMPLEPROFILE_H
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include <string>
class Module;
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
/// The sample profiler data loader pass.
class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> {
public:
SampleProfileLoaderPass(
std::string File = "", std::string RemappingFile = "",
- ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None)
- : ProfileFileName(File), ProfileRemappingFileName(RemappingFile),
- LTOPhase(LTOPhase) {}
+ ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
std::string ProfileFileName;
std::string ProfileRemappingFileName;
const ThinOrFullLTOPhase LTOPhase;
+ IntrusiveRefCntPtr<vfs::FileSystem> FS;
};
} // end namespace llvm
#define LLVM_TRANSFORMS_INSTRUMENTATION_PGOINSTRUMENTATION_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/IR/PassManager.h"
#include <cstdint>
#include <string>
class Instruction;
class Module;
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
/// The instrumentation (profile-instr-gen) pass for IR based PGO.
// We use this pass to create COMDAT profile variables for context
// sensitive PGO (CSPGO). The reason to have a pass for this is CSPGO
class PGOInstrumentationUse : public PassInfoMixin<PGOInstrumentationUse> {
public:
PGOInstrumentationUse(std::string Filename = "",
- std::string RemappingFilename = "", bool IsCS = false);
+ std::string RemappingFilename = "", bool IsCS = false,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
std::string ProfileRemappingFileName;
// If this is a context sensitive instrumentation.
bool IsCS;
+ IntrusiveRefCntPtr<vfs::FileSystem> FS;
};
/// The indirect function call promotion pass.
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
using namespace sampleprofutil;
using ProfileCount = Function::ProfileCount;
+namespace vfs {
+class FileSystem;
+} // namespace vfs
+
#define DEBUG_TYPE "sample-profile-impl"
namespace afdo_detail {
template <typename BT> class SampleProfileLoaderBaseImpl {
public:
- SampleProfileLoaderBaseImpl(std::string Name, std::string RemapName)
- : Filename(Name), RemappingFilename(RemapName) {}
+ SampleProfileLoaderBaseImpl(std::string Name, std::string RemapName,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS)
+ : Filename(Name), RemappingFilename(RemapName), FS(std::move(FS)) {}
void dump() { Reader->dump(); }
using InstructionT = typename afdo_detail::IRTraits<BT>::InstructionT;
/// Name of the profile remapping file to load.
std::string RemappingFilename;
+ /// VirtualFileSystem to load profile files from.
+ IntrusiveRefCntPtr<vfs::FileSystem> FS;
+
/// Profile Summary Info computed from sample profile.
ProfileSummaryInfo *PSI = nullptr;
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h"
#include "llvm/Transforms/Utils/SampleProfileLoaderBaseUtil.h"
char &llvm::MIRProfileLoaderPassID = MIRProfileLoaderPass::ID;
-FunctionPass *llvm::createMIRProfileLoaderPass(std::string File,
- std::string RemappingFile,
- FSDiscriminatorPass P) {
- return new MIRProfileLoaderPass(File, RemappingFile, P);
+FunctionPass *
+llvm::createMIRProfileLoaderPass(std::string File, std::string RemappingFile,
+ FSDiscriminatorPass P,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+ return new MIRProfileLoaderPass(File, RemappingFile, P, std::move(FS));
}
namespace llvm {
assert(LowBit < HighBit && "HighBit needs to be greater than Lowbit");
}
- MIRProfileLoader(StringRef Name, StringRef RemapName)
- : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName)) {
- }
+ MIRProfileLoader(StringRef Name, StringRef RemapName,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS)
+ : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName),
+ std::move(FS)) {}
void setBranchProbs(MachineFunction &F);
bool runOnFunction(MachineFunction &F);
bool MIRProfileLoader::doInitialization(Module &M) {
auto &Ctx = M.getContext();
- auto ReaderOrErr = sampleprof::SampleProfileReader::create(Filename, Ctx, P,
- RemappingFilename);
+ auto ReaderOrErr = sampleprof::SampleProfileReader::create(
+ Filename, Ctx, *FS, P, RemappingFilename);
if (std::error_code EC = ReaderOrErr.getError()) {
std::string Msg = "Could not open profile: " + EC.message();
Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
} // namespace llvm
-MIRProfileLoaderPass::MIRProfileLoaderPass(std::string FileName,
- std::string RemappingFileName,
- FSDiscriminatorPass P)
- : MachineFunctionPass(ID), ProfileFileName(FileName), P(P),
- MIRSampleLoader(
- std::make_unique<MIRProfileLoader>(FileName, RemappingFileName)) {
+MIRProfileLoaderPass::MIRProfileLoaderPass(
+ std::string FileName, std::string RemappingFileName, FSDiscriminatorPass P,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS)
+ : MachineFunctionPass(ID), ProfileFileName(FileName), P(P) {
LowBit = getFSPassBitBegin(P);
HighBit = getFSPassBitEnd(P);
+
+ auto VFS = FS ? std::move(FS) : vfs::getRealFileSystem();
+ MIRSampleLoader = std::make_unique<MIRProfileLoader>(
+ FileName, RemappingFileName, std::move(VFS));
assert(LowBit < HighBit && "HighBit needs to be greater than Lowbit");
}
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/Threading.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Target/CGPassBuilderOption.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
sampleprof::FSDiscriminatorPass::Pass1));
const std::string ProfileFile = getFSProfileFile(TM);
if (!ProfileFile.empty() && !DisableRAFSProfileLoader)
- addPass(
- createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM),
- sampleprof::FSDiscriminatorPass::Pass1));
+ addPass(createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM),
+ sampleprof::FSDiscriminatorPass::Pass1,
+ nullptr));
}
// Run register allocation and passes that are tightly coupled with it,
sampleprof::FSDiscriminatorPass::Pass2));
const std::string ProfileFile = getFSProfileFile(TM);
if (!ProfileFile.empty() && !DisableLayoutFSProfileLoader)
- addPass(
- createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM),
- sampleprof::FSDiscriminatorPass::Pass2));
+ addPass(createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM),
+ sampleprof::FSDiscriminatorPass::Pass2,
+ nullptr));
}
if (addPass(&MachineBlockPlacementID)) {
// Run a separate pass to collect block placement statistics.
#include "llvm/Support/Program.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
unsigned OptLevel, bool IsThinLTO,
ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary) {
+ auto FS = vfs::getRealFileSystem();
std::optional<PGOOptions> PGOOpt;
if (!Conf.SampleProfile.empty())
- PGOOpt = PGOOptions(Conf.SampleProfile, "", Conf.ProfileRemapping,
+ PGOOpt = PGOOptions(Conf.SampleProfile, "", Conf.ProfileRemapping, FS,
PGOOptions::SampleUse, PGOOptions::NoCSAction, true);
else if (Conf.RunCSIRInstr) {
- PGOOpt = PGOOptions("", Conf.CSIRProfile, Conf.ProfileRemapping,
+ PGOOpt = PGOOptions("", Conf.CSIRProfile, Conf.ProfileRemapping, FS,
PGOOptions::IRUse, PGOOptions::CSIRInstr,
Conf.AddFSDiscriminator);
} else if (!Conf.CSIRProfile.empty()) {
- PGOOpt = PGOOptions(Conf.CSIRProfile, "", Conf.ProfileRemapping,
+ PGOOpt = PGOOptions(Conf.CSIRProfile, "", Conf.ProfileRemapping, FS,
PGOOptions::IRUse, PGOOptions::CSIRUse,
Conf.AddFSDiscriminator);
NoPGOWarnMismatch = !Conf.PGOWarnMismatch;
} else if (Conf.AddFSDiscriminator) {
- PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
+ PGOOpt = PGOOptions("", "", "", nullptr, PGOOptions::NoAction,
PGOOptions::NoCSAction, true);
}
TM->setPGOOption(PGOOpt);
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/PGOOptions.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
#include "llvm/Transforms/Coroutines/CoroCleanup.h"
OptimizationLevel Level, bool RunProfileGen,
bool IsCS, std::string ProfileFile,
std::string ProfileRemappingFile,
- ThinOrFullLTOPhase LTOPhase) {
+ ThinOrFullLTOPhase LTOPhase,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS) {
assert(Level != OptimizationLevel::O0 && "Not expecting O0 here!");
if (!IsCS && !DisablePreInliner) {
InlineParams IP;
if (!RunProfileGen) {
assert(!ProfileFile.empty() && "Profile use expecting a profile file!");
- MPM.addPass(PGOInstrumentationUse(ProfileFile, ProfileRemappingFile, IsCS));
+ MPM.addPass(
+ PGOInstrumentationUse(ProfileFile, ProfileRemappingFile, IsCS, FS));
// Cache ProfileSummaryAnalysis once to avoid the potential need to insert
// RequireAnalysisPass for PSI before subsequent non-module passes.
MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
MPM.addPass(InstrProfiling(Options, IsCS));
}
-void PassBuilder::addPGOInstrPassesForO0(ModulePassManager &MPM,
- bool RunProfileGen, bool IsCS,
- std::string ProfileFile,
- std::string ProfileRemappingFile) {
+void PassBuilder::addPGOInstrPassesForO0(
+ ModulePassManager &MPM, bool RunProfileGen, bool IsCS,
+ std::string ProfileFile, std::string ProfileRemappingFile,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS) {
if (!RunProfileGen) {
assert(!ProfileFile.empty() && "Profile use expecting a profile file!");
- MPM.addPass(PGOInstrumentationUse(ProfileFile, ProfileRemappingFile, IsCS));
+ MPM.addPass(
+ PGOInstrumentationUse(ProfileFile, ProfileRemappingFile, IsCS, FS));
// Cache ProfileSummaryAnalysis once to avoid the potential need to insert
// RequireAnalysisPass for PSI before subsequent non-module passes.
MPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
addPGOInstrPasses(MPM, Level,
/* RunProfileGen */ PGOOpt->Action == PGOOptions::IRInstr,
/* IsCS */ false, PGOOpt->ProfileFile,
- PGOOpt->ProfileRemappingFile, Phase);
+ PGOOpt->ProfileRemappingFile, Phase, PGOOpt->FS);
MPM.addPass(PGOIndirectCallPromotion(false, false));
}
if (PGOOpt && Phase != ThinOrFullLTOPhase::ThinLTOPostLink &&
if (PGOOpt->CSAction == PGOOptions::CSIRInstr)
addPGOInstrPasses(MPM, Level, /* RunProfileGen */ true,
/* IsCS */ true, PGOOpt->CSProfileGenFile,
- PGOOpt->ProfileRemappingFile, LTOPhase);
+ PGOOpt->ProfileRemappingFile, LTOPhase, PGOOpt->FS);
else if (PGOOpt->CSAction == PGOOptions::CSIRUse)
addPGOInstrPasses(MPM, Level, /* RunProfileGen */ false,
/* IsCS */ true, PGOOpt->ProfileFile,
- PGOOpt->ProfileRemappingFile, LTOPhase);
+ PGOOpt->ProfileRemappingFile, LTOPhase, PGOOpt->FS);
}
// Re-compute GlobalsAA here prior to function passes. This is particularly
addPGOInstrPasses(MPM, Level, /* RunProfileGen */ true,
/* IsCS */ true, PGOOpt->CSProfileGenFile,
PGOOpt->ProfileRemappingFile,
- ThinOrFullLTOPhase::FullLTOPostLink);
+ ThinOrFullLTOPhase::FullLTOPostLink, PGOOpt->FS);
else if (PGOOpt->CSAction == PGOOptions::CSIRUse)
addPGOInstrPasses(MPM, Level, /* RunProfileGen */ false,
/* IsCS */ true, PGOOpt->ProfileFile,
PGOOpt->ProfileRemappingFile,
- ThinOrFullLTOPhase::FullLTOPostLink);
+ ThinOrFullLTOPhase::FullLTOPostLink, PGOOpt->FS);
}
// Break up allocas
addPGOInstrPassesForO0(
MPM,
/* RunProfileGen */ (PGOOpt->Action == PGOOptions::IRInstr),
- /* IsCS */ false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile);
+ /* IsCS */ false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile,
+ PGOOpt->FS);
for (auto &C : PipelineStartEPCallbacks)
C(MPM, Level);
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
Expected<std::unique_ptr<CoverageMapping>>
CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
- StringRef ProfileFilename, ArrayRef<StringRef> Arches,
- StringRef CompilationDir,
+ StringRef ProfileFilename, vfs::FileSystem &FS,
+ ArrayRef<StringRef> Arches, StringRef CompilationDir,
const object::BuildIDFetcher *BIDFetcher) {
- auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
+ auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename, FS);
if (Error E = ProfileReaderOrErr.takeError())
return createFileError(ProfileFilename, std::move(E));
auto ProfileReader = std::move(ProfileReaderOrErr.get());
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SwapByteOrder.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
bool IsCS) {
auto getProfileSum = [IsCS](const std::string &Filename,
CountSumOrPercent &Sum) -> Error {
- auto ReaderOrErr = InstrProfReader::create(Filename);
+ // This function is only used from llvm-profdata that doesn't use any kind
+ // of VFS. Just create a default RealFileSystem to read profiles.
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr = InstrProfReader::create(Filename, *FS);
if (Error E = ReaderOrErr.takeError()) {
return E;
}
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/SymbolRemappingReader.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
}
static Expected<std::unique_ptr<MemoryBuffer>>
-setupMemoryBuffer(const Twine &Path) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
- MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/true);
+setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS) {
+ auto BufferOrErr = Filename.str() == "-" ? MemoryBuffer::getSTDIN()
+ : FS.getBufferForFile(Filename);
if (std::error_code EC = BufferOrErr.getError())
return errorCodeToError(EC);
return std::move(BufferOrErr.get());
}
Expected<std::unique_ptr<InstrProfReader>>
-InstrProfReader::create(const Twine &Path,
+InstrProfReader::create(const Twine &Path, vfs::FileSystem &FS,
const InstrProfCorrelator *Correlator) {
// Set up the buffer to read.
- auto BufferOrError = setupMemoryBuffer(Path);
+ auto BufferOrError = setupMemoryBuffer(Path, FS);
if (Error E = BufferOrError.takeError())
return std::move(E);
return InstrProfReader::create(std::move(BufferOrError.get()), Correlator);
}
Expected<std::unique_ptr<IndexedInstrProfReader>>
-IndexedInstrProfReader::create(const Twine &Path, const Twine &RemappingPath) {
+IndexedInstrProfReader::create(const Twine &Path, vfs::FileSystem &FS,
+ const Twine &RemappingPath) {
// Set up the buffer to read.
- auto BufferOrError = setupMemoryBuffer(Path);
+ auto BufferOrError = setupMemoryBuffer(Path, FS);
if (Error E = BufferOrError.takeError())
return std::move(E);
std::unique_ptr<MemoryBuffer> RemappingBuffer;
std::string RemappingPathStr = RemappingPath.str();
if (!RemappingPathStr.empty()) {
- auto RemappingBufferOrError = setupMemoryBuffer(RemappingPathStr);
+ auto RemappingBufferOrError = setupMemoryBuffer(RemappingPathStr, FS);
if (Error E = RemappingBufferOrError.takeError())
return std::move(E);
RemappingBuffer = std::move(RemappingBufferOrError.get());
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstddef>
///
/// \returns an error code indicating the status of the buffer.
static ErrorOr<std::unique_ptr<MemoryBuffer>>
-setupMemoryBuffer(const Twine &Filename) {
- auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
+setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS) {
+ auto BufferOrErr = Filename.str() == "-" ? MemoryBuffer::getSTDIN()
+ : FS.getBufferForFile(Filename);
if (std::error_code EC = BufferOrErr.getError())
return EC;
auto Buffer = std::move(BufferOrErr.get());
/// \returns an error code indicating the status of the created reader.
ErrorOr<std::unique_ptr<SampleProfileReader>>
SampleProfileReader::create(const std::string Filename, LLVMContext &C,
- FSDiscriminatorPass P,
+ vfs::FileSystem &FS, FSDiscriminatorPass P,
const std::string RemapFilename) {
- auto BufferOrError = setupMemoryBuffer(Filename);
+ auto BufferOrError = setupMemoryBuffer(Filename, FS);
if (std::error_code EC = BufferOrError.getError())
return EC;
- return create(BufferOrError.get(), C, P, RemapFilename);
+ return create(BufferOrError.get(), C, FS, P, RemapFilename);
}
/// Create a sample profile remapper from the given input, to remap the
/// \returns an error code indicating the status of the created reader.
ErrorOr<std::unique_ptr<SampleProfileReaderItaniumRemapper>>
SampleProfileReaderItaniumRemapper::create(const std::string Filename,
+ vfs::FileSystem &FS,
SampleProfileReader &Reader,
LLVMContext &C) {
- auto BufferOrError = setupMemoryBuffer(Filename);
+ auto BufferOrError = setupMemoryBuffer(Filename, FS);
if (std::error_code EC = BufferOrError.getError())
return EC;
return create(BufferOrError.get(), Reader, C);
/// \returns an error code indicating the status of the created reader.
ErrorOr<std::unique_ptr<SampleProfileReader>>
SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C,
- FSDiscriminatorPass P,
+ vfs::FileSystem &FS, FSDiscriminatorPass P,
const std::string RemapFilename) {
std::unique_ptr<SampleProfileReader> Reader;
if (SampleProfileReaderRawBinary::hasFormat(*B))
return sampleprof_error::unrecognized_format;
if (!RemapFilename.empty()) {
- auto ReaderOrErr =
- SampleProfileReaderItaniumRemapper::create(RemapFilename, *Reader, C);
+ auto ReaderOrErr = SampleProfileReaderItaniumRemapper::create(
+ RemapFilename, FS, *Reader, C);
if (std::error_code EC = ReaderOrErr.getError()) {
std::string Msg = "Could not create remapper: " + EC.message();
C.diagnose(DiagnosticInfoSampleProfile(RemapFilename, Msg));
NativeFormatting.cpp
OptimizedStructLayout.cpp
Optional.cpp
+ PGOOptions.cpp
Parallel.cpp
PluginLoader.cpp
PrettyStackTrace.cpp
--- /dev/null
+//===------ PGOOptions.cpp -- PGO option tunables --------------*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/PGOOptions.h"
+#include "llvm/Support/VirtualFileSystem.h"
+
+using namespace llvm;
+
+PGOOptions::PGOOptions(std::string ProfileFile, std::string CSProfileGenFile,
+ std::string ProfileRemappingFile,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS, PGOAction Action,
+ CSPGOAction CSAction, bool DebugInfoForProfiling,
+ bool PseudoProbeForProfiling)
+ : ProfileFile(ProfileFile), CSProfileGenFile(CSProfileGenFile),
+ ProfileRemappingFile(ProfileRemappingFile), Action(Action),
+ CSAction(CSAction),
+ DebugInfoForProfiling(DebugInfoForProfiling ||
+ (Action == SampleUse && !PseudoProbeForProfiling)),
+ PseudoProbeForProfiling(PseudoProbeForProfiling), FS(std::move(FS)) {
+ // Note, we do allow ProfileFile.empty() for Action=IRUse LTO can
+ // callback with IRUse action without ProfileFile.
+
+ // If there is a CSAction, PGOAction cannot be IRInstr or SampleUse.
+ assert(this->CSAction == NoCSAction ||
+ (this->Action != IRInstr && this->Action != SampleUse));
+
+ // For CSIRInstr, CSProfileGenFile also needs to be nonempty.
+ assert(this->CSAction != CSIRInstr || !this->CSProfileGenFile.empty());
+
+ // If CSAction is CSIRUse, PGOAction needs to be IRUse as they share
+ // a profile.
+ assert(this->CSAction != CSIRUse || this->Action == IRUse);
+
+ // If neither Action nor CSAction, DebugInfoForProfiling or
+ // PseudoProbeForProfiling needs to be true.
+ assert(this->Action != NoAction || this->CSAction != NoCSAction ||
+ this->DebugInfoForProfiling || this->PseudoProbeForProfiling);
+
+ // If we need to use the profile, the VFS cannot be nullptr.
+ assert(this->FS || !(this->Action == IRUse || this->CSAction == CSIRUse));
+}
+
+PGOOptions::PGOOptions(const PGOOptions &) = default;
+
+PGOOptions &PGOOptions::operator=(const PGOOptions &O) = default;
+
+PGOOptions::~PGOOptions() = default;
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/ProfileData/SampleProfReader.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Transforms/IPO/SampleProfile.h"
using namespace llvm;
using namespace sampleprof;
return false;
LLVMContext &Ctx = M.getContext();
+ // TODO: Propagate virtual file system into LLVM targets.
+ auto FS = vfs::getRealFileSystem();
ErrorOr<std::unique_ptr<SampleProfileReader>> ReaderOrErr =
- SampleProfileReader::create(Filename, Ctx);
+ SampleProfileReader::create(Filename, Ctx, *FS);
if (std::error_code EC = ReaderOrErr.getError()) {
std::string Msg = "Could not open profile: " + EC.message();
Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg,
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/ProfiledCallGraph.h"
public:
SampleProfileLoader(
StringRef Name, StringRef RemapName, ThinOrFullLTOPhase LTOPhase,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS,
std::function<AssumptionCache &(Function &)> GetAssumptionCache,
std::function<TargetTransformInfo &(Function &)> GetTargetTransformInfo,
std::function<const TargetLibraryInfo &(Function &)> GetTLI)
- : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName)),
+ : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName),
+ std::move(FS)),
GetAC(std::move(GetAssumptionCache)),
GetTTI(std::move(GetTargetTransformInfo)), GetTLI(std::move(GetTLI)),
LTOPhase(LTOPhase),
auto &Ctx = M.getContext();
auto ReaderOrErr = SampleProfileReader::create(
- Filename, Ctx, FSDiscriminatorPass::Base, RemappingFilename);
+ Filename, Ctx, *FS, FSDiscriminatorPass::Base, RemappingFilename);
if (std::error_code EC = ReaderOrErr.getError()) {
std::string Msg = "Could not open profile: " + EC.message();
Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
return emitAnnotations(F);
return false;
}
+SampleProfileLoaderPass::SampleProfileLoaderPass(
+ std::string File, std::string RemappingFile, ThinOrFullLTOPhase LTOPhase,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS)
+ : ProfileFileName(File), ProfileRemappingFileName(RemappingFile),
+ LTOPhase(LTOPhase), FS(std::move(FS)) {}
PreservedAnalyses SampleProfileLoaderPass::run(Module &M,
ModuleAnalysisManager &AM) {
return FAM.getResult<TargetLibraryAnalysis>(F);
};
+ if (!FS)
+ FS = vfs::getRealFileSystem();
+
SampleProfileLoader SampleLoader(
ProfileFileName.empty() ? SampleProfileFile : ProfileFileName,
ProfileRemappingFileName.empty() ? SampleProfileRemappingFile
: ProfileRemappingFileName,
- LTOPhase, GetAssumptionCache, GetTTI, GetTLI);
+ LTOPhase, FS, GetAssumptionCache, GetTTI, GetTLI);
if (!SampleLoader.doInitialization(M, &FAM))
return PreservedAnalyses::all();
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/HashBuilder.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
static bool annotateAllFunctions(
Module &M, StringRef ProfileFileName, StringRef ProfileRemappingFileName,
+ vfs::FileSystem &FS,
function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
function_ref<BlockFrequencyInfo *(Function &)> LookupBFI,
LLVM_DEBUG(dbgs() << "Read in profile counters: ");
auto &Ctx = M.getContext();
// Read the counter array from file.
- auto ReaderOrErr =
- IndexedInstrProfReader::create(ProfileFileName, ProfileRemappingFileName);
+ auto ReaderOrErr = IndexedInstrProfReader::create(ProfileFileName, FS,
+ ProfileRemappingFileName);
if (Error E = ReaderOrErr.takeError()) {
handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
Ctx.diagnose(
return true;
}
-PGOInstrumentationUse::PGOInstrumentationUse(std::string Filename,
- std::string RemappingFilename,
- bool IsCS)
+PGOInstrumentationUse::PGOInstrumentationUse(
+ std::string Filename, std::string RemappingFilename, bool IsCS,
+ IntrusiveRefCntPtr<vfs::FileSystem> VFS)
: ProfileFileName(std::move(Filename)),
- ProfileRemappingFileName(std::move(RemappingFilename)), IsCS(IsCS) {
+ ProfileRemappingFileName(std::move(RemappingFilename)), IsCS(IsCS),
+ FS(std::move(VFS)) {
if (!PGOTestProfileFile.empty())
ProfileFileName = PGOTestProfileFile;
if (!PGOTestProfileRemappingFile.empty())
ProfileRemappingFileName = PGOTestProfileRemappingFile;
+ if (!FS)
+ FS = vfs::getRealFileSystem();
}
PreservedAnalyses PGOInstrumentationUse::run(Module &M,
auto *PSI = &AM.getResult<ProfileSummaryAnalysis>(M);
- if (!annotateAllFunctions(M, ProfileFileName, ProfileRemappingFileName,
+ if (!annotateAllFunctions(M, ProfileFileName, ProfileRemappingFileName, *FS,
LookupTLI, LookupBPI, LookupBFI, PSI, IsCS))
return PreservedAnalyses::all();
if (modifiedTimeGT(ObjectFilename, PGOFilename))
warning("profile data may be out of date - object is newer",
ObjectFilename);
+ auto FS = vfs::getRealFileSystem();
auto CoverageOrErr =
- CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches,
+ CoverageMapping::load(ObjectFilenames, PGOFilename, *FS, CoverageArches,
ViewOpts.CompilationDirectory, BIDFetcher.get());
if (Error E = CoverageOrErr.takeError()) {
error("Failed to load coverage: " + toString(std::move(E)));
#include "llvm/Support/Path.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/Threading.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
OverlapStats &Overlap,
const OverlapFuncFilters &FuncFilter,
raw_fd_ostream &OS, bool IsCS) {
- auto ReaderOrErr = InstrProfReader::create(TestFilename);
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr = InstrProfReader::create(TestFilename, *FS);
if (Error E = ReaderOrErr.takeError()) {
// Skip the empty profiles by returning sliently.
instrprof_error IPE = InstrProfError::take(std::move(E));
return;
}
- auto ReaderOrErr = InstrProfReader::create(Input.Filename, Correlator);
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr = InstrProfReader::create(Input.Filename, *FS, Correlator);
if (Error E = ReaderOrErr.takeError()) {
// Skip the empty profiles by returning sliently.
instrprof_error IPE = InstrProfError::take(std::move(E));
// Read sample profile.
LLVMContext Context;
+ auto FS = vfs::getRealFileSystem();
auto ReaderOrErr = sampleprof::SampleProfileReader::create(
- SampleFilename.str(), Context, FSDiscriminatorPassOption);
+ SampleFilename.str(), Context, *FS, FSDiscriminatorPassOption);
if (std::error_code EC = ReaderOrErr.getError())
exitWithErrorCode(EC, SampleFilename);
auto Reader = std::move(ReaderOrErr.get());
std::optional<bool> ProfileIsProbeBased;
std::optional<bool> ProfileIsCS;
for (const auto &Input : Inputs) {
- auto ReaderOrErr = SampleProfileReader::create(Input.Filename, Context,
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr = SampleProfileReader::create(Input.Filename, Context, *FS,
FSDiscriminatorPassOption);
if (std::error_code EC = ReaderOrErr.getError()) {
warnOrExitGivenError(FailMode, EC, Input.Filename);
using namespace sampleprof;
LLVMContext Context;
- auto BaseReaderOrErr = SampleProfileReader::create(BaseFilename, Context,
+ auto FS = vfs::getRealFileSystem();
+ auto BaseReaderOrErr = SampleProfileReader::create(BaseFilename, Context, *FS,
FSDiscriminatorPassOption);
if (std::error_code EC = BaseReaderOrErr.getError())
exitWithErrorCode(EC, BaseFilename);
- auto TestReaderOrErr = SampleProfileReader::create(TestFilename, Context,
+ auto TestReaderOrErr = SampleProfileReader::create(TestFilename, Context, *FS,
FSDiscriminatorPassOption);
if (std::error_code EC = TestReaderOrErr.getError())
exitWithErrorCode(EC, TestFilename);
exitWithError("JSON output is not supported for instr profiles");
if (SFormat == ShowFormat::Yaml)
exitWithError("YAML output is not supported for instr profiles");
- auto ReaderOrErr = InstrProfReader::create(Filename);
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr = InstrProfReader::create(Filename, *FS);
std::vector<uint32_t> Cutoffs = std::move(DetailedSummaryCutoffs);
if (ShowDetailedSummary && Cutoffs.empty()) {
Cutoffs = ProfileSummaryBuilder::DefaultCutoffs;
exitWithError("YAML output is not supported for sample profiles");
using namespace sampleprof;
LLVMContext Context;
- auto ReaderOrErr =
- SampleProfileReader::create(Filename, Context, FSDiscriminatorPassOption);
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr = SampleProfileReader::create(Filename, Context, *FS,
+ FSDiscriminatorPassOption);
if (std::error_code EC = ReaderOrErr.getError())
exitWithErrorCode(EC, Filename);
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/VirtualFileSystem.h"
static cl::OptionCategory ProfGenCategory("ProfGen Options");
if (SampleProfFilename.getNumOccurrences()) {
LLVMContext Context;
- auto ReaderOrErr = SampleProfileReader::create(SampleProfFilename, Context);
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr =
+ SampleProfileReader::create(SampleProfFilename, Context, *FS);
std::unique_ptr<sampleprof::SampleProfileReader> Reader =
std::move(ReaderOrErr.get());
Reader->read();
#include "llvm/Passes/StandardInstrumentations.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
bool EnableDebugify, bool VerifyDIPreserve) {
bool VerifyEachPass = VK == VK_VerifyEachPass;
+ auto FS = vfs::getRealFileSystem();
std::optional<PGOOptions> P;
switch (PGOKindFlag) {
case InstrGen:
- P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr);
+ P = PGOOptions(ProfileFile, "", "", FS, PGOOptions::IRInstr);
break;
case InstrUse:
- P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse);
+ P = PGOOptions(ProfileFile, "", ProfileRemappingFile, FS,
+ PGOOptions::IRUse);
break;
case SampleUse:
- P = PGOOptions(ProfileFile, "", ProfileRemappingFile,
+ P = PGOOptions(ProfileFile, "", ProfileRemappingFile, FS,
PGOOptions::SampleUse);
break;
case NoPGO:
if (DebugInfoForProfiling || PseudoProbeForProfiling)
- P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
- DebugInfoForProfiling, PseudoProbeForProfiling);
+ P = PGOOptions("", "", "", nullptr, PGOOptions::NoAction,
+ PGOOptions::NoCSAction, DebugInfoForProfiling,
+ PseudoProbeForProfiling);
else
P = std::nullopt;
}
P->CSAction = PGOOptions::CSIRInstr;
P->CSProfileGenFile = CSProfileGenFile;
} else
- P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
+ P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile, FS,
PGOOptions::NoAction, PGOOptions::CSIRInstr);
} else /* CSPGOKindFlag == CSInstrUse */ {
if (!P) {
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Testing/Support/SupportHelpers.h"
#include "gtest/gtest.h"
void readProfile(const Module &M, StringRef Profile,
StringRef RemapFile = "") {
+ auto FS = vfs::getRealFileSystem();
auto ReaderOrErr = SampleProfileReader::create(
- std::string(Profile), Context, FSDiscriminatorPass::Base,
+ std::string(Profile), Context, *FS, FSDiscriminatorPass::Base,
std::string(RemapFile));
ASSERT_TRUE(NoError(ReaderOrErr.getError()));
Reader = std::move(ReaderOrErr.get());