|
37 | 37 | #include "llvm/Transforms/Utils/NameAnonGlobals.h"
|
38 | 38 |
|
39 | 39 | using namespace llvm;
|
40 |
| -using namespace llvm::legacy; |
41 | 40 |
|
42 | 41 | typedef struct LLVMOpaquePass *LLVMPassRef;
|
43 | 42 | typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
|
@@ -612,7 +611,9 @@ LLVMRustOptimizeWithNewPassManager(
|
612 | 611 | bool NoPrepopulatePasses, bool VerifyIR,
|
613 | 612 | bool PrepareForThinLTO, bool PrepareForLTO, bool UseThinLTOBuffers,
|
614 | 613 | bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
|
615 |
| - bool DisableSimplifyLibCalls) { |
| 614 | + bool DisableSimplifyLibCalls, |
| 615 | + bool SanitizeMemory, bool SanitizeThread, bool SanitizeAddress, |
| 616 | + bool SanitizeRecover, int SanitizeMemoryTrackOrigins) { |
616 | 617 | Module *TheModule = unwrap(ModuleRef);
|
617 | 618 | TargetMachine *TM = unwrap(TMRef);
|
618 | 619 | PassBuilder::OptimizationLevel OptLevel = fromRust(OptLevelRust);
|
@@ -654,17 +655,85 @@ LLVMRustOptimizeWithNewPassManager(
|
654 | 655 | PB.registerFunctionAnalyses(FAM);
|
655 | 656 | PB.registerLoopAnalyses(LAM);
|
656 | 657 | PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
|
657 |
| - PB.registerPipelineStartEPCallback([VerifyIR](ModulePassManager &MPM) { |
658 |
| - if (VerifyIR) |
659 |
| - MPM.addPass(VerifierPass()); |
660 |
| - }); |
| 658 | + |
| 659 | + // We manually collect pipeline callbacks so we can apply them at O0, where the |
| 660 | + // PassBuilder does not create a pipeline. |
| 661 | + std::vector<std::function<void(ModulePassManager &)>> PipelineStartEPCallbacks; |
| 662 | + std::vector<std::function<void(FunctionPassManager &, PassBuilder::OptimizationLevel)>> |
| 663 | + OptimizerLastEPCallbacks; |
| 664 | + |
| 665 | + if (VerifyIR) { |
| 666 | + PipelineStartEPCallbacks.push_back([VerifyIR](ModulePassManager &MPM) { |
| 667 | + MPM.addPass(VerifierPass()); |
| 668 | + }); |
| 669 | + } |
| 670 | + |
| 671 | + if (SanitizeMemory) { |
| 672 | + MemorySanitizerOptions Options( |
| 673 | + SanitizeMemoryTrackOrigins, |
| 674 | + SanitizeRecover, |
| 675 | + /*CompileKernel=*/false); |
| 676 | +#if LLVM_VERSION_GE(10, 0) |
| 677 | + PipelineStartEPCallbacks.push_back([Options](ModulePassManager &MPM) { |
| 678 | + MPM.addPass(MemorySanitizerPass(Options)); |
| 679 | + }); |
| 680 | +#endif |
| 681 | + OptimizerLastEPCallbacks.push_back( |
| 682 | + [Options](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { |
| 683 | + FPM.addPass(MemorySanitizerPass(Options)); |
| 684 | + } |
| 685 | + ); |
| 686 | + } |
| 687 | + |
| 688 | + if (SanitizeThread) { |
| 689 | +#if LLVM_VERSION_GE(10, 0) |
| 690 | + PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM) { |
| 691 | + MPM.addPass(ThreadSanitizerPass()); |
| 692 | + }); |
| 693 | +#endif |
| 694 | + OptimizerLastEPCallbacks.push_back( |
| 695 | + [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { |
| 696 | + FPM.addPass(ThreadSanitizerPass()); |
| 697 | + } |
| 698 | + ); |
| 699 | + } |
| 700 | + |
| 701 | + if (SanitizeAddress) { |
| 702 | + // FIXME: Rust does not expose the UseAfterScope option. |
| 703 | + PipelineStartEPCallbacks.push_back([&](ModulePassManager &MPM) { |
| 704 | + MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); |
| 705 | + }); |
| 706 | + OptimizerLastEPCallbacks.push_back( |
| 707 | + [SanitizeRecover](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { |
| 708 | + FPM.addPass(AddressSanitizerPass(/*CompileKernel=*/false, SanitizeRecover)); |
| 709 | + } |
| 710 | + ); |
| 711 | + PipelineStartEPCallbacks.push_back( |
| 712 | + [SanitizeRecover](ModulePassManager &MPM) { |
| 713 | + MPM.addPass(ModuleAddressSanitizerPass(/*CompileKernel=*/false, SanitizeRecover)); |
| 714 | + } |
| 715 | + ); |
| 716 | + } |
661 | 717 |
|
662 | 718 | ModulePassManager MPM(DebugPassManager);
|
663 | 719 | if (!NoPrepopulatePasses) {
|
664 | 720 | if (OptLevel == PassBuilder::O0) {
|
| 721 | + for (const auto &C : PipelineStartEPCallbacks) |
| 722 | + C(MPM); |
| 723 | + |
| 724 | + FunctionPassManager FPM(DebugPassManager); |
| 725 | + for (const auto &C : OptimizerLastEPCallbacks) |
| 726 | + C(FPM, OptLevel); |
| 727 | + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); |
| 728 | + |
665 | 729 | MPM.addPass(AlwaysInlinerPass(/*InsertLifetimeIntrinsics=*/false));
|
666 | 730 | // FIXME: PGO?
|
667 | 731 | } else {
|
| 732 | + for (const auto &C : PipelineStartEPCallbacks) |
| 733 | + PB.registerPipelineStartEPCallback(C); |
| 734 | + for (const auto &C : OptimizerLastEPCallbacks) |
| 735 | + PB.registerOptimizerLastEPCallback(C); |
| 736 | + |
668 | 737 | // FIXME: Sanitizers? PGO?
|
669 | 738 | if (PrepareForThinLTO) {
|
670 | 739 | MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
|
|
0 commit comments