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,67 @@ 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
+ } 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));
1196
1249
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 );
1200
1253
}
1201
1254
}
1202
1255
}
@@ -1545,6 +1598,7 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
1545
1598
auto &Ctx = M->getASTContext ();
1546
1599
// Create an IRGenModule for each source file.
1547
1600
bool DidRunSILCodeGenPreparePasses = false ;
1601
+ unsigned idx = 0 ;
1548
1602
for (auto *File : M->getFiles ()) {
1549
1603
auto nextSF = dyn_cast<SourceFile>(File);
1550
1604
if (!nextSF)
@@ -1561,11 +1615,12 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
1561
1615
if (!targetMachine) continue ;
1562
1616
1563
1617
// Create the IR emitter.
1618
+ auto outputName = *OutputIter++;
1564
1619
IRGenModule *IGM = new IRGenModule (
1565
- irgen, std::move (targetMachine), nextSF, desc.ModuleName , *OutputIter++ ,
1620
+ irgen, std::move (targetMachine), nextSF, desc.ModuleName , outputName ,
1566
1621
nextSF->getFilename (), nextSF->getPrivateDiscriminator ().str ());
1567
1622
1568
- initLLVMModule (*IGM, *SILMod);
1623
+ initLLVMModule (*IGM, *SILMod, idx++ );
1569
1624
if (!DidRunSILCodeGenPreparePasses) {
1570
1625
// Run SIL level IRGen preparation passes on the module the first time
1571
1626
// around.
0 commit comments