[CGSCC] Allow creation of no-rerun CGSCC->function adaptor via textual pipeline

Reviewed By: asbirlea

Differential Revision: https://reviews.llvm.org/D145196
This commit is contained in:
Arthur Eubanks 2023-03-02 14:47:46 -08:00
parent 500d530eaf
commit 5558346c2b
4 changed files with 63 additions and 11 deletions

View File

@ -487,8 +487,16 @@ public:
void printPipeline(raw_ostream &OS,
function_ref<StringRef(StringRef)> MapClassName2PassName) {
OS << "function";
if (EagerlyInvalidate)
OS << "<eager-inv>";
if (EagerlyInvalidate || NoRerun) {
OS << "<";
if (EagerlyInvalidate)
OS << "eager-inv";
if (EagerlyInvalidate && NoRerun)
OS << ";";
if (NoRerun)
OS << "no-rerun";
OS << ">";
}
OS << '(';
Pass->printPipeline(OS, MapClassName2PassName);
OS << ')';

View File

@ -486,6 +486,28 @@ static std::optional<int> parseRepeatPassName(StringRef Name) {
return Count;
}
static std::optional<std::pair<bool, bool>>
parseFunctionPipelineName(StringRef Name) {
std::pair<bool, bool> Params;
if (!Name.consume_front("function"))
return std::nullopt;
if (Name.empty())
return Params;
if (!Name.consume_front("<") || !Name.consume_back(">"))
return std::nullopt;
while (!Name.empty()) {
auto [Front, Back] = Name.split(';');
Name = Back;
if (Front == "eager-inv")
Params.first = true;
else if (Front == "no-rerun")
Params.second = true;
else
return std::nullopt;
}
return Params;
}
static std::optional<int> parseDevirtPassName(StringRef Name) {
if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
return std::nullopt;
@ -1009,12 +1031,14 @@ static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
if (startsWithDefaultPipelineAliasPrefix(Name))
return DefaultAliasRegex.match(Name);
StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
// Explicitly handle pass manager names.
if (Name == "module")
return true;
if (Name == "cgscc")
return true;
if (Name == "function" || Name == "function<eager-inv>")
if (NameNoBracket == "function")
return true;
if (Name == "coro-cond")
return true;
@ -1040,9 +1064,10 @@ static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
template <typename CallbacksT>
static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
// Explicitly handle pass manager names.
StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
if (Name == "cgscc")
return true;
if (Name == "function" || Name == "function<eager-inv>")
if (NameNoBracket == "function")
return true;
// Explicitly handle custom-parsed pass names.
@ -1068,7 +1093,8 @@ static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
template <typename CallbacksT>
static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
// Explicitly handle pass manager names.
if (Name == "function" || Name == "function<eager-inv>")
StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
if (NameNoBracket == "function")
return true;
if (Name == "loop" || Name == "loop-mssa")
return true;
@ -1226,12 +1252,16 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM,
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
return Error::success();
}
if (Name == "function" || Name == "function<eager-inv>") {
if (auto Params = parseFunctionPipelineName(Name)) {
if (Params->second)
return make_error<StringError>(
"cannot have a no-rerun module to function adaptor",
inconvertibleErrorCode());
FunctionPassManager FPM;
if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
return Err;
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM),
Name != "function"));
MPM.addPass(
createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
return Error::success();
}
if (auto Count = parseRepeatPassName(Name)) {
@ -1394,13 +1424,13 @@ Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
CGPM.addPass(std::move(NestedCGPM));
return Error::success();
}
if (Name == "function" || Name == "function<eager-inv>") {
if (auto Params = parseFunctionPipelineName(Name)) {
FunctionPassManager FPM;
if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
return Err;
// Add the nested pass manager with the appropriate adaptor.
CGPM.addPass(
createCGSCCToFunctionPassAdaptor(std::move(FPM), Name != "function"));
CGPM.addPass(createCGSCCToFunctionPassAdaptor(
std::move(FPM), Params->first, Params->second));
return Error::success();
}
if (auto Count = parseRepeatPassName(Name)) {

View File

@ -101,3 +101,13 @@
;; Test function-attrs
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='cgscc(function-attrs<skip-non-recursive>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-29
; CHECK-29: cgscc(function-attrs<skip-non-recursive>)
;; Test cgscc -> function adaptor
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='cgscc(function<eager-inv;no-rerun>(no-op-function))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-30
; CHECK-30: cgscc(function<eager-inv;no-rerun>(no-op-function))
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='cgscc(function<no-rerun;eager-inv>(no-op-function))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-31
; CHECK-31: cgscc(function<eager-inv;no-rerun>(no-op-function))
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='cgscc(function<no-rerun>(no-op-function))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-32
; CHECK-32: cgscc(function<no-rerun>(no-op-function))

View File

@ -57,6 +57,10 @@
; CHECK-DEFAULT-AA-DAG: Running analysis: BasicAA
; CHECK-DEFAULT-AA-DAG: Running analysis: TypeBasedAA
; RUN: not opt -passes='function<no-rerun>(no-op-function)' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-RERUN-BAD
; CHECK-RERUN-BAD: cannot have a no-rerun module to function adaptor
; RUN: not opt -disable-output -debug-pass-manager \
; RUN: -passes='no-op-module)' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-UNBALANCED1