Merge pull request #82107 from tobias-stadler/remarks-fix-llvm-setup

[IRGen] Setup LLVMRemarkStreamer using existing RemarkStreamer
This commit is contained in:
Arnold Schwaighofer
2025-06-30 13:50:31 -07:00
committed by GitHub
5 changed files with 33 additions and 39 deletions

View File

@@ -68,6 +68,7 @@ private:
std::unique_ptr<llvm::LLVMContext> Context;
std::unique_ptr<llvm::Module> Module;
std::unique_ptr<llvm::TargetMachine> Target;
std::unique_ptr<llvm::raw_fd_ostream> RemarkStream;
GeneratedModule() : Context(nullptr), Module(nullptr), Target(nullptr) {}
@@ -81,13 +82,14 @@ public:
/// needed, use \c GeneratedModule::null() instead.
explicit GeneratedModule(std::unique_ptr<llvm::LLVMContext> &&Context,
std::unique_ptr<llvm::Module> &&Module,
std::unique_ptr<llvm::TargetMachine> &&Target)
: Context(std::move(Context)), Module(std::move(Module)),
Target(std::move(Target)) {
assert(getModule() && "Use GeneratedModule::null() instead");
assert(getContext() && "Use GeneratedModule::null() instead");
assert(getTargetMachine() && "Use GeneratedModule::null() instead");
}
std::unique_ptr<llvm::TargetMachine> &&Target,
std::unique_ptr<llvm::raw_fd_ostream> &&RemarkStream)
: Context(std::move(Context)), Module(std::move(Module)),
Target(std::move(Target)), RemarkStream(std::move(RemarkStream)) {
assert(getModule() && "Use GeneratedModule::null() instead");
assert(getContext() && "Use GeneratedModule::null() instead");
assert(getTargetMachine() && "Use GeneratedModule::null() instead");
}
GeneratedModule(GeneratedModule &&) = default;
GeneratedModule& operator=(GeneratedModule &&) = default;

View File

@@ -72,6 +72,10 @@ public:
/// \c llvm::remarks::RemarkStreamer with the given \c LLVMContext.
void intoLLVMContext(llvm::LLVMContext &Ctx) &;
std::unique_ptr<llvm::raw_fd_ostream> releaseStream() {
return std::move(remarkStream);
}
public:
/// Emit a remark through the streamer.
template <typename RemarkT>

View File

@@ -703,32 +703,11 @@ bool swift::performLLVM(const IRGenOptions &Opts,
assert(Opts.OutputKind == IRGenOutputKind::Module && "no output specified");
}
std::string OptRemarksRecordFile;
if (Opts.AnnotateCondFailMessage && !OutputFilename.empty()) {
OptRemarksRecordFile = std::string(OutputFilename);
OptRemarksRecordFile.append(".opt.yaml");
}
auto &Ctxt = Module->getContext();
std::unique_ptr<llvm::DiagnosticHandler> OldDiagnosticHandler =
Ctxt.getDiagnosticHandler();
Ctxt.setDiagnosticHandler(std::make_unique<SwiftDiagnosticHandler>(Opts));
llvm::Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
setupLLVMOptimizationRemarks(Ctxt, OptRemarksRecordFile.c_str(), "annotation-remarks", "yaml",
false/*RemarksWithHotness*/,
0/*RemarksHotnessThreshold*/);
if (Error E = OptRecordFileOrErr.takeError()) {
diagnoseSync(Diags, DiagMutex, SourceLoc(), diag::error_opening_output,
StringRef(OptRemarksRecordFile.c_str()),
toString(std::move(E)));
return true;
}
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
std::move(*OptRecordFileOrErr);
performLLVMOptimizations(Opts, Diags, DiagMutex, Module, TargetMachine,
OutputFile ? &OutputFile->getOS() : nullptr);
@@ -759,10 +738,8 @@ bool swift::performLLVM(const IRGenOptions &Opts,
}
auto res = compileAndWriteLLVM(Module, TargetMachine, Opts, Stats, Diags,
*OutputFile, DiagMutex,
CASIDFile ? CASIDFile.get() : nullptr);
if (OptRecordFile)
OptRecordFile->keep();
*OutputFile, DiagMutex,
CASIDFile ? CASIDFile.get() : nullptr);
Ctxt.setDiagnosticHandler(std::move(OldDiagnosticHandler));
@@ -1166,7 +1143,7 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
NewUsed->setSection("llvm.metadata");
}
static void initLLVMModule(const IRGenModule &IGM, SILModule &SIL) {
static void initLLVMModule(IRGenModule &IGM, SILModule &SIL) {
auto *Module = IGM.getModule();
assert(Module && "Expected llvm:Module for IR generation!");
@@ -1208,8 +1185,19 @@ static void initLLVMModule(const IRGenModule &IGM, SILModule &SIL) {
"standard-library"),
llvm::ConstantAsMetadata::get(Value)}));
if (auto *streamer = SIL.getSILRemarkStreamer()) {
streamer->intoLLVMContext(Module->getContext());
if (auto *SILstreamer = SIL.getSILRemarkStreamer()) {
// Install RemarkStreamer into LLVM and keep the remarks file alive. This is
// required even if no LLVM remarks are enabled, because the AsmPrinter
// serializes meta information about the remarks into the object file.
IGM.RemarkStream = SILstreamer->releaseStream();
SILstreamer->intoLLVMContext(Context);
auto &RS = *IGM.getLLVMContext().getMainRemarkStreamer();
if (IGM.getOptions().AnnotateCondFailMessage) {
Context.setLLVMRemarkStreamer(
std::make_unique<llvm::LLVMRemarkStreamer>(RS));
// FIXME: add a frontend flag to enable all LLVM remarks
cantFail(RS.setFilter("annotation-remarks"));
}
}
}

View File

@@ -1469,10 +1469,9 @@ bool IRGenModule::IsWellKnownBuiltinOrStructralType(CanType T) const {
GeneratedModule IRGenModule::intoGeneratedModule() && {
return GeneratedModule{
std::move(LLVMContext),
std::unique_ptr<llvm::Module>{ClangCodeGen->ReleaseModule()},
std::move(TargetMachine)
};
std::move(LLVMContext),
std::unique_ptr<llvm::Module>{ClangCodeGen->ReleaseModule()},
std::move(TargetMachine), std::move(RemarkStream)};
}
bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) {

View File

@@ -674,6 +674,7 @@ public:
SILModuleConventions silConv;
ModuleDecl *ObjCModule = nullptr;
ModuleDecl *ClangImporterModule = nullptr;
std::unique_ptr<llvm::raw_fd_ostream> RemarkStream;
llvm::StringMap<ModuleDecl*> OriginalModules;
llvm::SmallString<128> OutputFilename;