diff options
author | Fedor Sergeev <fedor.sergeev@azul.com> | 2019-01-10 10:01:53 +0000 |
---|---|---|
committer | Fedor Sergeev <fedor.sergeev@azul.com> | 2019-01-10 10:01:53 +0000 |
commit | b7871405fa91a752ca65df572d2d0a435a9993e1 (patch) | |
tree | b6885a2415b42a8dd4aa45a36f0095cf416bb929 | |
parent | 15313a3705a1f4ea2629689e4e3d4539d860179f (diff) | |
download | bcm5719-llvm-b7871405fa91a752ca65df572d2d0a435a9993e1.tar.gz bcm5719-llvm-b7871405fa91a752ca65df572d2d0a435a9993e1.zip |
[LoopUnroll] add parsing for unroll parameters in -passes pipeline
Allow to specify loop-unrolling with optional parameters explicitly
spelled out in -passes pipeline specification.
Introducing somewhat generic way of specifying parameters parsing via
FUNCTION_PASS_PARAMETRIZED pass registration.
Syntax of parametrized unroll pass name is as follows:
'unroll<' parameter-list '>'
Where parameter-list is ';'-separate list of parameter names and optlevel
optlevel: 'O[0-3]'
parameter: { 'partial' | 'peeling' | 'runtime' | 'upperbound' }
negated: 'no-' parameter
Example:
-passes=loop(unroll<O3;runtime;no-upperbound>)
this invokes LoopUnrollPass configured with OptLevel=3,
Runtime, no UpperBound, everything else by default.
llvm-svn: 350808
-rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 96 | ||||
-rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 10 |
2 files changed, 104 insertions, 2 deletions
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index e1d0a47fb6d..576393533aa 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1242,6 +1242,91 @@ static Optional<int> parseDevirtPassName(StringRef Name) { return Count; } +static bool checkParametrizedPassName(StringRef Name, StringRef PassName) { + if (!Name.consume_front(PassName)) + return false; + // normal pass name w/o parameters == default parameters + if (Name.empty()) + return true; + return Name.startswith("<") && Name.endswith(">"); +} + +namespace { + +/// This performs customized parsing of pass name with parameters. +/// +/// We do not need parametrization of passes in textual pipeline very often, +/// yet on a rare occasion ability to specify parameters right there can be +/// useful. +/// +/// \p Name - parameterized specification of a pass from a textual pipeline +/// is a string in a form of : +/// PassName '<' parameter-list '>' +/// +/// Parameter list is being parsed by the parser callable argument, \p Parser, +/// It takes a string-ref of parameters and returns either StringError or a +/// parameter list in a form of a custom parameters type, all wrapped into +/// Expected<> template class. +/// +template <typename ParametersParseCallableT> +auto parsePassParameters(ParametersParseCallableT &&Parser, StringRef Name, + StringRef PassName) -> decltype(Parser(StringRef{})) { + using ParametersT = typename decltype(Parser(StringRef{}))::value_type; + + StringRef Params = Name; + if (!Params.consume_front(PassName)) { + assert(false && + "unable to strip pass name from parametrized pass specification"); + } + if (Params.empty()) + return ParametersT{}; + if (!Params.consume_front("<") || !Params.consume_back(">")) { + assert(false && "invalid format for parametrized pass name"); + } + + Expected<ParametersT> Result = Parser(Params); + assert((Result || Result.template errorIsA<StringError>()) && + "Pass parameter parser can only return StringErrors."); + return std::move(Result); +} + +/// Parser of parameters for LoopUnroll pass. +Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) { + LoopUnrollOptions UnrollOpts; + while (!Params.empty()) { + StringRef ParamName; + std::tie(ParamName, Params) = Params.split(';'); + int OptLevel = StringSwitch<int>(ParamName) + .Case("O0", 0) + .Case("O1", 1) + .Case("O2", 2) + .Case("O3", 3) + .Default(-1); + if (OptLevel >= 0) { + UnrollOpts.setOptLevel(OptLevel); + continue; + } + + bool Enable = !ParamName.consume_front("no-"); + if (ParamName == "partial") { + UnrollOpts.setPartial(Enable); + } else if (ParamName == "peeling") { + UnrollOpts.setPeeling(Enable); + } else if (ParamName == "runtime") { + UnrollOpts.setRuntime(Enable); + } else if (ParamName == "upperbound") { + UnrollOpts.setUpperBound(Enable); + } else { + return make_error<StringError>( + formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(), + inconvertibleErrorCode()); + } + } + return UnrollOpts; +} + +} // namespace + /// Tests whether a pass name starts with a valid prefix for a default pipeline /// alias. static bool startsWithDefaultPipelineAliasPrefix(StringRef Name) { @@ -1337,6 +1422,9 @@ static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) { #define FUNCTION_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; +#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ + if (checkParametrizedPassName(Name, NAME)) \ + return true; #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ return true; @@ -1674,6 +1762,14 @@ Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM, FPM.addPass(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(); \ + FPM.addPass(CREATE_PASS(Params.get())); \ + return Error::success(); \ + } #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">") { \ FPM.addPass( \ diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index a8c03ad0596..209a8811c10 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -223,8 +223,6 @@ FUNCTION_PASS("spec-phis", SpeculateAroundPHIsPass()) FUNCTION_PASS("sroa", SROA()) FUNCTION_PASS("tailcallelim", TailCallElimPass()) FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass()) -FUNCTION_PASS("unroll", LoopUnrollPass()) -FUNCTION_PASS("unroll<peeling;no-runtime>",LoopUnrollPass(LoopUnrollOptions().setPeeling(true).setRuntime(false))) FUNCTION_PASS("verify", VerifierPass()) FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass()) FUNCTION_PASS("verify<loops>", LoopVerifierPass()) @@ -236,6 +234,14 @@ FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass()) FUNCTION_PASS("msan", MemorySanitizerPass()) #undef FUNCTION_PASS +#ifndef FUNCTION_PASS_WITH_PARAMS +#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) +#endif +FUNCTION_PASS_WITH_PARAMS("unroll", + [](LoopUnrollOptions Opts) { return LoopUnrollPass(Opts); }, + parseLoopUnrollOptions) +#undef FUNCTION_PASS_WITH_PARAMS + #ifndef LOOP_ANALYSIS #define LOOP_ANALYSIS(NAME, CREATE_PASS) #endif |