44
44
#include " llvm/CodeGen/ShadowStackGCLowering.h"
45
45
#include " llvm/CodeGen/SjLjEHPrepare.h"
46
46
#include " llvm/CodeGen/StackProtector.h"
47
+ #include " llvm/CodeGen/TargetPassConfig.h"
47
48
#include " llvm/CodeGen/UnreachableBlockElim.h"
48
49
#include " llvm/CodeGen/WasmEHPrepare.h"
49
50
#include " llvm/CodeGen/WinEHPrepare.h"
@@ -176,73 +177,80 @@ template <typename DerivedT> class CodeGenPassBuilder {
176
177
// Function object to maintain state while adding codegen IR passes.
177
178
class AddIRPass {
178
179
public:
179
- AddIRPass (ModulePassManager &MPM) : MPM(MPM) {}
180
+ AddIRPass (ModulePassManager &MPM, const DerivedT &PB ) : MPM(MPM), PB(PB ) {}
180
181
~AddIRPass () {
181
182
if (!FPM.isEmpty ())
182
183
MPM.addPass (createModuleToFunctionPassAdaptor (std::move (FPM)));
183
184
}
184
185
185
- template <typename PassT> void operator ()(PassT &&Pass) {
186
+ template <typename PassT>
187
+ void operator ()(PassT &&Pass, StringRef Name = PassT::name()) {
186
188
static_assert ((is_detected<is_function_pass_t , PassT>::value ||
187
189
is_detected<is_module_pass_t , PassT>::value) &&
188
190
" Only module pass and function pass are supported." );
189
191
192
+ if (!PB.runBeforeAdding (Name))
193
+ return ;
194
+
190
195
// Add Function Pass
191
196
if constexpr (is_detected<is_function_pass_t , PassT>::value) {
192
197
FPM.addPass (std::forward<PassT>(Pass));
198
+
199
+ for (auto &C : PB.AfterCallbacks )
200
+ C (Name);
193
201
} else {
194
202
// Add Module Pass
195
203
if (!FPM.isEmpty ()) {
196
204
MPM.addPass (createModuleToFunctionPassAdaptor (std::move (FPM)));
197
205
FPM = FunctionPassManager ();
198
206
}
207
+
199
208
MPM.addPass (std::forward<PassT>(Pass));
209
+
210
+ for (auto &C : PB.AfterCallbacks )
211
+ C (Name);
200
212
}
201
213
}
202
214
203
215
private:
204
216
ModulePassManager &MPM;
205
217
FunctionPassManager FPM;
218
+ const DerivedT &PB;
206
219
};
207
220
208
221
// Function object to maintain state while adding codegen machine passes.
209
222
class AddMachinePass {
210
223
public:
211
- AddMachinePass (MachineFunctionPassManager &PM) : PM(PM) {}
224
+ AddMachinePass (MachineFunctionPassManager &PM, const DerivedT &PB)
225
+ : PM(PM), PB(PB) {}
212
226
213
227
template <typename PassT> void operator ()(PassT &&Pass) {
214
228
static_assert (
215
229
is_detected<has_key_t , PassT>::value,
216
230
" Machine function pass must define a static member variable `Key`." );
217
- for (auto &C : BeforeCallbacks)
218
- if (!C (&PassT::Key))
219
- return ;
231
+
232
+ if (!PB.runBeforeAdding (PassT::name ()))
233
+ return ;
234
+
220
235
PM.addPass (std::forward<PassT>(Pass));
221
- for (auto &C : AfterCallbacks)
222
- C (&PassT::Key);
236
+
237
+ for (auto &C : PB.AfterCallbacks )
238
+ C (PassT::name ());
223
239
}
224
240
225
241
template <typename PassT> void insertPass (MachinePassKey *ID, PassT Pass) {
226
- AfterCallbacks.emplace_back (
242
+ PB. AfterCallbacks .emplace_back (
227
243
[this , ID, Pass = std::move (Pass)](MachinePassKey *PassID) {
228
244
if (PassID == ID)
229
245
this ->PM .addPass (std::move (Pass));
230
246
});
231
247
}
232
248
233
- void disablePass (MachinePassKey *ID) {
234
- BeforeCallbacks.emplace_back (
235
- [ID](MachinePassKey *PassID) { return PassID != ID; });
236
- }
237
-
238
249
MachineFunctionPassManager releasePM () { return std::move (PM); }
239
250
240
251
private:
241
252
MachineFunctionPassManager &PM;
242
- SmallVector<llvm::unique_function<bool (MachinePassKey *)>, 4 >
243
- BeforeCallbacks;
244
- SmallVector<llvm::unique_function<void (MachinePassKey *)>, 4 >
245
- AfterCallbacks;
253
+ const DerivedT &PB;
246
254
};
247
255
248
256
LLVMTargetMachine &TM;
@@ -473,20 +481,43 @@ template <typename DerivedT> class CodeGenPassBuilder {
473
481
const DerivedT &derived () const {
474
482
return static_cast <const DerivedT &>(*this );
475
483
}
484
+
485
+ bool runBeforeAdding (StringRef Name) const {
486
+ bool ShouldAdd = true ;
487
+ for (auto &C : BeforeCallbacks)
488
+ ShouldAdd &= C (Name);
489
+ return ShouldAdd;
490
+ }
491
+
492
+ void setStartStopPasses (const TargetPassConfig::StartStopInfo &Info) const ;
493
+
494
+ Error verifyStartStop (const TargetPassConfig::StartStopInfo &Info) const ;
495
+
496
+ mutable SmallVector<llvm::unique_function<bool (StringRef)>, 4 >
497
+ BeforeCallbacks;
498
+ mutable SmallVector<llvm::unique_function<void (StringRef)>, 4 > AfterCallbacks;
499
+
500
+ // / Helper variable for `-start-before/-start-after/-stop-before/-stop-after`
501
+ mutable bool Started = true ;
502
+ mutable bool Stopped = true ;
476
503
};
477
504
478
505
template <typename Derived>
479
506
Error CodeGenPassBuilder<Derived>::buildPipeline(
480
507
ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
481
508
raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
482
509
CodeGenFileType FileType) const {
483
- AddIRPass addIRPass (MPM);
510
+ auto StartStopInfo = TargetPassConfig::getStartStopInfo (*PIC);
511
+ if (!StartStopInfo)
512
+ return StartStopInfo.takeError ();
513
+ setStartStopPasses (*StartStopInfo);
514
+ AddIRPass addIRPass (MPM, derived ());
484
515
// `ProfileSummaryInfo` is always valid.
485
516
addIRPass (RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
486
517
addIRPass (RequireAnalysisPass<CollectorMetadataAnalysis, Module>());
487
518
addISelPasses (addIRPass);
488
519
489
- AddMachinePass addPass (MFPM);
520
+ AddMachinePass addPass (MFPM, derived () );
490
521
if (auto Err = addCoreISelPasses (addPass))
491
522
return std::move (Err);
492
523
@@ -499,6 +530,68 @@ Error CodeGenPassBuilder<Derived>::buildPipeline(
499
530
});
500
531
501
532
addPass (FreeMachineFunctionPass ());
533
+ return verifyStartStop (*StartStopInfo);
534
+ }
535
+
536
+ template <typename Derived>
537
+ void CodeGenPassBuilder<Derived>::setStartStopPasses(
538
+ const TargetPassConfig::StartStopInfo &Info) const {
539
+ if (!Info.StartPass .empty ()) {
540
+ Started = false ;
541
+ BeforeCallbacks.emplace_back ([this , &Info, AfterFlag = Info.StartAfter ,
542
+ Count = 0u ](StringRef ClassName) mutable {
543
+ if (Count == Info.StartInstanceNum ) {
544
+ if (AfterFlag) {
545
+ AfterFlag = false ;
546
+ Started = true ;
547
+ }
548
+ return Started;
549
+ }
550
+
551
+ auto PassName = PIC->getPassNameForClassName (ClassName);
552
+ if (Info.StartPass == PassName && ++Count == Info.StartInstanceNum )
553
+ Started = !Info.StartAfter ;
554
+
555
+ return Started;
556
+ });
557
+ }
558
+
559
+ if (!Info.StopPass .empty ()) {
560
+ Stopped = false ;
561
+ BeforeCallbacks.emplace_back ([this , &Info, AfterFlag = Info.StopAfter ,
562
+ Count = 0u ](StringRef ClassName) mutable {
563
+ if (Count == Info.StopInstanceNum ) {
564
+ if (AfterFlag) {
565
+ AfterFlag = false ;
566
+ Stopped = true ;
567
+ }
568
+ return !Stopped;
569
+ }
570
+
571
+ auto PassName = PIC->getPassNameForClassName (ClassName);
572
+ if (Info.StopPass == PassName && ++Count == Info.StopInstanceNum )
573
+ Stopped = !Info.StopAfter ;
574
+ return !Stopped;
575
+ });
576
+ }
577
+ }
578
+
579
+ template <typename Derived>
580
+ Error CodeGenPassBuilder<Derived>::verifyStartStop(
581
+ const TargetPassConfig::StartStopInfo &Info) const {
582
+ if (Started && Stopped)
583
+ return Error::success ();
584
+
585
+ if (!Started)
586
+ return make_error<StringError>(
587
+ " Can't find start pass \" " +
588
+ PIC->getPassNameForClassName (Info.StartPass ) + " \" ." ,
589
+ std::make_error_code (std::errc::invalid_argument));
590
+ if (!Stopped)
591
+ return make_error<StringError>(
592
+ " Can't find stop pass \" " +
593
+ PIC->getPassNameForClassName (Info.StopPass ) + " \" ." ,
594
+ std::make_error_code (std::errc::invalid_argument));
502
595
return Error::success ();
503
596
}
504
597
0 commit comments