Skip to content

Commit 7656837

Browse files
[IRGen] Setup LLVMRemarkStreamer using existing RemarkStreamer
Calling setupLLVMOptimizationRemarks overwrites the MainRemarkStreamer in the LLVM context. This prevents LLVM from serializing the remark meta information for the already emitted SIL remarks into the object file. Without the meta information bitstream remarks don't work correctly. Instead, emit SIL remarks and LLVM remarks to the same RemarkSerializer, and keep the file stream alive until after CodeGen.
1 parent 9259c3e commit 7656837

File tree

5 files changed

+33
-39
lines changed

5 files changed

+33
-39
lines changed

include/swift/AST/IRGenRequests.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class GeneratedModule final {
6868
std::unique_ptr<llvm::LLVMContext> Context;
6969
std::unique_ptr<llvm::Module> Module;
7070
std::unique_ptr<llvm::TargetMachine> Target;
71+
std::unique_ptr<llvm::raw_fd_ostream> RemarkStream;
7172

7273
GeneratedModule() : Context(nullptr), Module(nullptr), Target(nullptr) {}
7374

@@ -81,13 +82,14 @@ class GeneratedModule final {
8182
/// needed, use \c GeneratedModule::null() instead.
8283
explicit GeneratedModule(std::unique_ptr<llvm::LLVMContext> &&Context,
8384
std::unique_ptr<llvm::Module> &&Module,
84-
std::unique_ptr<llvm::TargetMachine> &&Target)
85-
: Context(std::move(Context)), Module(std::move(Module)),
86-
Target(std::move(Target)) {
87-
assert(getModule() && "Use GeneratedModule::null() instead");
88-
assert(getContext() && "Use GeneratedModule::null() instead");
89-
assert(getTargetMachine() && "Use GeneratedModule::null() instead");
90-
}
85+
std::unique_ptr<llvm::TargetMachine> &&Target,
86+
std::unique_ptr<llvm::raw_fd_ostream> &&RemarkStream)
87+
: Context(std::move(Context)), Module(std::move(Module)),
88+
Target(std::move(Target)), RemarkStream(std::move(RemarkStream)) {
89+
assert(getModule() && "Use GeneratedModule::null() instead");
90+
assert(getContext() && "Use GeneratedModule::null() instead");
91+
assert(getTargetMachine() && "Use GeneratedModule::null() instead");
92+
}
9193

9294
GeneratedModule(GeneratedModule &&) = default;
9395
GeneratedModule& operator=(GeneratedModule &&) = default;

include/swift/SIL/SILRemarkStreamer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ class SILRemarkStreamer {
7272
/// \c llvm::remarks::RemarkStreamer with the given \c LLVMContext.
7373
void intoLLVMContext(llvm::LLVMContext &Ctx) &;
7474

75+
std::unique_ptr<llvm::raw_fd_ostream> releaseStream() {
76+
return std::move(remarkStream);
77+
}
78+
7579
public:
7680
/// Emit a remark through the streamer.
7781
template <typename RemarkT>

lib/IRGen/IRGen.cpp

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -703,32 +703,11 @@ bool swift::performLLVM(const IRGenOptions &Opts,
703703
assert(Opts.OutputKind == IRGenOutputKind::Module && "no output specified");
704704
}
705705

706-
std::string OptRemarksRecordFile;
707-
if (Opts.AnnotateCondFailMessage && !OutputFilename.empty()) {
708-
OptRemarksRecordFile = std::string(OutputFilename);
709-
OptRemarksRecordFile.append(".opt.yaml");
710-
}
711-
712706
auto &Ctxt = Module->getContext();
713707
std::unique_ptr<llvm::DiagnosticHandler> OldDiagnosticHandler =
714708
Ctxt.getDiagnosticHandler();
715709
Ctxt.setDiagnosticHandler(std::make_unique<SwiftDiagnosticHandler>(Opts));
716710

717-
llvm::Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
718-
setupLLVMOptimizationRemarks(Ctxt, OptRemarksRecordFile.c_str(), "annotation-remarks", "yaml",
719-
false/*RemarksWithHotness*/,
720-
0/*RemarksHotnessThreshold*/);
721-
722-
if (Error E = OptRecordFileOrErr.takeError()) {
723-
diagnoseSync(Diags, DiagMutex, SourceLoc(), diag::error_opening_output,
724-
StringRef(OptRemarksRecordFile.c_str()),
725-
toString(std::move(E)));
726-
return true;
727-
}
728-
729-
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
730-
std::move(*OptRecordFileOrErr);
731-
732711
performLLVMOptimizations(Opts, Diags, DiagMutex, Module, TargetMachine,
733712
OutputFile ? &OutputFile->getOS() : nullptr);
734713

@@ -759,10 +738,8 @@ bool swift::performLLVM(const IRGenOptions &Opts,
759738
}
760739

761740
auto res = compileAndWriteLLVM(Module, TargetMachine, Opts, Stats, Diags,
762-
*OutputFile, DiagMutex,
763-
CASIDFile ? CASIDFile.get() : nullptr);
764-
if (OptRecordFile)
765-
OptRecordFile->keep();
741+
*OutputFile, DiagMutex,
742+
CASIDFile ? CASIDFile.get() : nullptr);
766743

767744
Ctxt.setDiagnosticHandler(std::move(OldDiagnosticHandler));
768745

@@ -1166,7 +1143,7 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
11661143
NewUsed->setSection("llvm.metadata");
11671144
}
11681145

1169-
static void initLLVMModule(const IRGenModule &IGM, SILModule &SIL) {
1146+
static void initLLVMModule(IRGenModule &IGM, SILModule &SIL) {
11701147
auto *Module = IGM.getModule();
11711148
assert(Module && "Expected llvm:Module for IR generation!");
11721149

@@ -1208,8 +1185,19 @@ static void initLLVMModule(const IRGenModule &IGM, SILModule &SIL) {
12081185
"standard-library"),
12091186
llvm::ConstantAsMetadata::get(Value)}));
12101187

1211-
if (auto *streamer = SIL.getSILRemarkStreamer()) {
1212-
streamer->intoLLVMContext(Module->getContext());
1188+
if (auto *SILstreamer = SIL.getSILRemarkStreamer()) {
1189+
// Install RemarkStreamer into LLVM and keep the remarks file alive. This is
1190+
// required even if no LLVM remarks are enabled, because the AsmPrinter
1191+
// serializes meta information about the remarks into the object file.
1192+
IGM.RemarkStream = SILstreamer->releaseStream();
1193+
SILstreamer->intoLLVMContext(Context);
1194+
auto &RS = *IGM.getLLVMContext().getMainRemarkStreamer();
1195+
if (IGM.getOptions().AnnotateCondFailMessage) {
1196+
Context.setLLVMRemarkStreamer(
1197+
std::make_unique<llvm::LLVMRemarkStreamer>(RS));
1198+
// FIXME: add a frontend flag to enable all LLVM remarks
1199+
cantFail(RS.setFilter("annotation-remarks"));
1200+
}
12131201
}
12141202
}
12151203

lib/IRGen/IRGenModule.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,10 +1469,9 @@ bool IRGenModule::IsWellKnownBuiltinOrStructralType(CanType T) const {
14691469

14701470
GeneratedModule IRGenModule::intoGeneratedModule() && {
14711471
return GeneratedModule{
1472-
std::move(LLVMContext),
1473-
std::unique_ptr<llvm::Module>{ClangCodeGen->ReleaseModule()},
1474-
std::move(TargetMachine)
1475-
};
1472+
std::move(LLVMContext),
1473+
std::unique_ptr<llvm::Module>{ClangCodeGen->ReleaseModule()},
1474+
std::move(TargetMachine), std::move(RemarkStream)};
14761475
}
14771476

14781477
bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) {

lib/IRGen/IRGenModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,7 @@ class IRGenModule {
674674
SILModuleConventions silConv;
675675
ModuleDecl *ObjCModule = nullptr;
676676
ModuleDecl *ClangImporterModule = nullptr;
677+
std::unique_ptr<llvm::raw_fd_ostream> RemarkStream;
677678

678679
llvm::StringMap<ModuleDecl*> OriginalModules;
679680
llvm::SmallString<128> OutputFilename;

0 commit comments

Comments
 (0)