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,23 @@ 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
+
217
232
static void populatePGOOptions (std::optional<PGOOptions> &Out,
218
- const IRGenOptions &Opts) {
233
+ const IRGenOptions &Opts,
234
+ DiagnosticEngine &Diags) {
219
235
if (!Opts.UseSampleProfile .empty ()) {
220
236
Out = PGOOptions (
221
237
/* ProfileFile=*/ Opts.UseSampleProfile ,
@@ -234,31 +250,60 @@ static void populatePGOOptions(std::optional<PGOOptions> &Out,
234
250
if (Opts.EnableCSIRProfileGen ) {
235
251
const bool hasUse = !Opts.UseIRProfile .empty ();
236
252
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
- );
253
+ /* ProfileFile=*/ Opts.UseIRProfile ,
254
+ /* CSProfileGenFile=*/ Opts.InstrProfileOutput ,
255
+ /* ProfileRemappingFile=*/ " " ,
256
+ /* MemoryProfile=*/ " " ,
257
+ /* FS=*/ llvm::vfs::getRealFileSystem (),
258
+ /* Action=*/ hasUse ? PGOOptions::IRUse : PGOOptions::NoAction,
259
+ /* CSPGOAction=*/ PGOOptions::CSIRInstr,
260
+ /* ColdType=*/ PGOOptions::ColdFuncOpt::Default,
261
+ /* DebugInfoForProfiling=*/ Opts.DebugInfoForProfiling );
247
262
return ;
248
263
}
249
264
250
265
if (Opts.EnableIRProfileGen ) {
251
266
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
- );
267
+ /* ProfileFile=*/ Opts.InstrProfileOutput ,
268
+ /* CSProfileGenFile=*/ " " ,
269
+ /* ProfileRemappingFile=*/ " " ,
270
+ /* MemoryProfile=*/ " " ,
271
+ /* FS=*/ llvm::vfs::getRealFileSystem (),
272
+ /* Action=*/ PGOOptions::IRInstr,
273
+ /* CSPGOAction=*/ PGOOptions::NoCSAction,
274
+ /* ColdType=*/ PGOOptions::ColdFuncOpt::Default,
275
+ /* DebugInfoForProfiling=*/ Opts.DebugInfoForProfiling );
276
+ return ;
277
+ }
278
+
279
+ if (!Opts.UseIRProfile .empty ()) {
280
+ auto FS = llvm::vfs::getRealFileSystem ();
281
+ std::unique_ptr<llvm::IndexedInstrProfReader> Reader =
282
+ getProfileReader (Opts.UseIRProfile .c_str (), *FS, Diags);
283
+ if (!Reader)
284
+ return ;
285
+
286
+ // Currently memprof profiles are only added at the IR level. Mark the
287
+ // profile type as IR in that case as well and the subsequent matching
288
+ // needs to detect which is available (might be one or both).
289
+ const bool IsIR = Reader->isIRLevelProfile () || Reader->hasMemoryProfile ();
290
+ const bool IsCS = Reader->hasCSIRLevelProfile ();
291
+ if (!IsIR) {
292
+ Diags.diagnose (SourceLoc (), diag::ir_profile_invalid,
293
+ Opts.UseIRProfile .c_str ());
294
+ return ;
295
+ }
296
+
297
+ Out = PGOOptions (
298
+ /* ProfileFile=*/ Opts.UseIRProfile ,
299
+ /* CSProfileGenFile=*/ " " ,
300
+ /* ProfileRemappingFile=*/ " " ,
301
+ /* MemoryProfile=*/ " " ,
302
+ /* FS=*/ FS,
303
+ /* Action=*/ PGOOptions::IRUse,
304
+ /* CSPGOAction=*/ IsCS ? PGOOptions::CSIRUse : PGOOptions::NoCSAction,
305
+ /* ColdType=*/ PGOOptions::ColdFuncOpt::Default,
306
+ /* DebugInfoForProfiling=*/ Opts.DebugInfoForProfiling );
262
307
return ;
263
308
}
264
309
@@ -297,7 +342,7 @@ void swift::performLLVMOptimizations(const IRGenOptions &Opts,
297
342
llvm::TargetMachine *TargetMachine,
298
343
llvm::raw_pwrite_stream *out) {
299
344
std::optional<PGOOptions> PGOOpt;
300
- populatePGOOptions (PGOOpt, Opts);
345
+ populatePGOOptions (PGOOpt, Opts, Diags );
301
346
302
347
PipelineTuningOptions PTO;
303
348
0 commit comments