-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mlir] Add support for parsing nested PassPipelineOptions #101118
Conversation
@llvm/pr-subscribers-mlir @llvm/pr-subscribers-mlir-core Author: Nikhil Kalra (nikalra) Changes
Full diff: https://github.com/llvm/llvm-project/pull/101118.diff 4 Files Affected:
diff --git a/mlir/include/mlir/Pass/PassOptions.h b/mlir/include/mlir/Pass/PassOptions.h
index 6bffa84f7b16b..5b844f4a1cc12 100644
--- a/mlir/include/mlir/Pass/PassOptions.h
+++ b/mlir/include/mlir/Pass/PassOptions.h
@@ -139,6 +139,25 @@ class PassOptions : protected llvm::cl::SubCommand {
}
};
+ /// This is the parser that is used by pass options that wrap PassOptions
+ /// instances. Like GenericOptionParser, this is a thin wrapper around
+ /// llvm::cl::basic_parser.
+ template <typename PassOptionsT>
+ struct PassOptionsParser : public llvm::cl::basic_parser<PassOptionsT> {
+ using llvm::cl::basic_parser<PassOptionsT>::basic_parser;
+ // Parse the options object by delegating to
+ // `PassOptionsT::parseFromString`.
+ bool parse(llvm::cl::Option &, StringRef, StringRef arg,
+ PassOptionsT &value) {
+ return failed(value.parseFromString(arg));
+ }
+
+ // Print the options object by delegating to `PassOptionsT::print`.
+ static void print(llvm::raw_ostream &os, const PassOptionsT &value) {
+ value.print(os);
+ }
+ };
+
/// Utility methods for printing option values.
template <typename DataT>
static void printValue(raw_ostream &os, GenericOptionParser<DataT> &parser,
@@ -160,13 +179,19 @@ class PassOptions : protected llvm::cl::SubCommand {
/// TODO: We should upstream the methods in GenericOptionParser to avoid the
/// need to do this.
template <typename DataType>
- using OptionParser =
+ using OptionParser = std::conditional_t<
+ // If the data type is derived from PassOptions, use the
+ // PassOptionsParser.
+ std::is_base_of_v<PassOptions, DataType>, PassOptionsParser<DataType>,
+ // Otherwise, use GenericOptionParser where it is well formed, and fall
+ // back to llvm::cl::parser otherwise.
std::conditional_t<std::is_base_of<llvm::cl::generic_parser_base,
llvm::cl::parser<DataType>>::value,
GenericOptionParser<DataType>,
- llvm::cl::parser<DataType>>;
+ llvm::cl::parser<DataType>>>;
- /// This class represents a specific pass option, with a provided data type.
+ /// This class represents a specific pass option, with a provided
+ /// data type.
template <typename DataType, typename OptionParser = OptionParser<DataType>>
class Option
: public llvm::cl::opt<DataType, /*ExternalStorage=*/false, OptionParser>,
@@ -278,11 +303,12 @@ class PassOptions : protected llvm::cl::SubCommand {
if ((**this).empty())
return;
- os << this->ArgStr << '=';
+ os << this->ArgStr << "={";
auto printElementFn = [&](const DataType &value) {
printValue(os, this->getParser(), value);
};
llvm::interleave(*this, os, printElementFn, ",");
+ os << "}";
}
/// Copy the value from the given option into this one.
@@ -311,7 +337,7 @@ class PassOptions : protected llvm::cl::SubCommand {
/// Print the options held by this struct in a form that can be parsed via
/// 'parseFromString'.
- void print(raw_ostream &os);
+ void print(raw_ostream &os) const;
/// Print the help string for the options held by this struct. `descIndent` is
/// the indent that the descriptions should be aligned.
diff --git a/mlir/lib/Pass/PassRegistry.cpp b/mlir/lib/Pass/PassRegistry.cpp
index 483cbe80faba6..387c5340bcc8a 100644
--- a/mlir/lib/Pass/PassRegistry.cpp
+++ b/mlir/lib/Pass/PassRegistry.cpp
@@ -12,6 +12,7 @@
#include "mlir/Pass/PassManager.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -159,13 +160,36 @@ const PassPipelineInfo *mlir::PassPipelineInfo::lookup(StringRef pipelineArg) {
// PassOptions
//===----------------------------------------------------------------------===//
+/// Extract an argument from 'options' and update it to point after the arg.
+/// Returns the cleaned argument string.
+static StringRef extractArgAndUpdateOptions(StringRef &options,
+ size_t argSize) {
+ StringRef str = options.take_front(argSize).trim();
+ options = options.drop_front(argSize).ltrim();
+ // Handle escape sequences
+ if (str.size() > 2) {
+ const auto escapePairs = {std::make_pair('\'', '\''),
+ std::make_pair('"', '"'),
+ std::make_pair('{', '}')};
+ for (const auto &escape : escapePairs) {
+ if (str.front() == escape.first && str.back() == escape.second) {
+ // Drop the escape characters and trim.
+ str = str.drop_front().drop_back().trim();
+ // Don't process additional escape sequences.
+ break;
+ }
+ }
+ }
+ return str;
+}
+
LogicalResult detail::pass_options::parseCommaSeparatedList(
llvm::cl::Option &opt, StringRef argName, StringRef optionStr,
function_ref<LogicalResult(StringRef)> elementParseFn) {
// Functor used for finding a character in a string, and skipping over
// various "range" characters.
llvm::unique_function<size_t(StringRef, size_t, char)> findChar =
- [&](StringRef str, size_t index, char c) -> size_t {
+ [&findChar](StringRef str, size_t index, char c) -> size_t {
for (size_t i = index, e = str.size(); i < e; ++i) {
if (str[i] == c)
return i;
@@ -187,13 +211,15 @@ LogicalResult detail::pass_options::parseCommaSeparatedList(
size_t nextElePos = findChar(optionStr, 0, ',');
while (nextElePos != StringRef::npos) {
// Process the portion before the comma.
- if (failed(elementParseFn(optionStr.substr(0, nextElePos))))
+ if (failed(
+ elementParseFn(extractArgAndUpdateOptions(optionStr, nextElePos))))
return failure();
- optionStr = optionStr.substr(nextElePos + 1);
+ optionStr = optionStr.drop_front(); // drop the leading ','
nextElePos = findChar(optionStr, 0, ',');
}
- return elementParseFn(optionStr.substr(0, nextElePos));
+ return elementParseFn(
+ extractArgAndUpdateOptions(optionStr, optionStr.size()));
}
/// Out of line virtual function to provide home for the class.
@@ -213,27 +239,6 @@ void detail::PassOptions::copyOptionValuesFrom(const PassOptions &other) {
/// `options` string pointing after the parsed option].
static std::tuple<StringRef, StringRef, StringRef>
parseNextArg(StringRef options) {
- // Functor used to extract an argument from 'options' and update it to point
- // after the arg.
- auto extractArgAndUpdateOptions = [&](size_t argSize) {
- StringRef str = options.take_front(argSize).trim();
- options = options.drop_front(argSize).ltrim();
- // Handle escape sequences
- if (str.size() > 2) {
- const auto escapePairs = {std::make_pair('\'', '\''),
- std::make_pair('"', '"'),
- std::make_pair('{', '}')};
- for (const auto &escape : escapePairs) {
- if (str.front() == escape.first && str.back() == escape.second) {
- // Drop the escape characters and trim.
- str = str.drop_front().drop_back().trim();
- // Don't process additional escape sequences.
- break;
- }
- }
- }
- return str;
- };
// Try to process the given punctuation, properly escaping any contained
// characters.
auto tryProcessPunct = [&](size_t ¤tPos, char punct) {
@@ -250,13 +255,13 @@ parseNextArg(StringRef options) {
for (size_t argEndIt = 0, optionsE = options.size();; ++argEndIt) {
// Check for the end of the full option.
if (argEndIt == optionsE || options[argEndIt] == ' ') {
- argName = extractArgAndUpdateOptions(argEndIt);
+ argName = extractArgAndUpdateOptions(options, argEndIt);
return std::make_tuple(argName, StringRef(), options);
}
// Check for the end of the name and the start of the value.
if (options[argEndIt] == '=') {
- argName = extractArgAndUpdateOptions(argEndIt);
+ argName = extractArgAndUpdateOptions(options, argEndIt);
options = options.drop_front();
break;
}
@@ -266,7 +271,7 @@ parseNextArg(StringRef options) {
for (size_t argEndIt = 0, optionsE = options.size();; ++argEndIt) {
// Handle the end of the options string.
if (argEndIt == optionsE || options[argEndIt] == ' ') {
- StringRef value = extractArgAndUpdateOptions(argEndIt);
+ StringRef value = extractArgAndUpdateOptions(options, argEndIt);
return std::make_tuple(argName, value, options);
}
@@ -318,7 +323,7 @@ LogicalResult detail::PassOptions::parseFromString(StringRef options,
/// Print the options held by this struct in a form that can be parsed via
/// 'parseFromString'.
-void detail::PassOptions::print(raw_ostream &os) {
+void detail::PassOptions::print(raw_ostream &os) const {
// If there are no options, there is nothing left to do.
if (OptionsMap.empty())
return;
diff --git a/mlir/test/Pass/pipeline-options-parsing.mlir b/mlir/test/Pass/pipeline-options-parsing.mlir
index 50f08241ee5cf..b6c2b688b7cfb 100644
--- a/mlir/test/Pass/pipeline-options-parsing.mlir
+++ b/mlir/test/Pass/pipeline-options-parsing.mlir
@@ -11,6 +11,8 @@
// RUN: mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(builtin.module(func.func(test-options-pass{list=3}), func.func(test-options-pass{enum=one list=1,2,3,4 string="foo bar baz"})))' -dump-pass-pipeline 2>&1 | FileCheck --check-prefix=CHECK_5 %s
// RUN: mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(builtin.module(func.func(test-options-pass{list=3}), func.func(test-options-pass{enum=one list=1,2,3,4 string={foo bar baz}})))' -dump-pass-pipeline 2>&1 | FileCheck --check-prefix=CHECK_5 %s
// RUN: mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(builtin.module(func.func(test-options-pass{list=3}), func.func(test-options-pass{enum=one list=1,2,3,4 string=foo"bar"baz})))' -dump-pass-pipeline 2>&1 | FileCheck --check-prefix=CHECK_6 %s
+// RUN: mlir-opt %s -verify-each=false '-test-options-super-pass-pipeline=super-list={{enum=zero list=1 string=foo},{enum=one list=2 string="bar"},{enum=two list=3 string={baz}}}' -dump-pass-pipeline 2>&1 | FileCheck --check-prefix=CHECK_7 %s
+// RUN: mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(func.func(test-options-super-pass{list={{enum=zero list={1} string=foo },{enum=one list={2} string=bar },{enum=two list={3} string=baz }}}))' -dump-pass-pipeline 2>&1 | FileCheck --check-prefix=CHECK_7 %s
// CHECK_ERROR_1: missing closing '}' while processing pass options
// CHECK_ERROR_2: no such option test-option
@@ -18,9 +20,10 @@
// CHECK_ERROR_4: 'notaninteger' value invalid for integer argument
// CHECK_ERROR_5: for the --enum option: Cannot find option named 'invalid'!
-// CHECK_1: test-options-pass{enum=zero list=1,2,3,4,5 string=nested_pipeline{arg1=10 arg2=" {} " arg3=true} string-list=a,b,c,d}
-// CHECK_2: test-options-pass{enum=one list=1 string= string-list=a,b}
-// CHECK_3: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list=3 string= }),func.func(test-options-pass{enum=one list=1,2,3,4 string= })))
-// CHECK_4: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list=3 string= }),func.func(test-options-pass{enum=one list=1,2,3,4 string=foobar })))
-// CHECK_5: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list=3 string= }),func.func(test-options-pass{enum=one list=1,2,3,4 string={foo bar baz} })))
-// CHECK_6: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list=3 string= }),func.func(test-options-pass{enum=one list=1,2,3,4 string=foo"bar"baz })))
+// CHECK_1: test-options-pass{enum=zero list={1,2,3,4,5} string=nested_pipeline{arg1=10 arg2=" {} " arg3=true} string-list={a,b,c,d}}
+// CHECK_2: test-options-pass{enum=one list={1} string= string-list={a,b}}
+// CHECK_3: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list={3} string= }),func.func(test-options-pass{enum=one list={1,2,3,4} string= })))
+// CHECK_4: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list={3} string= }),func.func(test-options-pass{enum=one list={1,2,3,4} string=foobar })))
+// CHECK_5: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list={3} string= }),func.func(test-options-pass{enum=one list={1,2,3,4} string={foo bar baz} })))
+// CHECK_6: builtin.module(builtin.module(func.func(test-options-pass{enum=zero list={3} string= }),func.func(test-options-pass{enum=one list={1,2,3,4} string=foo"bar"baz })))
+// CHECK_7{LITERAL}: builtin.module(func.func(test-options-super-pass{list={{enum=zero list={1} string=foo },{enum=one list={2} string=bar },{enum=two list={3} string=baz }}}))
diff --git a/mlir/test/lib/Pass/TestPassManager.cpp b/mlir/test/lib/Pass/TestPassManager.cpp
index 2762e25490324..ee32bec0c79bd 100644
--- a/mlir/test/lib/Pass/TestPassManager.cpp
+++ b/mlir/test/lib/Pass/TestPassManager.cpp
@@ -54,7 +54,7 @@ struct TestOptionsPass
: public PassWrapper<TestOptionsPass, OperationPass<func::FuncOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestOptionsPass)
- enum Enum { One, Two };
+ enum Enum { Zero, One, Two };
struct Options : public PassPipelineOptions<Options> {
ListOption<int> listOption{*this, "list",
@@ -66,7 +66,15 @@ struct TestOptionsPass
Option<Enum> enumOption{
*this, "enum", llvm::cl::desc("Example enum option"),
llvm::cl::values(clEnumValN(0, "zero", "Example zero value"),
- clEnumValN(1, "one", "Example one value"))};
+ clEnumValN(1, "one", "Example one value"),
+ clEnumValN(2, "two", "Example two value"))};
+
+ Options() = default;
+ Options(const Options &rhs) { *this = rhs; }
+ Options &operator=(const Options &rhs) {
+ copyOptionValuesFrom(rhs);
+ return *this;
+ }
};
TestOptionsPass() = default;
TestOptionsPass(const TestOptionsPass &) : PassWrapper() {}
@@ -92,7 +100,37 @@ struct TestOptionsPass
Option<Enum> enumOption{
*this, "enum", llvm::cl::desc("Example enum option"),
llvm::cl::values(clEnumValN(0, "zero", "Example zero value"),
- clEnumValN(1, "one", "Example one value"))};
+ clEnumValN(1, "one", "Example one value"),
+ clEnumValN(2, "two", "Example two value"))};
+};
+
+struct TestOptionsSuperPass
+ : public PassWrapper<TestOptionsSuperPass, OperationPass<func::FuncOp>> {
+ MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestOptionsSuperPass)
+
+ struct Options : public PassPipelineOptions<Options> {
+ ListOption<TestOptionsPass::Options> listOption{
+ *this, "super-list",
+ llvm::cl::desc("Example list of PassPipelineOptions option")};
+
+ Options() = default;
+ };
+
+ TestOptionsSuperPass() = default;
+ TestOptionsSuperPass(const TestOptionsSuperPass &) : PassWrapper() {}
+ TestOptionsSuperPass(const Options &options) {
+ listOption = options.listOption;
+ }
+
+ void runOnOperation() final {}
+ StringRef getArgument() const final { return "test-options-super-pass"; }
+ StringRef getDescription() const final {
+ return "Test options of options parsing capabilities";
+ }
+
+ ListOption<TestOptionsPass::Options> listOption{
+ *this, "list",
+ llvm::cl::desc("Example list of PassPipelineOptions option")};
};
/// A test pass that always aborts to enable testing the crash recovery
@@ -220,6 +258,7 @@ static void testNestedPipelineTextual(OpPassManager &pm) {
namespace mlir {
void registerPassManagerTestPass() {
PassRegistration<TestOptionsPass>();
+ PassRegistration<TestOptionsSuperPass>();
PassRegistration<TestModulePass>();
@@ -248,5 +287,14 @@ void registerPassManagerTestPass() {
[](OpPassManager &pm, const TestOptionsPass::Options &options) {
pm.addPass(std::make_unique<TestOptionsPass>(options));
});
+
+ PassPipelineRegistration<TestOptionsSuperPass::Options>
+ registerOptionsSuperPassPipeline(
+ "test-options-super-pass-pipeline",
+ "Parses options of PassPipelineOptions using pass pipeline "
+ "registration",
+ [](OpPassManager &pm, const TestOptionsSuperPass::Options &options) {
+ pm.addPass(std::make_unique<TestOptionsSuperPass>(options));
+ });
}
} // namespace mlir
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, thanks!
mlir/lib/Pass/PassRegistry.cpp
Outdated
LogicalResult detail::pass_options::parseCommaSeparatedList( | ||
llvm::cl::Option &opt, StringRef argName, StringRef optionStr, | ||
function_ref<LogicalResult(StringRef)> elementParseFn) { | ||
// Functor used for finding a character in a string, and skipping over | ||
// various "range" characters. | ||
llvm::unique_function<size_t(StringRef, size_t, char)> findChar = | ||
[&](StringRef str, size_t index, char c) -> size_t { | ||
[&findChar](StringRef str, size_t index, char c) -> size_t { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted -- I spent a couple of minutes re-reading this lambda to convince myself it didn't implicitly capture/modify anything, but it doesn't impact this change so I'll change it back.
Options(const Options &rhs) { *this = rhs; } | ||
Options &operator=(const Options &rhs) { | ||
copyOptionValuesFrom(rhs); | ||
return *this; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add these to the PassPipelineOptions base class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ListOption has an implicitly deleted copy constructor so we're forced to add this boilerplate to the derived classes.
@River707 Once everything looks good to you, would you mind merging this PR in? I don't have merge permissions for the LLVM repo. |
* 'main' of https://github.com/llvm/llvm-project: (700 commits) [SandboxIR][NFC] SingleLLVMInstructionImpl class (llvm#102687) [ThinLTO]Clean up 'import-assume-unique-local' flag. (llvm#102424) [nsan] Make #include more conventional [SandboxIR][NFC] Use Tracker.emplaceIfTracking() [libc] Moved range_reduction_double ifdef statement (llvm#102659) [libc] Fix CFP long double and add tests (llvm#102660) [TargetLowering] Handle vector types in expandFixedPointMul (llvm#102635) [compiler-rt][NFC] Replace environment variable with %t (llvm#102197) [UnitTests] Convert a test to use opaque pointers (llvm#102668) [CodeGen][NFCI] Don't re-implement parts of ASTContext::getIntWidth (llvm#101765) [SandboxIR] Clean up tracking code with the help of emplaceIfTracking() (llvm#102406) [mlir][bazel] remove extra blanks in mlir-tblgen test [NVPTX][NFC] Update tests to use bfloat type (llvm#101493) [mlir] Add support for parsing nested PassPipelineOptions (llvm#101118) [mlir][bazel] add missing td dependency in mlir-tblgen test [flang][cuda] Fix lib dependency [libc] Clean up remaining use of *_WIDTH macros in printf (llvm#102679) [flang][cuda] Convert cuf.alloc for box to fir.alloca in device context (llvm#102662) [SandboxIR] Implement the InsertElementInst class (llvm#102404) [libc] Fix use of cpp::numeric_limits<...>::digits (llvm#102674) [mlir][ODS] Verify type constraints in Types and Attributes (llvm#102326) [LTO] enable `ObjCARCContractPass` only on optimized build (llvm#101114) [mlir][ODS] Consistent `cppType` / `cppClassName` usage (llvm#102657) [lldb] Move definition of SBSaveCoreOptions dtor out of header (llvm#102539) [libc] Use cpp::numeric_limits in preference to C23 <limits.h> macros (llvm#102665) [clang] Implement -fptrauth-auth-traps. (llvm#102417) [LLVM][rtsan] rtsan transform to preserve CFGAnalyses (llvm#102651) Revert "[AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)" [RISCV][GISel] Add missing tests for G_CTLZ/CTTZ instruction selection. NFC Return available function types for BindingDecls. (llvm#102196) [clang] Wire -fptrauth-returns to "ptrauth-returns" fn attribute. (llvm#102416) [RISCV] Remove riscv-experimental-rv64-legal-i32. (llvm#102509) [RISCV] Move PseudoVSET(I)VLI expansion to use PseudoInstExpansion. (llvm#102496) [NVPTX] support switch statement with brx.idx (reland) (llvm#102550) [libc][newhdrgen]sorted function names in yaml (llvm#102544) [GlobalIsel] Combine G_ADD and G_SUB with constants (llvm#97771) Suppress spurious warnings due to R_RISCV_SET_ULEB128 [scudo] Separated committed and decommitted entries. (llvm#101409) [MIPS] Fix missing ANDI optimization (llvm#97689) [Clang] Add env var for nvptx-arch/amdgpu-arch timeout (llvm#102521) [asan] Switch allocator to dynamic base address (llvm#98511) [AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086) [libc][math][c23] Add fadd{l,f128} C23 math functions (llvm#102531) [mlir][bazel] revert bazel rule change for DLTITransformOps [msan] Support vst{2,3,4}_lane instructions (llvm#101215) Revert "[MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)" [X86] pr57673.ll - generate MIR test checks [mlir][vector][test] Split tests from vector-transfer-flatten.mlir (llvm#102584) [mlir][bazel] add bazel rule for DLTITransformOps OpenMPOpt: Remove dead include [IR] Add method to GlobalVariable to change type of initializer. (llvm#102553) [flang][cuda] Force default allocator in device code (llvm#102238) [llvm] Construct SmallVector<SDValue> with ArrayRef (NFC) (llvm#102578) [MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561) [AMDGPU][AsmParser][NFC] Remove a misleading comment. (llvm#102604) [Arm][AArch64][Clang] Respect function's branch protection attributes. (llvm#101978) [mlir] Verifier: steal bit to track seen instead of set. (llvm#102626) [Clang] Fix Handling of Init Capture with Parameter Packs in LambdaScopeForCallOperatorInstantiationRAII (llvm#100766) [X86] Convert truncsat clamping patterns to use SDPatternMatch. NFC. [gn] Give two scripts argparse.RawDescriptionHelpFormatter [bazel] Add missing dep for the SPIRVToLLVM target [Clang] Simplify specifying passes via -Xoffload-linker (llvm#102483) [bazel] Port for d45de80 [SelectionDAG] Use unaligned store/load to move AVX registers onto stack for `insertelement` (llvm#82130) [Clang][OMPX] Add the code generation for multi-dim `num_teams` (llvm#101407) [ARM] Regenerate big-endian-vmov.ll. NFC [AMDGPU][AsmParser][NFCI] All NamedIntOperands to be of the i32 type. (llvm#102616) [libc][math][c23] Add totalorderl function. (llvm#102564) [mlir][spirv] Support `memref` in `convert-to-spirv` pass (llvm#102534) [MLIR][GPU-LLVM] Convert `gpu.func` to `llvm.func` (llvm#101664) Fix a unit test input file (llvm#102567) [llvm-readobj][COFF] Dump hybrid objects for ARM64X files. (llvm#102245) AMDGPU/NewPM: Port SIFixSGPRCopies to new pass manager (llvm#102614) [MemoryBuiltins] Simplify getCalledFunction() helper (NFC) [AArch64] Add invalid 1 x vscale costs for reductions and reduction-operations. (llvm#102105) [MemoryBuiltins] Handle allocator attributes on call-site LSV/test/AArch64: add missing lit.local.cfg; fix build (llvm#102607) Revert "Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)" [RISCV] Add Syntacore SCR5 RV32/64 processors definition (llvm#102285) [InstCombine] Remove unnecessary RUN line from test (NFC) [flang][OpenMP] Handle multiple ranges in `num_teams` clause (llvm#102535) [mlir][vector] Add tests for scalable vectors in one-shot-bufferize.mlir (llvm#102361) [mlir][vector] Disable `vector.matrix_multiply` for scalable vectors (llvm#102573) [clang] Implement CWG2627 Bit-fields and narrowing conversions (llvm#78112) [NFC] Use references to avoid copying (llvm#99863) Revert "[mlir][ArmSME] Pattern to swap shape_cast(tranpose) with transpose(shape_cast) (llvm#100731)" (llvm#102457) [IRBuilder] Generate nuw GEPs for struct member accesses (llvm#99538) [bazel] Port for 9b06e25 [CodeGen][NewPM] Improve start/stop pass error message CodeGenPassBuilder (llvm#102591) [AArch64] Implement TRBMPAM_EL1 system register (llvm#102485) [InstCombine] Fixing wrong select folding in vectors with undef elements (llvm#102244) [AArch64] Sink operands to fmuladd. (llvm#102297) LSV: document hang reported in llvm#37865 (llvm#102479) Enable logf128 constant folding for hosts with 128bit floats (llvm#96287) [RISCV][clang] Remove bfloat base type in non-zvfbfmin vcreate (llvm#102146) [RISCV][clang] Add missing `zvfbfmin` to `vget_v` intrinsic (llvm#102149) [mlir][vector] Add mask elimination transform (llvm#99314) [Clang][Interp] Fix display of syntactically-invalid note for member function calls (llvm#102170) [bazel] Port for 3fffa6d [DebugInfo][RemoveDIs] Use iterator-inserters in clang (llvm#102006) ... Signed-off-by: Edwiin Kusuma Jaya <kutemeikito0905@gmail.com>
This commit makes the following changes: 1. Previously certain pipeline options could cause the options parser to get stuck in an an infinite loop. An example is: ``` mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(func.func(test-options-super-pass{list={list=1,2},{list=3,4}}))'' ``` In this example, the 'list' option of the `test-options-super-pass` is itself a pass options specification (this capability was added in llvm#101118). However, while the textual format allows `ListOption<int>` to be given as `list=1,2,3`, it did not allow the same format for `ListOption<T>` when T is a subclass of `PassOptions` without extra enclosing `{....}`. Lack of enclosing `{...}` would cause the infinite looping in the parser. This change resolves the parser bug and also allows omitting the outer `{...}` for `ListOption`-of-options. 2. Previously, if you specified a default list value for your `ListOption`, e.g. `ListOption<int> opt{*this, "list", llvm::list_init({1,2,3})}`, it would be impossible to override that default value of `{1,2,3}` with an *empty* list on the command line, since `my-pass{list=}` was not allowed. This was not allowed because of ambiguous handling of lists-of-strings (no literal marker is currently required). This updates this behvior so that specifying empty lists (either `list={}` or just `list=` is allowed.
This commit makes the following changes: 1. Previously certain pipeline options could cause the options parser to get stuck in an an infinite loop. An example is: ``` mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(func.func(test-options-super-pass{list={list=1,2},{list=3,4}}))'' ``` In this example, the 'list' option of the `test-options-super-pass` is itself a pass options specification (this capability was added in llvm#101118). However, while the textual format allows `ListOption<int>` to be given as `list=1,2,3`, it did not allow the same format for `ListOption<T>` when T is a subclass of `PassOptions` without extra enclosing `{....}`. Lack of enclosing `{...}` would cause the infinite looping in the parser. This change resolves the parser bug and also allows omitting the outer `{...}` for `ListOption`-of-options. 2. Previously, if you specified a default list value for your `ListOption`, e.g. `ListOption<int> opt{*this, "list", llvm::list_init({1,2,3})}`, it would be impossible to override that default value of `{1,2,3}` with an *empty* list on the command line, since `my-pass{list=}` was not allowed. This was not allowed because of ambiguous handling of lists-of-strings (no literal marker is currently required). This change makes it explicit in the ListOption construction that we would like to treat all ListOption as having a default value of "empty" unless otherwise specified (e.g. using `llvm::list_init`). It removes the requirement that lists are not printed if empty. Instead, lists are not printed if they do not have their default value. It is now clarified that the textual format `my-pass{string-list=""}` or `my-pass{string-list={}}` is interpreted as "empty list". This makes it imposssible to specify that ListOption `string-list` should be a size-1 list containing the empty string. However, `my-pass{string-list={"",""}}` *does* specify a size-2 list containing the empty string. This behavior seems preferable to allow for overriding non-empty defaults as described above.
This commit makes the following changes: 1. Previously certain pipeline options could cause the options parser to get stuck in an an infinite loop. An example is: ``` mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(func.func(test-options-super-pass{list={list=1,2},{list=3,4}}))'' ``` In this example, the 'list' option of the `test-options-super-pass` is itself a pass options specification (this capability was added in llvm#101118). However, while the textual format allows `ListOption<int>` to be given as `list=1,2,3`, it did not allow the same format for `ListOption<T>` when T is a subclass of `PassOptions` without extra enclosing `{....}`. Lack of enclosing `{...}` would cause the infinite looping in the parser. This change resolves the parser bug and also allows omitting the outer `{...}` for `ListOption`-of-options. 2. Previously, if you specified a default list value for your `ListOption`, e.g. `ListOption<int> opt{*this, "list", llvm::list_init({1,2,3})}`, it would be impossible to override that default value of `{1,2,3}` with an *empty* list on the command line, since `my-pass{list=}` was not allowed. This was not allowed because of ambiguous handling of lists-of-strings (no literal marker is currently required). This change makes it explicit in the ListOption construction that we would like to treat all ListOption as having a default value of "empty" unless otherwise specified (e.g. using `llvm::list_init`). It removes the requirement that lists are not printed if empty. Instead, lists are not printed if they do not have their default value. It is now clarified that the textual format `my-pass{string-list=""}` or `my-pass{string-list={}}` is interpreted as "empty list". This makes it imposssible to specify that ListOption `string-list` should be a size-1 list containing the empty string. However, `my-pass{string-list={"",""}}` *does* specify a size-2 list containing the empty string. This behavior seems preferable to allow for overriding non-empty defaults as described above.
…118877) This commit makes the following changes: 1. Previously certain pipeline options could cause the options parser to get stuck in an an infinite loop. An example is: ``` mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(func.func(test-options-super-pass{list={list=1,2},{list=3,4}}))'' ``` In this example, the 'list' option of the `test-options-super-pass` is itself a pass options specification (this capability was added in #101118). However, while the textual format allows `ListOption<int>` to be given as `list=1,2,3`, it did not allow the same format for `ListOption<T>` when T is a subclass of `PassOptions` without extra enclosing `{....}`. Lack of enclosing `{...}` would cause the infinite looping in the parser. This change resolves the parser bug and also allows omitting the outer `{...}` for `ListOption`-of-options. 2. Previously, if you specified a default list value for your `ListOption`, e.g. `ListOption<int> opt{*this, "list", llvm::cl::list_init({1,2,3})}`, it would be impossible to override that default value of `{1,2,3}` with an *empty* list on the command line, since `my-pass{list=}` was not allowed. This was not allowed because of ambiguous handling of lists-of-strings (no literal marker is currently required). This change makes it explicit in the ListOption construction that we would like to treat all ListOption as having a default value of "empty" unless otherwise specified (e.g. using `llvm::list_init`). It removes the requirement that lists are not printed if empty. Instead, lists are not printed if they do not have their default value. It is now clarified that the textual format `my-pass{string-list=""}` or `my-pass{string-list={}}` is interpreted as "empty list". This makes it imposssible to specify that ListOption `string-list` should be a size-1 list containing the empty string. However, `my-pass{string-list={"",""}}` *does* specify a size-2 list containing the empty string. This behavior seems preferable to allow for overriding non-empty defaults as described above.
…al format (#118877) This commit makes the following changes: 1. Previously certain pipeline options could cause the options parser to get stuck in an an infinite loop. An example is: ``` mlir-opt %s -verify-each=false -pass-pipeline='builtin.module(func.func(test-options-super-pass{list={list=1,2},{list=3,4}}))'' ``` In this example, the 'list' option of the `test-options-super-pass` is itself a pass options specification (this capability was added in llvm/llvm-project#101118). However, while the textual format allows `ListOption<int>` to be given as `list=1,2,3`, it did not allow the same format for `ListOption<T>` when T is a subclass of `PassOptions` without extra enclosing `{....}`. Lack of enclosing `{...}` would cause the infinite looping in the parser. This change resolves the parser bug and also allows omitting the outer `{...}` for `ListOption`-of-options. 2. Previously, if you specified a default list value for your `ListOption`, e.g. `ListOption<int> opt{*this, "list", llvm::cl::list_init({1,2,3})}`, it would be impossible to override that default value of `{1,2,3}` with an *empty* list on the command line, since `my-pass{list=}` was not allowed. This was not allowed because of ambiguous handling of lists-of-strings (no literal marker is currently required). This change makes it explicit in the ListOption construction that we would like to treat all ListOption as having a default value of "empty" unless otherwise specified (e.g. using `llvm::list_init`). It removes the requirement that lists are not printed if empty. Instead, lists are not printed if they do not have their default value. It is now clarified that the textual format `my-pass{string-list=""}` or `my-pass{string-list={}}` is interpreted as "empty list". This makes it imposssible to specify that ListOption `string-list` should be a size-1 list containing the empty string. However, `my-pass{string-list={"",""}}` *does* specify a size-2 list containing the empty string. This behavior seems preferable to allow for overriding non-empty defaults as described above.
PassOptions
to allowOption
/ListOption
to wrap PassOption objects. This is helpful when creating meta-pipelines (pass pipelines composed of pass pipelines).ListOption
printing to enable round-tripping the output ofdump-pass-pipeline
back intomlir-opt
for more complex structures.