14
14
//
15
15
// ===----------------------------------------------------------------------===//
16
16
17
- #define DEBUG_TYPE " irgen "
17
+ #include " ../Serialization/ModuleFormat.h "
18
18
#include " IRGenModule.h"
19
19
#include " swift/ABI/MetadataValues.h"
20
20
#include " swift/AST/DiagnosticsIRGen.h"
44
44
#include " swift/SILOptimizer/PassManager/Passes.h"
45
45
#include " swift/Subsystems.h"
46
46
#include " swift/TBDGen/TBDGen.h"
47
- #include " ../Serialization/ModuleFormat.h"
48
47
#include " clang/Basic/TargetInfo.h"
49
48
#include " clang/Frontend/CompilerInstance.h"
50
49
#include " llvm/ADT/StringSet.h"
59
58
#include " llvm/IR/LLVMContext.h"
60
59
#include " llvm/IR/LegacyPassManager.h"
61
60
#include " llvm/IR/Module.h"
61
+ #include " llvm/IR/PassManager.h"
62
62
#include " llvm/IR/ValueSymbolTable.h"
63
63
#include " llvm/IR/Verifier.h"
64
64
#include " llvm/Linker/Linker.h"
65
65
#include " llvm/MC/SubtargetFeature.h"
66
66
#include " llvm/MC/TargetRegistry.h"
67
67
#include " llvm/Object/ObjectFile.h"
68
+ #include " llvm/Passes/PassBuilder.h"
69
+ #include " llvm/Passes/StandardInstrumentations.h"
68
70
#include " llvm/Support/CommandLine.h"
69
71
#include " llvm/Support/Debug.h"
70
72
#include " llvm/Support/ErrorHandling.h"
79
81
#include " llvm/Transforms/IPO/PassManagerBuilder.h"
80
82
#include " llvm/Transforms/Instrumentation.h"
81
83
#include " llvm/Transforms/Instrumentation/AddressSanitizer.h"
84
+ #include " llvm/Transforms/Instrumentation/InstrProfiling.h"
82
85
#include " llvm/Transforms/Instrumentation/SanitizerCoverage.h"
83
86
#include " llvm/Transforms/Instrumentation/ThreadSanitizer.h"
84
87
#include " llvm/Transforms/ObjCARC.h"
@@ -93,6 +96,8 @@ using namespace swift;
93
96
using namespace irgen ;
94
97
using namespace llvm ;
95
98
99
+ #define DEBUG_TYPE " irgen"
100
+
96
101
static cl::opt<bool > DisableObjCARCContract (
97
102
" disable-objc-arc-contract" , cl::Hidden,
98
103
cl::desc (" Disable running objc arc contract for testing purposes" ));
@@ -216,6 +221,22 @@ void setModuleFlags(IRGenModule &IGM) {
216
221
}
217
222
}
218
223
224
+ static void align (llvm::Module *Module) {
225
+ // For performance benchmarking: Align the module to the page size by
226
+ // aligning the first function of the module.
227
+ unsigned pageSize =
228
+ #if HAVE_UNISTD_H
229
+ sysconf (_SC_PAGESIZE));
230
+ #else
231
+ 4096 ; // Use a default value
232
+ #endif
233
+ for (auto I = Module->begin (), E = Module->end (); I != E; ++I) {
234
+ if (!I->isDeclaration ()) {
235
+ I->setAlignment (llvm::MaybeAlign (pageSize));
236
+ break ;
237
+ }
238
+ }
239
+ }
219
240
static void
220
241
performOptimizationsUsingLegacyPassManger (const IRGenOptions &Opts,
221
242
llvm::Module *Module,
@@ -373,27 +394,197 @@ performOptimizationsUsingLegacyPassManger(const IRGenOptions &Opts,
373
394
ModulePasses.run (*Module);
374
395
375
396
if (AlignModuleToPageSize) {
376
- // For performance benchmarking: Align the module to the page size by
377
- // aligning the first function of the module.
378
- unsigned pageSize =
379
- #if HAVE_UNISTD_H
380
- sysconf (_SC_PAGESIZE));
381
- #else
382
- 4096 ; // Use a default value
383
- #endif
384
- for (auto I = Module->begin (), E = Module->end (); I != E; ++I) {
385
- if (!I->isDeclaration ()) {
386
- I->setAlignment (llvm::MaybeAlign (pageSize));
387
- break ;
388
- }
389
- }
397
+ align (Module);
390
398
}
391
399
}
392
400
393
401
static void
394
402
performOptimizationsUsingNewPassManger (const IRGenOptions &Opts,
395
403
llvm::Module *Module,
396
- llvm::TargetMachine *TargetMachine) {}
404
+ llvm::TargetMachine *TargetMachine) {
405
+ Optional<PGOOptions> PGOOpt;
406
+
407
+ PipelineTuningOptions PTO;
408
+
409
+ bool RunSwiftMergeFunctions = true ;
410
+ // LLVM MergeFunctions and SwiftMergeFunctions don't understand that the
411
+ // string in the metadata on calls in @llvm.type.checked.load intrinsics is
412
+ // semantically meaningful, and mis-compile (mis-merge) unrelated functions.
413
+ if (Opts.VirtualFunctionElimination || Opts.WitnessMethodElimination ) {
414
+ RunSwiftMergeFunctions = false ;
415
+ }
416
+
417
+ bool RunSwiftSpecificLLVMOptzns =
418
+ !Opts.DisableSwiftSpecificLLVMOptzns && !Opts.DisableLLVMOptzns ;
419
+
420
+ PTO.CallGraphProfile = false ;
421
+
422
+ llvm::OptimizationLevel level = llvm::OptimizationLevel::O0;
423
+ if (Opts.shouldOptimize () && !Opts.DisableLLVMOptzns ) {
424
+ // For historical reasons, loop interleaving is set to mirror setting for
425
+ // loop unrolling.
426
+ PTO.LoopInterleaving = true ;
427
+ PTO.LoopVectorization = true ;
428
+ PTO.SLPVectorization = true ;
429
+ PTO.MergeFunctions = RunSwiftMergeFunctions;
430
+ level = llvm::OptimizationLevel::Os;
431
+ } else {
432
+ level = llvm::OptimizationLevel::O0;
433
+ }
434
+
435
+ LoopAnalysisManager LAM;
436
+ FunctionAnalysisManager FAM;
437
+ CGSCCAnalysisManager CGAM;
438
+ ModuleAnalysisManager MAM;
439
+
440
+ bool DebugPassStructure = false ;
441
+ PassInstrumentationCallbacks PIC;
442
+ PrintPassOptions PrintPassOpts;
443
+ PrintPassOpts.Indent = DebugPassStructure;
444
+ PrintPassOpts.SkipAnalyses = DebugPassStructure;
445
+ StandardInstrumentations SI (DebugPassStructure, /* VerifyEach*/ false ,
446
+ PrintPassOpts);
447
+ SI.registerCallbacks (PIC, &FAM);
448
+
449
+ PassBuilder PB (TargetMachine, PTO, PGOOpt, &PIC);
450
+
451
+ // Register the AA manager first so that our version is the one used.
452
+ FAM.registerPass ([&] {
453
+ auto AA = PB.buildDefaultAAPipeline ();
454
+ if (RunSwiftSpecificLLVMOptzns)
455
+ AA.registerFunctionAnalysis <SwiftAA>();
456
+ return AA;
457
+ });
458
+ FAM.registerPass ([&] { return SwiftAA (); });
459
+
460
+ // Register all the basic analyses with the managers.
461
+ PB.registerModuleAnalyses (MAM);
462
+ PB.registerCGSCCAnalyses (CGAM);
463
+ PB.registerFunctionAnalyses (FAM);
464
+ PB.registerLoopAnalyses (LAM);
465
+ PB.crossRegisterProxies (LAM, FAM, CGAM, MAM);
466
+ ModulePassManager MPM;
467
+
468
+ if (RunSwiftSpecificLLVMOptzns) {
469
+ PB.registerScalarOptimizerLateEPCallback (
470
+ [](FunctionPassManager &FPM, OptimizationLevel Level) {
471
+ if (Level != OptimizationLevel::O0)
472
+ FPM.addPass (SwiftARCOptPass ());
473
+ });
474
+ PB.registerOptimizerLastEPCallback ([](ModulePassManager &MPM,
475
+ OptimizationLevel Level) {
476
+ if (Level != OptimizationLevel::O0)
477
+ MPM.addPass (createModuleToFunctionPassAdaptor (SwiftARCContractPass ()));
478
+ });
479
+ }
480
+
481
+ // PassBuilder adds coroutine passes per default.
482
+ //
483
+
484
+ if (Opts.Sanitizers & SanitizerKind::Address) {
485
+ PB.registerOptimizerLastEPCallback ([&](ModulePassManager &MPM,
486
+ OptimizationLevel Level) {
487
+ auto Recover = bool (Opts.SanitizersWithRecoveryInstrumentation &
488
+ SanitizerKind::Address);
489
+ bool UseAfterScope = false ;
490
+ bool ModuleUseAfterScope = true ;
491
+ bool UseOdrIndicator = Opts.SanitizeAddressUseODRIndicator ;
492
+ llvm::AsanDtorKind DestructorKind = llvm::AsanDtorKind::Global;
493
+ llvm::AsanDetectStackUseAfterReturnMode UseAfterReturn =
494
+ llvm::AsanDetectStackUseAfterReturnMode::Runtime;
495
+ MPM.addPass (
496
+ RequireAnalysisPass<ASanGlobalsMetadataAnalysis, llvm::Module>());
497
+ MPM.addPass (ModuleAddressSanitizerPass (false , Recover,
498
+ ModuleUseAfterScope,
499
+ UseOdrIndicator, DestructorKind));
500
+ MPM.addPass (createModuleToFunctionPassAdaptor (AddressSanitizerPass (
501
+ {false , Recover, UseAfterScope, UseAfterReturn})));
502
+ });
503
+ }
504
+
505
+ if (Opts.Sanitizers & SanitizerKind::Thread) {
506
+ PB.registerOptimizerLastEPCallback (
507
+ [&](ModulePassManager &MPM, OptimizationLevel Level) {
508
+ MPM.addPass (ModuleThreadSanitizerPass ());
509
+ MPM.addPass (createModuleToFunctionPassAdaptor (ThreadSanitizerPass ()));
510
+ });
511
+ }
512
+
513
+ if (Opts.SanitizeCoverage .CoverageType !=
514
+ llvm::SanitizerCoverageOptions::SCK_None) {
515
+ PB.registerOptimizerLastEPCallback ([&](ModulePassManager &MPM,
516
+ OptimizationLevel Level) {
517
+ std::vector<std::string> allowlistFiles;
518
+ std::vector<std::string> ignorelistFiles;
519
+ MPM.addPass (ModuleSanitizerCoveragePass (Opts.SanitizeCoverage ,
520
+ allowlistFiles, ignorelistFiles));
521
+ });
522
+ }
523
+ if (RunSwiftSpecificLLVMOptzns && RunSwiftMergeFunctions) {
524
+ PB.registerOptimizerLastEPCallback (
525
+ [&](ModulePassManager &MPM, OptimizationLevel Level) {
526
+ if (Level != OptimizationLevel::O0) {
527
+ const PointerAuthSchema &schema = Opts.PointerAuth .FunctionPointers ;
528
+ unsigned key = (schema.isEnabled () ? schema.getKey () : 0 );
529
+ MPM.addPass (SwiftMergeFunctionsPass (schema.isEnabled (), key));
530
+ }
531
+ });
532
+ }
533
+ if (RunSwiftSpecificLLVMOptzns) {
534
+ PB.registerOptimizerLastEPCallback ([&](ModulePassManager &MPM,
535
+ OptimizationLevel Level) {
536
+ MPM.addPass (
537
+ createModuleToFunctionPassAdaptor (SwiftDbgAddrBlockSplitterPass ()));
538
+ });
539
+ }
540
+
541
+ if (Opts.GenerateProfile ) {
542
+ InstrProfOptions options;
543
+ options.Atomic = bool (Opts.Sanitizers & SanitizerKind::Thread);
544
+ PB.registerPipelineStartEPCallback (
545
+ [options](ModulePassManager &MPM, OptimizationLevel level) {
546
+ MPM.addPass (InstrProfiling (options, false ));
547
+ });
548
+ }
549
+
550
+ if (!Opts.shouldOptimize () || Opts.DisableLLVMOptzns ) {
551
+ MPM = PB.buildO0DefaultPipeline (level, false );
552
+ } else {
553
+ MPM = PB.buildPerModuleDefaultPipeline (level);
554
+ }
555
+
556
+ // Make sure we do ARC contraction under optimization. We don't
557
+ // rely on any other LLVM ARC transformations, but we do need ARC
558
+ // contraction to add the objc_retainAutoreleasedReturnValue
559
+ // assembly markers and remove clang.arc.used.
560
+ if (Opts.shouldOptimize () && !DisableObjCARCContract &&
561
+ !Opts.DisableLLVMOptzns )
562
+ MPM.addPass (createModuleToFunctionPassAdaptor (ObjCARCContractPass ()));
563
+
564
+ if (Opts.Verify ) {
565
+ // Run verification before we run the pipeline.
566
+ ModulePassManager VerifyPM;
567
+ VerifyPM.addPass (VerifierPass ());
568
+ VerifyPM.run (*Module, MAM);
569
+ // PB.registerPipelineStartEPCallback(
570
+ // [](ModulePassManager &MPM, OptimizationLevel Level) {
571
+ // MPM.addPass(VerifierPass());
572
+ // });
573
+
574
+ // Run verification after we ran the pipeline;
575
+ MPM.addPass (VerifierPass ());
576
+ }
577
+
578
+ if (Opts.PrintInlineTree )
579
+ MPM.addPass (InlineTreePrinterPass ());
580
+
581
+ if (!Opts.DisableLLVMOptzns )
582
+ MPM.run (*Module, MAM);
583
+
584
+ if (AlignModuleToPageSize) {
585
+ align (Module);
586
+ }
587
+ }
397
588
398
589
void swift::performLLVMOptimizations (const IRGenOptions &Opts,
399
590
llvm::Module *Module,
0 commit comments