4242#include " llvm/CodeGen/ShadowStackGCLowering.h"
4343#include " llvm/CodeGen/SjLjEHPrepare.h"
4444#include " llvm/CodeGen/StackProtector.h"
45+ #include " llvm/CodeGen/TargetPassConfig.h"
4546#include " llvm/CodeGen/UnreachableBlockElim.h"
4647#include " llvm/CodeGen/WasmEHPrepare.h"
4748#include " llvm/CodeGen/WinEHPrepare.h"
@@ -174,8 +175,9 @@ template <typename DerivedT> class CodeGenPassBuilder {
174175 // Function object to maintain state while adding codegen IR passes.
175176 class AddIRPass {
176177 public:
177- AddIRPass (ModulePassManager &MPM, bool DebugPM, bool Check = true )
178- : MPM(MPM) {
178+ AddIRPass (ModulePassManager &MPM, const DerivedT &PB, bool DebugPM,
179+ bool Check = true )
180+ : MPM(MPM), PB(PB) {
179181 if (Check)
180182 AddingFunctionPasses = false ;
181183 }
@@ -186,10 +188,17 @@ template <typename DerivedT> class CodeGenPassBuilder {
186188 // Add Function Pass
187189 template <typename PassT>
188190 std::enable_if_t <is_detected<is_function_pass_t , PassT>::value>
189- operator ()(PassT &&Pass) {
191+ operator ()(PassT &&Pass, StringRef Name = PassT::name() ) {
190192 if (AddingFunctionPasses && !*AddingFunctionPasses)
191193 AddingFunctionPasses = true ;
194+ for (const auto C : PB.BeforeCallbacks )
195+ if (!C (Name))
196+ return ;
197+
192198 FPM.addPass (std::forward<PassT>(Pass));
199+
200+ for (const auto &C : PB.AfterCallbacks )
201+ C (Name);
193202 }
194203
195204 // Add Module Pass
@@ -199,12 +208,20 @@ template <typename DerivedT> class CodeGenPassBuilder {
199208 operator ()(PassT &&Pass) {
200209 assert ((!AddingFunctionPasses || !*AddingFunctionPasses) &&
201210 " could not add module pass after adding function pass" );
211+ for (const auto C : PB.BeforeCallbacks )
212+ if (!C (PassT::name ()))
213+ return ;
214+
202215 MPM.addPass (std::forward<PassT>(Pass));
216+
217+ for (const auto &C : PB.AfterCallbacks )
218+ C (PassT::name ());
203219 }
204220
205221 private:
206222 ModulePassManager &MPM;
207223 FunctionPassManager FPM;
224+ const DerivedT &PB;
208225 // The codegen IR pipeline are mostly function passes with the exceptions of
209226 // a few loop and module passes. `AddingFunctionPasses` make sures that
210227 // we could only add module passes at the beginning of the pipeline. Once
@@ -218,41 +235,34 @@ template <typename DerivedT> class CodeGenPassBuilder {
218235 // Function object to maintain state while adding codegen machine passes.
219236 class AddMachinePass {
220237 public:
221- AddMachinePass (MachineFunctionPassManager &PM) : PM(PM) {}
238+ AddMachinePass (MachineFunctionPassManager &PM, const DerivedT &PB)
239+ : PM(PM), PB(PB) {}
222240
223241 template <typename PassT> void operator ()(PassT &&Pass) {
224242 static_assert (
225243 is_detected<has_key_t , PassT>::value,
226244 " Machine function pass must define a static member variable `Key`." );
227- for (auto &C : BeforeCallbacks)
228- if (!C (& PassT::Key ))
245+ for (auto &C : PB. BeforeCallbacks )
246+ if (!C (PassT::name () ))
229247 return ;
230248 PM.addPass (std::forward<PassT>(Pass));
231- for (auto &C : AfterCallbacks)
232- C (& PassT::Key );
249+ for (auto &C : PB. AfterCallbacks )
250+ C (PassT::name () );
233251 }
234252
235253 template <typename PassT> void insertPass (MachinePassKey *ID, PassT Pass) {
236- AfterCallbacks.emplace_back (
254+ PB. AfterCallbacks .emplace_back (
237255 [this , ID, Pass = std::move (Pass)](MachinePassKey *PassID) {
238256 if (PassID == ID)
239257 this ->PM .addPass (std::move (Pass));
240258 });
241259 }
242260
243- void disablePass (MachinePassKey *ID) {
244- BeforeCallbacks.emplace_back (
245- [ID](MachinePassKey *PassID) { return PassID != ID; });
246- }
247-
248261 MachineFunctionPassManager releasePM () { return std::move (PM); }
249262
250263 private:
251264 MachineFunctionPassManager &PM;
252- SmallVector<llvm::unique_function<bool (MachinePassKey *)>, 4 >
253- BeforeCallbacks;
254- SmallVector<llvm::unique_function<void (MachinePassKey *)>, 4 >
255- AfterCallbacks;
265+ const DerivedT &PB;
256266 };
257267
258268 LLVMTargetMachine &TM;
@@ -480,20 +490,37 @@ template <typename DerivedT> class CodeGenPassBuilder {
480490 const DerivedT &derived () const {
481491 return static_cast <const DerivedT &>(*this );
482492 }
493+
494+ void setStartStopPasses (const TargetPassConfig::StartStopInfo &Info) const ;
495+
496+ Error verifyStartStop (const TargetPassConfig::StartStopInfo &Info) const ;
497+
498+ mutable SmallVector<llvm::unique_function<bool (StringRef)>, 4 >
499+ BeforeCallbacks;
500+ mutable SmallVector<llvm::unique_function<void (StringRef)>, 4 > AfterCallbacks;
501+
502+ // / Helper variable for `-start-before/-start-after/-stop-before/-stop-after`
503+ mutable bool ShouldAddPass = true ;
504+ mutable bool Started = true ;
505+ mutable bool Stopped = true ;
483506};
484507
485508template <typename Derived>
486509Error CodeGenPassBuilder<Derived>::buildPipeline(
487510 ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
488511 raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
489512 CodeGenFileType FileType) const {
490- AddIRPass addIRPass (MPM, Opt.DebugPM );
513+ auto StartStopInfo = TargetPassConfig::getStartStopInfo (*PIC);
514+ if (StartStopInfo)
515+ return StartStopInfo.takeError ();
516+ setStartStopPasses (*StartStopInfo);
517+ AddIRPass addIRPass (MPM, derived (), Opt.DebugPM );
491518 // `ProfileSummaryInfo` is always valid.
492519 addIRPass (RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
493520 addIRPass (RequireAnalysisPass<CollectorMetadataAnalysis, Module>());
494521 addISelPasses (addIRPass);
495522
496- AddMachinePass addPass (MFPM);
523+ AddMachinePass addPass (MFPM, derived () );
497524 if (auto Err = addCoreISelPasses (addPass))
498525 return std::move (Err);
499526
@@ -506,7 +533,94 @@ Error CodeGenPassBuilder<Derived>::buildPipeline(
506533 });
507534
508535 addPass (FreeMachineFunctionPass ());
509- return Error::success ();
536+ return verifyStartStop (StartStopInfo);
537+ }
538+
539+ template <typename Derived>
540+ void CodeGenPassBuilder<Derived>::setStartStopPasses(
541+ const TargetPassConfig::StartStopInfo &Info) const {
542+ if (!Info.StartPass .empty ()) {
543+ ShouldAddPass = false ;
544+ Started = false ;
545+ if (Info.StartBefore ) {
546+ BeforeCallbacks.emplace_back (
547+ [this , &Info, Count = 0 ](StringRef ClassName) mutable {
548+ auto PassName = PIC->getPassNameForClassName (ClassName);
549+ if (Count == Info.StartInstanceNum )
550+ return true ;
551+ if (Info.StartPass == PassName)
552+ ++Count;
553+ if (Count == Info.StartInstanceNum ) {
554+ ShouldAddPass = true ;
555+ Started = true ;
556+ }
557+ return ShouldAddPass;
558+ });
559+ } else {
560+ AfterCallbacks.emplace_back (
561+ [this , &Info, Count = 0 ](StringRef ClassName) mutable {
562+ auto PassName = PIC->getPassNameForClassName (ClassName);
563+ if (Count == Info.StartInstanceNum )
564+ return ;
565+ if (Info.StartPass == PassName)
566+ ++Count;
567+ if (Count == Info.StartInstanceNum ) {
568+ ShouldAddPass = true ;
569+ Started = true ;
570+ }
571+ });
572+ }
573+ }
574+
575+ if (!Info.StopPass .empty ()) {
576+ Stopped = false ;
577+ if (Info.StopBefore ) {
578+ BeforeCallbacks.emplace_back (
579+ [this , &Info, Count = 0u ](StringRef ClassName) mutable {
580+ auto PassName = PIC->getPassNameForClassName (ClassName);
581+ if (Count == Info.StopInstanceNum )
582+ return false ;
583+ if (Info.StopPass == PassName)
584+ ++Count;
585+ if (Count == Info.StopInstanceNum ) {
586+ ShouldAddPass = false ;
587+ Stopped = true ;
588+ }
589+ return ShouldAddPass;
590+ });
591+ } else {
592+ AfterCallbacks.emplace_back (
593+ [this , &Info, Count = 0u ](StringRef ClassName) mutable {
594+ auto PassName = PIC->getPassNameForClassName (ClassName);
595+ if (Count == Info.StopInstanceNum )
596+ return ;
597+ if (Info.StopPass == PassName)
598+ ++Count;
599+ if (Count == Info.StopInstanceNum ) {
600+ ShouldAddPass = false ;
601+ Stopped = true ;
602+ }
603+ });
604+ }
605+ }
606+ }
607+
608+ template <typename Derived>
609+ Error CodeGenPassBuilder<Derived>::verifyStartStop(
610+ const TargetPassConfig::StartStopInfo &Info) const {
611+ if (Started && Stopped)
612+ return Error::success ();
613+
614+ if (!Started)
615+ return make_error<StringError>(
616+ " Can't find start pass \" " +
617+ PIC->getPassNameForClassName (Info.StartPass ) + " \" ." ,
618+ std::make_error_code (std::errc::invalid_argument));
619+ if (!Stopped)
620+ return make_error<StringError>(
621+ " Can't find stop pass \" " +
622+ PIC->getPassNameForClassName (Info.StopPass ) + " \" ." ,
623+ std::make_error_code (std::errc::invalid_argument));
510624}
511625
512626static inline AAManager registerAAAnalyses () {
@@ -626,8 +740,9 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
626740
627741 // Run loop strength reduction before anything else.
628742 if (getOptLevel () != CodeGenOptLevel::None && !Opt.DisableLSR ) {
629- addPass (createFunctionToLoopPassAdaptor (
630- LoopStrengthReducePass (), /* UseMemorySSA*/ true , Opt.DebugPM ));
743+ addPass (createFunctionToLoopPassAdaptor (LoopStrengthReducePass (),
744+ /* UseMemorySSA*/ true , Opt.DebugPM ),
745+ LoopStrengthReducePass::name ());
631746 // FIXME: use -stop-after so we could remove PrintLSR
632747 if (Opt.PrintLSR )
633748 addPass (PrintFunctionPass (dbgs (), " \n\n *** Code after LSR ***\n " ));
0 commit comments