2020#include " swift/ABI/MetadataValues.h"
2121#include " swift/ABI/ObjectFile.h"
2222#include " swift/AST/DiagnosticsIRGen.h"
23+ #include " swift/AST/DiagnosticsFrontend.h"
2324#include " swift/AST/IRGenOptions.h"
2425#include " swift/AST/IRGenRequests.h"
2526#include " swift/AST/LinkLibrary.h"
7172#include " llvm/Passes/PassBuilder.h"
7273#include " llvm/Passes/PassPlugin.h"
7374#include " llvm/Passes/StandardInstrumentations.h"
75+ #include " llvm/Remarks/Remark.h"
76+ #include " llvm/Remarks/RemarkStreamer.h"
7477#include " llvm/Support/CommandLine.h"
7578#include " llvm/Support/Debug.h"
7679#include " llvm/Support/ErrorHandling.h"
@@ -1143,7 +1146,7 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
11431146 NewUsed->setSection (" llvm.metadata" );
11441147}
11451148
1146- static void initLLVMModule (IRGenModule &IGM, SILModule &SIL) {
1149+ static void initLLVMModule (IRGenModule &IGM, SILModule &SIL, std::optional< unsigned > idx = {} ) {
11471150 auto *Module = IGM.getModule ();
11481151 assert (Module && " Expected llvm:Module for IR generation!" );
11491152
@@ -1186,17 +1189,67 @@ static void initLLVMModule(IRGenModule &IGM, SILModule &SIL) {
11861189 llvm::ConstantAsMetadata::get (Value)}));
11871190
11881191 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 ) {
1192+ auto remarkStream = SILstreamer->releaseStream ();
1193+ if (remarkStream) {
1194+ // Install RemarkStreamer into LLVM and keep the remarks file alive. This is
1195+ // required even if no LLVM remarks are enabled, because the AsmPrinter
1196+ // serializes meta information about the remarks into the object file.
1197+ IGM.RemarkStream = std::move (remarkStream);
1198+ SILstreamer->intoLLVMContext (Context);
1199+ auto &RS = *IGM.getLLVMContext ().getMainRemarkStreamer ();
1200+ if (IGM.getOptions ().AnnotateCondFailMessage ) {
1201+ Context.setLLVMRemarkStreamer (
1202+ std::make_unique<llvm::LLVMRemarkStreamer>(RS));
1203+ } else {
1204+ // Don't filter for now.
1205+ Context.setLLVMRemarkStreamer (
1206+ std::make_unique<llvm::LLVMRemarkStreamer>(RS));
1207+ }
1208+ } else {
1209+ assert (idx && " Not generating multiple output files?" );
1210+
1211+ // Construct llvmremarkstreamer objects for LLVM remarks originating in
1212+ // the LLVM backend and install it in the remaining LLVMModule(s).
1213+ auto &SILOpts = SIL.getOptions ();
1214+ assert (SILOpts.AuxOptRecordFiles .size () > (*idx - 1 ));
1215+
1216+ const auto &filename = SILOpts.AuxOptRecordFiles [*idx - 1 ];
1217+ auto &diagEngine = SIL.getASTContext ().Diags ;
1218+ std::error_code errorCode;
1219+ auto file = std::make_unique<llvm::raw_fd_ostream>(filename, errorCode,
1220+ llvm::sys::fs::OF_None);
1221+ if (errorCode) {
1222+ diagEngine.diagnose (SourceLoc (), diag::cannot_open_file, filename,
1223+ errorCode.message ());
1224+ return ;
1225+ }
1226+
1227+ const auto format = SILOpts.OptRecordFormat ;
1228+ llvm::Expected<std::unique_ptr<llvm::remarks::RemarkSerializer>>
1229+ remarkSerializerOrErr = llvm::remarks::createRemarkSerializer (
1230+ format, llvm::remarks::SerializerMode::Separate, *file);
1231+ if (llvm::Error err = remarkSerializerOrErr.takeError ()) {
1232+ diagEngine.diagnose (SourceLoc (), diag::error_creating_remark_serializer,
1233+ toString (std::move (err)));
1234+ return ;
1235+ }
1236+
1237+ auto auxRS = std::make_unique<llvm::remarks::RemarkStreamer>(
1238+ std::move (*remarkSerializerOrErr), filename);
1239+ const auto passes = SILOpts.OptRecordPasses ;
1240+ if (!passes.empty ()) {
1241+ if (llvm::Error err = auxRS->setFilter (passes)) {
1242+ diagEngine.diagnose (SourceLoc (), diag::error_creating_remark_serializer,
1243+ toString (std::move (err)));
1244+ return ;
1245+ }
1246+ }
1247+
1248+ Context.setMainRemarkStreamer (std::move (auxRS));
11961249 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 " ) );
1250+ std::make_unique<llvm::LLVMRemarkStreamer>(
1251+ *Context. getMainRemarkStreamer ()));
1252+ IGM. RemarkStream = std::move (file );
12001253 }
12011254 }
12021255}
@@ -1545,6 +1598,7 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
15451598 auto &Ctx = M->getASTContext ();
15461599 // Create an IRGenModule for each source file.
15471600 bool DidRunSILCodeGenPreparePasses = false ;
1601+ unsigned idx = 0 ;
15481602 for (auto *File : M->getFiles ()) {
15491603 auto nextSF = dyn_cast<SourceFile>(File);
15501604 if (!nextSF)
@@ -1561,11 +1615,12 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
15611615 if (!targetMachine) continue ;
15621616
15631617 // Create the IR emitter.
1618+ auto outputName = *OutputIter++;
15641619 IRGenModule *IGM = new IRGenModule (
1565- irgen, std::move (targetMachine), nextSF, desc.ModuleName , *OutputIter++ ,
1620+ irgen, std::move (targetMachine), nextSF, desc.ModuleName , outputName ,
15661621 nextSF->getFilename (), nextSF->getPrivateDiscriminator ().str ());
15671622
1568- initLLVMModule (*IGM, *SILMod);
1623+ initLLVMModule (*IGM, *SILMod, idx++ );
15691624 if (!DidRunSILCodeGenPreparePasses) {
15701625 // Run SIL level IRGen preparation passes on the module the first time
15711626 // around.
0 commit comments