72
72
#include " llvm/Passes/PassBuilder.h"
73
73
#include " llvm/Passes/PassPlugin.h"
74
74
#include " llvm/Passes/StandardInstrumentations.h"
75
+ #include " llvm/ProfileData/InstrProfReader.h"
75
76
#include " llvm/Remarks/Remark.h"
76
77
#include " llvm/Remarks/RemarkStreamer.h"
77
78
#include " llvm/Support/CommandLine.h"
@@ -214,8 +215,57 @@ static void align(llvm::Module *Module) {
214
215
}
215
216
}
216
217
218
+ static std::unique_ptr<llvm::IndexedInstrProfReader>
219
+ getProfileReader (const Twine &ProfileName, llvm::vfs::FileSystem &FS,
220
+ DiagnosticEngine &Diags) {
221
+ auto ReaderOrErr = llvm::IndexedInstrProfReader::create (ProfileName, FS);
222
+ if (auto E = ReaderOrErr.takeError ()) {
223
+ llvm::handleAllErrors (std::move (E), [&](const llvm::ErrorInfoBase &EI) {
224
+ Diags.diagnose (SourceLoc (), diag::ir_profile_read_failed,
225
+ ProfileName.str (), EI.message ());
226
+ });
227
+ return nullptr ;
228
+ }
229
+ return std::move (*ReaderOrErr);
230
+ }
231
+
232
+ static std::optional<PGOOptions> buildIRUseOptions (const IRGenOptions &Opts,
233
+ DiagnosticEngine &Diags) {
234
+ if (Opts.UseIRProfile .empty ())
235
+ return std::nullopt ;
236
+
237
+ auto FS = llvm::vfs::getRealFileSystem ();
238
+ std::unique_ptr<llvm::IndexedInstrProfReader> Reader =
239
+ getProfileReader (Opts.UseIRProfile .c_str (), *FS, Diags);
240
+ if (!Reader)
241
+ return std::nullopt ;
242
+
243
+ // Currently memprof profiles are only added at the IR level. Mark the
244
+ // profile type as IR in that case as well and the subsequent matching
245
+ // needs to detect which is available (might be one or both).
246
+ const bool IsIR = Reader->isIRLevelProfile () || Reader->hasMemoryProfile ();
247
+ if (!IsIR) {
248
+ Diags.diagnose (SourceLoc (), diag::ir_profile_invalid,
249
+ Opts.UseIRProfile .c_str ());
250
+ return std::nullopt ;
251
+ }
252
+
253
+ const bool IsCS = Reader->hasCSIRLevelProfile ();
254
+ return PGOOptions (
255
+ /* ProfileFile=*/ Opts.UseIRProfile ,
256
+ /* CSProfileGenFile=*/ " " ,
257
+ /* ProfileRemappingFile=*/ " " ,
258
+ /* MemoryProfile=*/ " " ,
259
+ /* FS=*/ FS,
260
+ /* Action=*/ PGOOptions::IRUse,
261
+ /* CSPGOAction=*/ IsCS ? PGOOptions::CSIRUse : PGOOptions::NoCSAction,
262
+ /* ColdType=*/ PGOOptions::ColdFuncOpt::Default,
263
+ /* DebugInfoForProfiling=*/ Opts.DebugInfoForProfiling );
264
+ }
265
+
217
266
static void populatePGOOptions (std::optional<PGOOptions> &Out,
218
- const IRGenOptions &Opts) {
267
+ const IRGenOptions &Opts,
268
+ DiagnosticEngine &Diags) {
219
269
if (!Opts.UseSampleProfile .empty ()) {
220
270
Out = PGOOptions (
221
271
/* ProfileFile=*/ Opts.UseSampleProfile ,
@@ -234,31 +284,34 @@ static void populatePGOOptions(std::optional<PGOOptions> &Out,
234
284
if (Opts.EnableCSIRProfileGen ) {
235
285
const bool hasUse = !Opts.UseIRProfile .empty ();
236
286
Out = PGOOptions (
237
- /* ProfileFile=*/ Opts.UseIRProfile ,
238
- /* CSProfileGenFile=*/ Opts.InstrProfileOutput ,
239
- /* ProfileRemappingFile=*/ " " ,
240
- /* MemoryProfile=*/ " " ,
241
- /* FS=*/ llvm::vfs::getRealFileSystem (),
242
- /* Action=*/ hasUse ? PGOOptions::IRUse : PGOOptions::NoAction,
243
- /* CSPGOAction=*/ PGOOptions::CSIRInstr,
244
- /* ColdType=*/ PGOOptions::ColdFuncOpt::Default,
245
- /* DebugInfoForProfiling=*/ Opts.DebugInfoForProfiling
246
- );
287
+ /* ProfileFile=*/ Opts.UseIRProfile ,
288
+ /* CSProfileGenFile=*/ Opts.InstrProfileOutput ,
289
+ /* ProfileRemappingFile=*/ " " ,
290
+ /* MemoryProfile=*/ " " ,
291
+ /* FS=*/ llvm::vfs::getRealFileSystem (),
292
+ /* Action=*/ hasUse ? PGOOptions::IRUse : PGOOptions::NoAction,
293
+ /* CSPGOAction=*/ PGOOptions::CSIRInstr,
294
+ /* ColdType=*/ PGOOptions::ColdFuncOpt::Default,
295
+ /* DebugInfoForProfiling=*/ Opts.DebugInfoForProfiling );
247
296
return ;
248
297
}
249
298
250
299
if (Opts.EnableIRProfileGen ) {
251
300
Out = PGOOptions (
252
- /* ProfileFile=*/ Opts.InstrProfileOutput ,
253
- /* CSProfileGenFile=*/ " " ,
254
- /* ProfileRemappingFile=*/ " " ,
255
- /* MemoryProfile=*/ " " ,
256
- /* FS=*/ llvm::vfs::getRealFileSystem (),
257
- /* Action=*/ PGOOptions::IRInstr,
258
- /* CSPGOAction=*/ PGOOptions::NoCSAction,
259
- /* ColdType=*/ PGOOptions::ColdFuncOpt::Default,
260
- /* DebugInfoForProfiling=*/ Opts.DebugInfoForProfiling
261
- );
301
+ /* ProfileFile=*/ Opts.InstrProfileOutput ,
302
+ /* CSProfileGenFile=*/ " " ,
303
+ /* ProfileRemappingFile=*/ " " ,
304
+ /* MemoryProfile=*/ " " ,
305
+ /* FS=*/ llvm::vfs::getRealFileSystem (),
306
+ /* Action=*/ PGOOptions::IRInstr,
307
+ /* CSPGOAction=*/ PGOOptions::NoCSAction,
308
+ /* ColdType=*/ PGOOptions::ColdFuncOpt::Default,
309
+ /* DebugInfoForProfiling=*/ Opts.DebugInfoForProfiling );
310
+ return ;
311
+ }
312
+
313
+ if (auto IRUseOptions = buildIRUseOptions (Opts, Diags)) {
314
+ Out = *IRUseOptions;
262
315
return ;
263
316
}
264
317
@@ -297,7 +350,7 @@ void swift::performLLVMOptimizations(const IRGenOptions &Opts,
297
350
llvm::TargetMachine *TargetMachine,
298
351
llvm::raw_pwrite_stream *out) {
299
352
std::optional<PGOOptions> PGOOpt;
300
- populatePGOOptions (PGOOpt, Opts);
353
+ populatePGOOptions (PGOOpt, Opts, Diags );
301
354
302
355
PipelineTuningOptions PTO;
303
356
0 commit comments