20
20
#include " swift/ABI/MetadataValues.h"
21
21
#include " swift/ABI/ObjectFile.h"
22
22
#include " swift/AST/DiagnosticsIRGen.h"
23
+ #include " swift/AST/DiagnosticsFrontend.h"
23
24
#include " swift/AST/IRGenOptions.h"
24
25
#include " swift/AST/IRGenRequests.h"
25
26
#include " swift/AST/LinkLibrary.h"
71
72
#include " llvm/Passes/PassBuilder.h"
72
73
#include " llvm/Passes/PassPlugin.h"
73
74
#include " llvm/Passes/StandardInstrumentations.h"
75
+ #include " llvm/Remarks/Remark.h"
76
+ #include " llvm/Remarks/RemarkStreamer.h"
74
77
#include " llvm/Support/CommandLine.h"
75
78
#include " llvm/Support/Debug.h"
76
79
#include " llvm/Support/ErrorHandling.h"
@@ -1143,7 +1146,7 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
1143
1146
NewUsed->setSection (" llvm.metadata" );
1144
1147
}
1145
1148
1146
- static void initLLVMModule (IRGenModule &IGM, SILModule &SIL) {
1149
+ static void initLLVMModule (IRGenModule &IGM, SILModule &SIL, std::optional< unsigned > idx = {} ) {
1147
1150
auto *Module = IGM.getModule ();
1148
1151
assert (Module && " Expected llvm:Module for IR generation!" );
1149
1152
@@ -1186,17 +1189,61 @@ static void initLLVMModule(IRGenModule &IGM, SILModule &SIL) {
1186
1189
llvm::ConstantAsMetadata::get (Value)}));
1187
1190
1188
1191
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
+ // FIXME: add a frontend flag to enable all LLVM remarks
1204
+ cantFail (RS.setFilter (" annotation-remarks" ));
1205
+ } else {
1206
+ // Don't filter for now.
1207
+ Context.setLLVMRemarkStreamer (
1208
+ std::make_unique<llvm::LLVMRemarkStreamer>(RS));
1209
+ }
1210
+ } else {
1211
+ assert (idx && " Not generating multiple output files?" );
1212
+
1213
+ // Construct llvmremarkstreamer objects for LLVM remarks originating in
1214
+ // the LLVM backend and install it in the remaining LLVMModule(s).
1215
+ auto &SILOpts = SIL.getOptions ();
1216
+ assert (SILOpts.AuxOptRecordFiles .size () > (*idx - 1 ));
1217
+
1218
+ const auto &filename = SILOpts.AuxOptRecordFiles [*idx - 1 ];
1219
+ auto &diagEngine = SIL.getASTContext ().Diags ;
1220
+ std::error_code errorCode;
1221
+ auto file = std::make_unique<llvm::raw_fd_ostream>(filename, errorCode,
1222
+ llvm::sys::fs::OF_None);
1223
+ if (errorCode) {
1224
+ diagEngine.diagnose (SourceLoc (), diag::cannot_open_file, filename,
1225
+ errorCode.message ());
1226
+ return ;
1227
+ }
1228
+
1229
+ const auto format = SILOpts.OptRecordFormat ;
1230
+ llvm::Expected<std::unique_ptr<llvm::remarks::RemarkSerializer>>
1231
+ remarkSerializerOrErr = llvm::remarks::createRemarkSerializer (
1232
+ format, llvm::remarks::SerializerMode::Separate, *file);
1233
+ if (llvm::Error err = remarkSerializerOrErr.takeError ()) {
1234
+ diagEngine.diagnose (SourceLoc (), diag::error_creating_remark_serializer,
1235
+ toString (std::move (err)));
1236
+ return ;
1237
+ }
1238
+
1239
+ auto auxRS = std::make_unique<llvm::remarks::RemarkStreamer>(
1240
+ std::move (*remarkSerializerOrErr), filename);
1241
+
1242
+ Context.setMainRemarkStreamer (std::move (auxRS));
1196
1243
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 " ) );
1244
+ std::make_unique<llvm::LLVMRemarkStreamer>(
1245
+ *Context. getMainRemarkStreamer ()));
1246
+ IGM. RemarkStream = std::move (file );
1200
1247
}
1201
1248
}
1202
1249
}
@@ -1545,6 +1592,7 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
1545
1592
auto &Ctx = M->getASTContext ();
1546
1593
// Create an IRGenModule for each source file.
1547
1594
bool DidRunSILCodeGenPreparePasses = false ;
1595
+ unsigned idx = 0 ;
1548
1596
for (auto *File : M->getFiles ()) {
1549
1597
auto nextSF = dyn_cast<SourceFile>(File);
1550
1598
if (!nextSF)
@@ -1561,11 +1609,12 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
1561
1609
if (!targetMachine) continue ;
1562
1610
1563
1611
// Create the IR emitter.
1612
+ auto outputName = *OutputIter++;
1564
1613
IRGenModule *IGM = new IRGenModule (
1565
- irgen, std::move (targetMachine), nextSF, desc.ModuleName , *OutputIter++ ,
1614
+ irgen, std::move (targetMachine), nextSF, desc.ModuleName , outputName ,
1566
1615
nextSF->getFilename (), nextSF->getPrivateDiscriminator ().str ());
1567
1616
1568
- initLLVMModule (*IGM, *SILMod);
1617
+ initLLVMModule (*IGM, *SILMod, idx++ );
1569
1618
if (!DidRunSILCodeGenPreparePasses) {
1570
1619
// Run SIL level IRGen preparation passes on the module the first time
1571
1620
// around.
0 commit comments