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