1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

[NewPM] make parsePassPipeline parse adaptor-wrapped user passes

Currently, when parsing text pipeline, different kinds of passes always
introduce nested pass managers. This makes it impossible to test the
adaptor-wrapped user passes from the text pipeline interface which is needed
by D82344 test cases. This also seems useful in general. See comments above
`parsePassPipeline`.

The syntax would be like mixing passes of different types, but it is
not the same as inferring the correct pass type and then adding the
matching nested pass managers. Strictly speaking, the resulted pipelines
are different.

Reviewed By: asbirlea, aeubanks

Differential Revision: https://reviews.llvm.org/D82698
This commit is contained in:
Yuanfang Chen 2020-07-18 22:26:37 -07:00
parent 5c895af3ba
commit a7608ccb78
3 changed files with 128 additions and 4 deletions

View File

@ -472,10 +472,21 @@ public:
/// module(function(loop(lpass1,lpass2,lpass3)))
///
/// This shortcut is especially useful for debugging and testing small pass
/// combinations. Note that these shortcuts don't introduce any other magic.
/// If the sequence of passes aren't all the exact same kind of pass, it will
/// be an error. You cannot mix different levels implicitly, you must
/// explicitly form a pass manager in which to nest passes.
/// combinations.
///
/// The sequence of passes aren't necessarily the exact same kind of pass.
/// You can mix different levels implicitly if adaptor passes are defined to
/// make them work. For example,
///
/// mpass1,fpass1,fpass2,mpass2,lpass1
///
/// This pipeline uses only one pass manager: the top-level module manager.
/// fpass1,fpass2 and lpass1 are added into the the top-level module manager
/// using only adaptor passes. No nested function/loop pass managers are
/// added. The purpose is to allow easy pass testing when the user
/// specifically want the pass to run under a adaptor directly. This is
/// preferred when a pipeline is largely of one type, but one or just a few
/// passes are of different types(See PassBuilder.cpp for examples).
Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
bool VerifyEachPass = true,
bool DebugLogging = false);

View File

@ -2212,6 +2212,40 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM,
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
return Error::success(); \
}
#define CGSCC_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
return Error::success(); \
}
#define FUNCTION_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
return Error::success(); \
}
#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \
if (checkParametrizedPassName(Name, NAME)) { \
auto Params = parsePassParameters(PARSER, Name, NAME); \
if (!Params) \
return Params.takeError(); \
MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
return Error::success(); \
}
#define LOOP_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
MPM.addPass(createModuleToFunctionPassAdaptor( \
createFunctionToLoopPassAdaptor(CREATE_PASS, false, DebugLogging))); \
return Error::success(); \
}
#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \
if (checkParametrizedPassName(Name, NAME)) { \
auto Params = parsePassParameters(PARSER, Name, NAME); \
if (!Params) \
return Params.takeError(); \
MPM.addPass( \
createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
CREATE_PASS(Params.get()), false, DebugLogging))); \
return Error::success(); \
}
#include "PassRegistry.def"
for (auto &C : ModulePipelineParsingCallbacks)
@ -2295,6 +2329,35 @@ Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
return Error::success(); \
}
#define FUNCTION_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
return Error::success(); \
}
#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \
if (checkParametrizedPassName(Name, NAME)) { \
auto Params = parsePassParameters(PARSER, Name, NAME); \
if (!Params) \
return Params.takeError(); \
CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
return Error::success(); \
}
#define LOOP_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
createFunctionToLoopPassAdaptor(CREATE_PASS, false, DebugLogging))); \
return Error::success(); \
}
#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \
if (checkParametrizedPassName(Name, NAME)) { \
auto Params = parsePassParameters(PARSER, Name, NAME); \
if (!Params) \
return Params.takeError(); \
CGPM.addPass( \
createCGSCCToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
CREATE_PASS(Params.get()), false, DebugLogging))); \
return Error::success(); \
}
#include "PassRegistry.def"
for (auto &C : CGSCCPipelineParsingCallbacks)
@ -2378,6 +2441,25 @@ Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
return Error::success(); \
}
// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
// "guard-widening");
// The risk is that it may become obsolete if we're not careful.
#define LOOP_PASS(NAME, CREATE_PASS) \
if (Name == NAME) { \
FPM.addPass( \
createFunctionToLoopPassAdaptor(CREATE_PASS, false, DebugLogging)); \
return Error::success(); \
}
#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \
if (checkParametrizedPassName(Name, NAME)) { \
auto Params = parsePassParameters(PARSER, Name, NAME); \
if (!Params) \
return Params.takeError(); \
FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), \
false, DebugLogging)); \
return Error::success(); \
}
#include "PassRegistry.def"
for (auto &C : FunctionPipelineParsingCallbacks)

View File

@ -173,6 +173,37 @@
; CHECK-NESTED-FP-LP: Finished llvm::Function pass manager run
; CHECK-NESTED-FP-LP: Finished llvm::Module pass manager run
; RUN: opt -disable-output -debug-pass-manager \
; RUN: -passes='module(no-op-function,no-op-loop,no-op-cgscc,cgscc(no-op-function,no-op-loop),function(no-op-loop))' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-ADAPTORS
; CHECK-ADAPTORS: Starting llvm::Module pass manager run
; CHECK-ADAPTORS: Starting llvm::Module pass manager run
; CHECK-ADAPTORS: Running pass: ModuleToFunctionPassAdaptor<{{.*}}NoOpFunctionPass>
; CHECK-ADAPTORS: Running pass: ModuleToFunctionPassAdaptor<{{.*}}FunctionToLoopPassAdaptor<{{.*}}NoOpLoopPass>{{.*}}>
; CHECK-ADAPTORS: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}NoOpCGSCCPass>
; CHECK-ADAPTORS: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}>
; CHECK-ADAPTORS: Starting CGSCC pass manager run
; CHECK-ADAPTORS: Running pass: CGSCCToFunctionPassAdaptor<{{.*}}NoOpFunctionPass>
; CHECK-ADAPTORS: Running pass: CGSCCToFunctionPassAdaptor<{{.*}}FunctionToLoopPassAdaptor<{{.*}}NoOpLoopPass>{{.*}}>
; CHECK-ADAPTORS: Finished CGSCC pass manager run
; CHECK-ADAPTORS: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
; CHECK-ADAPTORS: Starting llvm::Function pass manager run
; CHECK-ADAPTORS: Running pass: FunctionToLoopPassAdaptor<{{.*}}NoOpLoopPass>
; CHECK-ADAPTORS: Finished llvm::Function pass manager run
; CHECK-ADAPTORS: Finished llvm::Module pass manager run
; CHECK-ADAPTORS: Finished llvm::Module pass manager run
; RUN: opt -disable-output -debug-pass-manager \
; RUN: -passes='cgscc(print)' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-PRINT-IN-CGSCC
; CHECK-PRINT-IN-CGSCC: Starting llvm::Module pass manager run
; CHECK-PRINT-IN-CGSCC: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}>
; CHECK-PRINT-IN-CGSCC: Starting CGSCC pass manager run
; CHECK-PRINT-IN-CGSCC: Running pass: CGSCCToFunctionPassAdaptor<{{.*}}PrintFunctionPass>
; CHECK-PRINT-IN-CGSCC: Finished CGSCC pass manager run
; CHECK-PRINT-IN-CGSCC: Running pass: VerifierPass
; CHECK-PRINT-IN-CGSCC: Finished llvm::Module pass manager run
; RUN: not opt -disable-output -debug-pass-manager \
; RUN: -passes='function(no-op-function)function(no-op-function)' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-MISSING-COMMA1