@@ -616,6 +616,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
616616 bool DebugInfoForProfiling, void *LlvmSelfProfiler,
617617 LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
618618 LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
619+ const char *PostEnzymePasses, size_t PostEnzymePassesLen,
619620 const char *ExtraPasses, size_t ExtraPassesLen, const char *LLVMPlugins,
620621 size_t LLVMPluginsLen) {
621622 Module *TheModule = unwrap (ModuleRef);
@@ -852,120 +853,130 @@ extern "C" LLVMRustResult LLVMRustOptimize(
852853 raw_string_ostream ThinLinkDataOS (ThinLTOSummaryBuffer->data );
853854 bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO ||
854855 OptStage == LLVMRustOptStage::FatLTO;
855- if (!NoPrepopulatePasses) {
856- for (const auto &C : PipelineStartEPCallbacks)
857- PB .registerPipelineStartEPCallback (C);
858- for (const auto &C : OptimizerLastEPCallbacks)
859- PB .registerOptimizerLastEPCallback (C);
860-
861- // The pre-link pipelines don't support O0 and require using
862- // buildO0DefaultPipeline() instead. At the same time, the LTO pipelines do
863- // support O0 and using them is required.
864- if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
865- // We manually schedule ThinLTOBufferPasses below, so don't pass the value
866- // to enable it here.
867- MPM = PB .buildO0DefaultPipeline (OptLevel);
868- } else {
869- switch (OptStage) {
870- case LLVMRustOptStage::PreLinkNoLTO:
871- if (ThinLTOBufferRef) {
872- // This is similar to LLVM's `buildFatLTODefaultPipeline`, where the
873- // bitcode for embedding is obtained after performing
874- // `ThinLTOPreLinkDefaultPipeline`.
875- MPM .addPass (PB .buildThinLTOPreLinkDefaultPipeline (OptLevel));
876- MPM .addPass (ThinLTOBitcodeWriterPass (
877- ThinLTODataOS,
878- ThinLTOSummaryBufferRef ? &ThinLinkDataOS : nullptr ));
879- *ThinLTOBufferRef = ThinLTOBuffer.release ();
880- if (ThinLTOSummaryBufferRef) {
881- *ThinLTOSummaryBufferRef = ThinLTOSummaryBuffer.release ();
856+ if (PostEnzymePassesLen) {
857+ if (auto Err = PB .parsePassPipeline (
858+ MPM , StringRef (PostEnzymePasses, PostEnzymePassesLen))) {
859+ std::string ErrMsg = toString (std::move (Err));
860+ LLVMRustSetLastError (ErrMsg.c_str ());
861+ return LLVMRustResult::Failure;
862+ }
863+ } else {
864+ if (!NoPrepopulatePasses) {
865+ for (const auto &C : PipelineStartEPCallbacks)
866+ PB .registerPipelineStartEPCallback (C);
867+ for (const auto &C : OptimizerLastEPCallbacks)
868+ PB .registerOptimizerLastEPCallback (C);
869+
870+ // The pre-link pipelines don't support O0 and require using
871+ // buildO0DefaultPipeline() instead. At the same time, the LTO pipelines
872+ // do support O0 and using them is required.
873+ if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
874+ // We manually schedule ThinLTOBufferPasses below, so don't pass the
875+ // value to enable it here.
876+ MPM = PB .buildO0DefaultPipeline (OptLevel);
877+ } else {
878+ switch (OptStage) {
879+ case LLVMRustOptStage::PreLinkNoLTO:
880+ if (ThinLTOBufferRef) {
881+ // This is similar to LLVM's `buildFatLTODefaultPipeline`, where the
882+ // bitcode for embedding is obtained after performing
883+ // `ThinLTOPreLinkDefaultPipeline`.
884+ MPM .addPass (PB .buildThinLTOPreLinkDefaultPipeline (OptLevel));
885+ MPM .addPass (ThinLTOBitcodeWriterPass (
886+ ThinLTODataOS,
887+ ThinLTOSummaryBufferRef ? &ThinLinkDataOS : nullptr ));
888+ *ThinLTOBufferRef = ThinLTOBuffer.release ();
889+ if (ThinLTOSummaryBufferRef) {
890+ *ThinLTOSummaryBufferRef = ThinLTOSummaryBuffer.release ();
891+ }
892+ MPM .addPass (PB .buildModuleOptimizationPipeline (
893+ OptLevel, ThinOrFullLTOPhase::None));
894+ MPM .addPass (
895+ createModuleToFunctionPassAdaptor (AnnotationRemarksPass ()));
896+ } else {
897+ MPM = PB .buildPerModuleDefaultPipeline (OptLevel);
882898 }
883- MPM .addPass (PB .buildModuleOptimizationPipeline (
884- OptLevel, ThinOrFullLTOPhase::None));
885- MPM .addPass (
886- createModuleToFunctionPassAdaptor (AnnotationRemarksPass ()));
887- } else {
888- MPM = PB .buildPerModuleDefaultPipeline (OptLevel);
899+ break ;
900+ case LLVMRustOptStage::PreLinkThinLTO:
901+ case LLVMRustOptStage::PreLinkFatLTO:
902+ MPM = PB .buildThinLTOPreLinkDefaultPipeline (OptLevel);
903+ NeedThinLTOBufferPasses = false ;
904+ break ;
905+ case LLVMRustOptStage::ThinLTO:
906+ // FIXME: Does it make sense to pass the ModuleSummaryIndex?
907+ // It only seems to be needed for C++ specific optimizations.
908+ MPM = PB .buildThinLTODefaultPipeline (OptLevel, nullptr );
909+ break ;
910+ case LLVMRustOptStage::FatLTO:
911+ MPM = PB .buildLTODefaultPipeline (OptLevel, nullptr );
912+ NeedThinLTOBufferPasses = false ;
913+ break ;
889914 }
890- break ;
891- case LLVMRustOptStage::PreLinkThinLTO:
892- case LLVMRustOptStage::PreLinkFatLTO:
893- MPM = PB .buildThinLTOPreLinkDefaultPipeline (OptLevel);
894- NeedThinLTOBufferPasses = false ;
895- break ;
896- case LLVMRustOptStage::ThinLTO:
897- // FIXME: Does it make sense to pass the ModuleSummaryIndex?
898- // It only seems to be needed for C++ specific optimizations.
899- MPM = PB .buildThinLTODefaultPipeline (OptLevel, nullptr );
900- break ;
901- case LLVMRustOptStage::FatLTO:
902- MPM = PB .buildLTODefaultPipeline (OptLevel, nullptr );
903- NeedThinLTOBufferPasses = false ;
904- break ;
905915 }
916+ } else {
917+ // We're not building any of the default pipelines but we still want to
918+ // add the verifier, instrumentation, etc passes if they were requested
919+ for (const auto &C : PipelineStartEPCallbacks)
920+ C (MPM , OptLevel);
921+ for (const auto &C : OptimizerLastEPCallbacks)
922+ C (MPM , OptLevel, ThinOrFullLTOPhase::None);
906923 }
907- } else {
908- // We're not building any of the default pipelines but we still want to
909- // add the verifier, instrumentation, etc passes if they were requested
910- for (const auto &C : PipelineStartEPCallbacks)
911- C (MPM , OptLevel);
912- for (const auto &C : OptimizerLastEPCallbacks)
913- C (MPM , OptLevel, ThinOrFullLTOPhase::None);
914- }
915924
916- if (ExtraPassesLen) {
917- if (auto Err =
918- PB .parsePassPipeline (MPM , StringRef (ExtraPasses, ExtraPassesLen))) {
919- std::string ErrMsg = toString (std::move (Err));
920- LLVMRustSetLastError (ErrMsg.c_str ());
921- return LLVMRustResult::Failure;
925+ if (ExtraPassesLen) {
926+ if (auto Err = PB .parsePassPipeline (
927+ MPM , StringRef (ExtraPasses, ExtraPassesLen))) {
928+ std::string ErrMsg = toString (std::move (Err));
929+ LLVMRustSetLastError (ErrMsg.c_str ());
930+ return LLVMRustResult::Failure;
931+ }
922932 }
923- }
924933
925- if (NeedThinLTOBufferPasses) {
926- MPM .addPass (CanonicalizeAliasesPass ());
927- MPM .addPass (NameAnonGlobalPass ());
928- }
929- // For `-Copt-level=0`, and the pre-link fat/thin LTO stages.
930- if (ThinLTOBufferRef && *ThinLTOBufferRef == nullptr ) {
931- // thin lto summaries prevent fat lto, so do not emit them if fat
932- // lto is requested. See PR #136840 for background information.
933- if (OptStage != LLVMRustOptStage::PreLinkFatLTO) {
934- MPM .addPass (ThinLTOBitcodeWriterPass (
935- ThinLTODataOS, ThinLTOSummaryBufferRef ? &ThinLinkDataOS : nullptr ));
936- } else {
937- MPM .addPass (BitcodeWriterPass (ThinLTODataOS));
934+ if (NeedThinLTOBufferPasses) {
935+ MPM .addPass (CanonicalizeAliasesPass ());
936+ MPM .addPass (NameAnonGlobalPass ());
938937 }
939- *ThinLTOBufferRef = ThinLTOBuffer.release ();
940- if (ThinLTOSummaryBufferRef) {
941- *ThinLTOSummaryBufferRef = ThinLTOSummaryBuffer.release ();
938+ // For `-Copt-level=0`, and the pre-link fat/thin LTO stages.
939+ if (ThinLTOBufferRef && *ThinLTOBufferRef == nullptr ) {
940+ // thin lto summaries prevent fat lto, so do not emit them if fat
941+ // lto is requested. See PR #136840 for background information.
942+ if (OptStage != LLVMRustOptStage::PreLinkFatLTO) {
943+ MPM .addPass (ThinLTOBitcodeWriterPass (
944+ ThinLTODataOS,
945+ ThinLTOSummaryBufferRef ? &ThinLinkDataOS : nullptr ));
946+ } else {
947+ MPM .addPass (BitcodeWriterPass (ThinLTODataOS));
948+ }
949+ *ThinLTOBufferRef = ThinLTOBuffer.release ();
950+ if (ThinLTOSummaryBufferRef) {
951+ *ThinLTOSummaryBufferRef = ThinLTOSummaryBuffer.release ();
952+ }
942953 }
943- }
944954
945- // now load "-enzyme" pass:
946- // With dlopen, ENZYME macro may not be defined, so check EnzymePtr directly
947- // In the case of debug builds with multiple codegen units, we might not
948- // have all function definitions available during the early compiler
949- // invocations. We therefore wait for the final lto step to run Enzyme.
950- if (EnzymePtr && IsLTO) {
951-
952- if (PrintBeforeEnzyme) {
953- // Handle the Rust flag `-Zautodiff=PrintModBefore`.
954- std::string Banner = " Module before EnzymeNewPM" ;
955- MPM .addPass (PrintModulePass (outs (), Banner, true , false ));
956- }
955+ // now load "-enzyme" pass:
956+ // With dlopen, ENZYME macro may not be defined, so check EnzymePtr directly
957+ // In the case of debug builds with multiple codegen units, we might not
958+ // have all function definitions available during the early compiler
959+ // invocations. We therefore wait for the final lto step to run Enzyme.
960+ if (EnzymePtr && IsLTO) {
961+
962+ if (PrintBeforeEnzyme) {
963+ // Handle the Rust flag `-Zautodiff=PrintModBefore`.
964+ std::string Banner = " Module before EnzymeNewPM" ;
965+ MPM .addPass (PrintModulePass (outs (), Banner, true , false ));
966+ }
957967
958- EnzymePtr (PB , false );
959- if (auto Err = PB .parsePassPipeline (MPM , " enzyme" )) {
960- std::string ErrMsg = toString (std::move (Err));
961- LLVMRustSetLastError (ErrMsg.c_str ());
962- return LLVMRustResult::Failure;
963- }
968+ EnzymePtr (PB , false );
969+ if (auto Err = PB .parsePassPipeline (MPM , " enzyme" )) {
970+ std::string ErrMsg = toString (std::move (Err));
971+ LLVMRustSetLastError (ErrMsg.c_str ());
972+ return LLVMRustResult::Failure;
973+ }
964974
965- if (PrintAfterEnzyme) {
966- // Handle the Rust flag `-Zautodiff=PrintModAfter`.
967- std::string Banner = " Module after EnzymeNewPM" ;
968- MPM .addPass (PrintModulePass (outs (), Banner, true , false ));
975+ if (PrintAfterEnzyme) {
976+ // Handle the Rust flag `-Zautodiff=PrintModAfter`.
977+ std::string Banner = " Module after EnzymeNewPM" ;
978+ MPM .addPass (PrintModulePass (outs (), Banner, true , false ));
979+ }
969980 }
970981 }
971982
0 commit comments