Skip to content

Commit 6eb14fe

Browse files
committed
[CodeGen][NewPM] Support start/stop in CodeGen
1 parent e364ddf commit 6eb14fe

File tree

4 files changed

+190
-24
lines changed

4 files changed

+190
-24
lines changed

llvm/include/llvm/CodeGen/CodeGenPassBuilder.h

Lines changed: 138 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
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

485508
template <typename Derived>
486509
Error 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

512626
static 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"));

llvm/include/llvm/CodeGen/TargetPassConfig.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "llvm/Pass.h"
1717
#include "llvm/Support/CodeGen.h"
18+
#include "llvm/Support/Error.h"
1819
#include <cassert>
1920
#include <string>
2021

@@ -176,6 +177,20 @@ class TargetPassConfig : public ImmutablePass {
176177
static std::string
177178
getLimitedCodeGenPipelineReason(const char *Separator = "/");
178179

180+
struct StartStopInfo {
181+
bool StartBefore;
182+
bool StopBefore;
183+
unsigned StartInstanceNum;
184+
unsigned StopInstanceNum;
185+
StringRef StartPass;
186+
StringRef StopPass;
187+
};
188+
189+
/// Returns pass name in `-stop-before` or `-stop-after`
190+
/// NOTE: New pass manager migration only
191+
static Expected<StartStopInfo>
192+
getStartStopInfo(PassInstrumentationCallbacks &PIC);
193+
179194
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
180195

181196
bool getEnableTailMerge() const { return EnableTailMerge; }

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,40 @@ void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
609609
registerPartialPipelineCallback(PIC, LLVMTM);
610610
}
611611

612+
Expected<TargetPassConfig::StartStopInfo>
613+
TargetPassConfig::getStartStopInfo(PassInstrumentationCallbacks &PIC) {
614+
auto [StartBefore, StartBeforeInstanceNum] =
615+
getPassNameAndInstanceNum(StartBeforeOpt);
616+
auto [StartAfter, StartAfterInstanceNum] =
617+
getPassNameAndInstanceNum(StartAfterOpt);
618+
auto [StopBefore, StopBeforeInstanceNum] =
619+
getPassNameAndInstanceNum(StopBeforeOpt);
620+
auto [StopAfter, StopAfterInstanceNum] =
621+
getPassNameAndInstanceNum(StopAfterOpt);
622+
623+
if (!StartBefore.empty() && !StartAfter.empty())
624+
return make_error<StringError>(
625+
Twine(StartBeforeOptName) + " and " + StartAfterOptName + " specified!",
626+
std::make_error_code(std::errc::invalid_argument));
627+
if (!StopBefore.empty() && !StopAfter.empty())
628+
return make_error<StringError>(
629+
Twine(StopBeforeOptName) + " and " + StopAfterOptName + " specified!",
630+
std::make_error_code(std::errc::invalid_argument));
631+
632+
StartStopInfo Result;
633+
Result.StartPass = StartBefore.empty() ? StartAfter : StartBefore;
634+
Result.StopPass = StopBefore.empty() ? StopAfter : StopBefore;
635+
Result.StartInstanceNum =
636+
StartBefore.empty() ? StartAfterInstanceNum : StartBeforeInstanceNum;
637+
Result.StopInstanceNum =
638+
StopBefore.empty() ? StopAfterInstanceNum : StopBeforeInstanceNum;
639+
Result.StartBefore = !StartBefore.empty();
640+
Result.StopBefore = !StopBefore.empty();
641+
Result.StartInstanceNum += Result.StartInstanceNum == 0;
642+
Result.StopInstanceNum += Result.StopInstanceNum == 0;
643+
return Result;
644+
}
645+
612646
// Out of line constructor provides default values for pass options and
613647
// registers all common codegen passes.
614648
TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#include "llvm/CodeGen/ShadowStackGCLowering.h"
9292
#include "llvm/CodeGen/SjLjEHPrepare.h"
9393
#include "llvm/CodeGen/StackProtector.h"
94+
#include "llvm/CodeGen/TargetPassConfig.h"
9495
#include "llvm/CodeGen/TypePromotion.h"
9596
#include "llvm/CodeGen/WasmEHPrepare.h"
9697
#include "llvm/CodeGen/WinEHPrepare.h"
@@ -410,7 +411,8 @@ AnalysisKey NoOpLoopAnalysis::Key;
410411
/// We currently only use this for --print-before/after.
411412
bool shouldPopulateClassToPassNames() {
412413
return PrintPipelinePasses || !printBeforePasses().empty() ||
413-
!printAfterPasses().empty() || !isFilterPassesEmpty();
414+
!printAfterPasses().empty() || !isFilterPassesEmpty() ||
415+
TargetPassConfig::hasLimitedCodeGenPipeline();
414416
}
415417

416418
// A pass for testing -print-on-crash.

0 commit comments

Comments
 (0)