Skip to content

Commit 3dac6c9

Browse files
committed
IRGen: Introduce the option to use the new llvm pass manager
1 parent 5c9eab0 commit 3dac6c9

File tree

1 file changed

+208
-17
lines changed

1 file changed

+208
-17
lines changed

lib/IRGen/IRGen.cpp

Lines changed: 208 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
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"
@@ -44,7 +44,6 @@
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"
@@ -59,12 +58,15 @@
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"
@@ -79,6 +81,7 @@
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;
9396
using namespace irgen;
9497
using namespace llvm;
9598

99+
#define DEBUG_TYPE "irgen"
100+
96101
static 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+
}
219240
static void
220241
performOptimizationsUsingLegacyPassManger(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

393401
static void
394402
performOptimizationsUsingNewPassManger(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

398589
void swift::performLLVMOptimizations(const IRGenOptions &Opts,
399590
llvm::Module *Module,

0 commit comments

Comments
 (0)