42
42
#include " llvm/CodeGen/ShadowStackGCLowering.h"
43
43
#include " llvm/CodeGen/SjLjEHPrepare.h"
44
44
#include " llvm/CodeGen/StackProtector.h"
45
+ #include " llvm/CodeGen/TargetPassConfig.h"
45
46
#include " llvm/CodeGen/UnreachableBlockElim.h"
46
47
#include " llvm/CodeGen/WasmEHPrepare.h"
47
48
#include " llvm/CodeGen/WinEHPrepare.h"
@@ -174,8 +175,9 @@ template <typename DerivedT> class CodeGenPassBuilder {
174
175
// Function object to maintain state while adding codegen IR passes.
175
176
class AddIRPass {
176
177
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) {
179
181
if (Check)
180
182
AddingFunctionPasses = false ;
181
183
}
@@ -186,10 +188,17 @@ template <typename DerivedT> class CodeGenPassBuilder {
186
188
// Add Function Pass
187
189
template <typename PassT>
188
190
std::enable_if_t <is_detected<is_function_pass_t , PassT>::value>
189
- operator ()(PassT &&Pass) {
191
+ operator ()(PassT &&Pass, StringRef Name = PassT::name() ) {
190
192
if (AddingFunctionPasses && !*AddingFunctionPasses)
191
193
AddingFunctionPasses = true ;
194
+ for (const auto C : PB.BeforeCallbacks )
195
+ if (!C (Name))
196
+ return ;
197
+
192
198
FPM.addPass (std::forward<PassT>(Pass));
199
+
200
+ for (const auto &C : PB.AfterCallbacks )
201
+ C (Name);
193
202
}
194
203
195
204
// Add Module Pass
@@ -199,12 +208,20 @@ template <typename DerivedT> class CodeGenPassBuilder {
199
208
operator ()(PassT &&Pass) {
200
209
assert ((!AddingFunctionPasses || !*AddingFunctionPasses) &&
201
210
" could not add module pass after adding function pass" );
211
+ for (const auto C : PB.BeforeCallbacks )
212
+ if (!C (PassT::name ()))
213
+ return ;
214
+
202
215
MPM.addPass (std::forward<PassT>(Pass));
216
+
217
+ for (const auto &C : PB.AfterCallbacks )
218
+ C (PassT::name ());
203
219
}
204
220
205
221
private:
206
222
ModulePassManager &MPM;
207
223
FunctionPassManager FPM;
224
+ const DerivedT &PB;
208
225
// The codegen IR pipeline are mostly function passes with the exceptions of
209
226
// a few loop and module passes. `AddingFunctionPasses` make sures that
210
227
// we could only add module passes at the beginning of the pipeline. Once
@@ -218,41 +235,34 @@ template <typename DerivedT> class CodeGenPassBuilder {
218
235
// Function object to maintain state while adding codegen machine passes.
219
236
class AddMachinePass {
220
237
public:
221
- AddMachinePass (MachineFunctionPassManager &PM) : PM(PM) {}
238
+ AddMachinePass (MachineFunctionPassManager &PM, const DerivedT &PB)
239
+ : PM(PM), PB(PB) {}
222
240
223
241
template <typename PassT> void operator ()(PassT &&Pass) {
224
242
static_assert (
225
243
is_detected<has_key_t , PassT>::value,
226
244
" 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 () ))
229
247
return ;
230
248
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 () );
233
251
}
234
252
235
253
template <typename PassT> void insertPass (MachinePassKey *ID, PassT Pass) {
236
- AfterCallbacks.emplace_back (
254
+ PB. AfterCallbacks .emplace_back (
237
255
[this , ID, Pass = std::move (Pass)](MachinePassKey *PassID) {
238
256
if (PassID == ID)
239
257
this ->PM .addPass (std::move (Pass));
240
258
});
241
259
}
242
260
243
- void disablePass (MachinePassKey *ID) {
244
- BeforeCallbacks.emplace_back (
245
- [ID](MachinePassKey *PassID) { return PassID != ID; });
246
- }
247
-
248
261
MachineFunctionPassManager releasePM () { return std::move (PM); }
249
262
250
263
private:
251
264
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;
256
266
};
257
267
258
268
LLVMTargetMachine &TM;
@@ -480,20 +490,37 @@ template <typename DerivedT> class CodeGenPassBuilder {
480
490
const DerivedT &derived () const {
481
491
return static_cast <const DerivedT &>(*this );
482
492
}
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 ;
483
506
};
484
507
485
508
template <typename Derived>
486
509
Error CodeGenPassBuilder<Derived>::buildPipeline(
487
510
ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
488
511
raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
489
512
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 );
491
518
// `ProfileSummaryInfo` is always valid.
492
519
addIRPass (RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
493
520
addIRPass (RequireAnalysisPass<CollectorMetadataAnalysis, Module>());
494
521
addISelPasses (addIRPass);
495
522
496
- AddMachinePass addPass (MFPM);
523
+ AddMachinePass addPass (MFPM, derived () );
497
524
if (auto Err = addCoreISelPasses (addPass))
498
525
return std::move (Err);
499
526
@@ -506,7 +533,94 @@ Error CodeGenPassBuilder<Derived>::buildPipeline(
506
533
});
507
534
508
535
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));
510
624
}
511
625
512
626
static inline AAManager registerAAAnalyses () {
@@ -626,8 +740,9 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
626
740
627
741
// Run loop strength reduction before anything else.
628
742
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 ());
631
746
// FIXME: use -stop-after so we could remove PrintLSR
632
747
if (Opt.PrintLSR )
633
748
addPass (PrintFunctionPass (dbgs (), " \n\n *** Code after LSR ***\n " ));
0 commit comments