1414//
1515// ===----------------------------------------------------------------------===//
1616
17- #define DEBUG_TYPE " irgen "
17+ #include " ../Serialization/ModuleFormat.h "
1818#include " IRGenModule.h"
1919#include " swift/ABI/MetadataValues.h"
2020#include " swift/AST/DiagnosticsIRGen.h"
4444#include " swift/SILOptimizer/PassManager/Passes.h"
4545#include " swift/Subsystems.h"
4646#include " swift/TBDGen/TBDGen.h"
47- #include " ../Serialization/ModuleFormat.h"
4847#include " clang/Basic/TargetInfo.h"
4948#include " clang/Frontend/CompilerInstance.h"
5049#include " llvm/ADT/StringSet.h"
5958#include " llvm/IR/LLVMContext.h"
6059#include " llvm/IR/LegacyPassManager.h"
6160#include " llvm/IR/Module.h"
61+ #include " llvm/IR/PassManager.h"
6262#include " llvm/IR/ValueSymbolTable.h"
6363#include " llvm/IR/Verifier.h"
6464#include " llvm/Linker/Linker.h"
6565#include " llvm/MC/SubtargetFeature.h"
6666#include " llvm/MC/TargetRegistry.h"
6767#include " llvm/Object/ObjectFile.h"
68+ #include " llvm/Passes/PassBuilder.h"
69+ #include " llvm/Passes/StandardInstrumentations.h"
6870#include " llvm/Support/CommandLine.h"
6971#include " llvm/Support/Debug.h"
7072#include " llvm/Support/ErrorHandling.h"
7981#include " llvm/Transforms/IPO/PassManagerBuilder.h"
8082#include " llvm/Transforms/Instrumentation.h"
8183#include " llvm/Transforms/Instrumentation/AddressSanitizer.h"
84+ #include " llvm/Transforms/Instrumentation/InstrProfiling.h"
8285#include " llvm/Transforms/Instrumentation/SanitizerCoverage.h"
8386#include " llvm/Transforms/Instrumentation/ThreadSanitizer.h"
8487#include " llvm/Transforms/ObjCARC.h"
@@ -93,6 +96,8 @@ using namespace swift;
9396using namespace irgen ;
9497using namespace llvm ;
9598
99+ #define DEBUG_TYPE " irgen"
100+
96101static cl::opt<bool > DisableObjCARCContract (
97102 " disable-objc-arc-contract" , cl::Hidden,
98103 cl::desc (" Disable running objc arc contract for testing purposes" ));
@@ -216,6 +221,22 @@ void setModuleFlags(IRGenModule &IGM) {
216221 }
217222}
218223
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+ }
219240static void
220241performOptimizationsUsingLegacyPassManger (const IRGenOptions &Opts,
221242 llvm::Module *Module,
@@ -373,27 +394,197 @@ performOptimizationsUsingLegacyPassManger(const IRGenOptions &Opts,
373394 ModulePasses.run (*Module);
374395
375396 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);
390398 }
391399}
392400
393401static void
394402performOptimizationsUsingNewPassManger (const IRGenOptions &Opts,
395403 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+ }
397588
398589void swift::performLLVMOptimizations (const IRGenOptions &Opts,
399590 llvm::Module *Module,
0 commit comments