The pass tablegen backend has been reworked to remove the monolithic nature of the autogenerated declarations.
The pass public header can be generated with the -gen-pass-decls option. It contains options structs and registrations: the inclusion of options structs can be controlled individually for each pass by defining the GEN_PASS_DECL_PASSNAME macro; the declaration of the registrations have been kept together and can still be included by defining the GEN_PASS_REGISTRATION macro.
The private code used for the pass implementation (i.e. the pass base class and the constructors definitions, if missing from tablegen) can be generated with the -gen-pass-defs option. Similarly to the declarations file, the definitions of each pass can be enabled by defining the GEN_PASS_DEF_PASNAME variable.
While doing so, the pass base class has been enriched to also accept a the aformentioned struct of options and copy them to the actual pass options, thus allowing each pass to also be configurable within C++ and not only through command line.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
314 | Accessing the options class will be awkward because the base class takes a template parameter. |
Thanks, tou need to add a few tests now :)
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
87 | When removing this I can't tell what you're making public right now. |
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
87 | That has been moved in the "code generating" emitPassDecl method. The code that was generated after that protected keyword is still protected. The Options struct and the constructor, however, needs to be public and thus the "removal". | |
314 | What do you mean with awkward? |
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
314 | Oh sorry, realized later: you would need to write something like MyPassBase<MyPassImpl>::Options. Having not written a test didn't show me this problem. I will think about it (any suggestion is welcome) |
I’ve made few changes:
- Moved the options struct outside the pass class. I would have gone for the “PassNameOptions” name, but this was creating some issues with other existing passes such as LinalgTiling for which a LinalgTilingOptions already exists. I don’t have enough knowledge and time to adapt all the passes, thus I have opted to go for the “PassNameBaseOptions” name. When all the passes will switch to the tablegen-defined options, then the name can be changed.
- Restored the protected keyword. With the new design it can stay in the template string.
- Added a test to check the options forwarding.
The generation of the options structure has been separated from the generation of the pass classes. An additional compile-tme definition GEN_PASS_OPTIONS has been introduced to
include such structs. The rationale behind this choice is the need of including the options structures in the top-level Conversion/Passes.h, thus allowing them to be used
from outside the pass implementations (i.e. by users wanting to customize the behaviour of the pass).
In case no option exists for a pass, the struct is not generated (it would be empty).
The existing conversion passes have also been adapted to work with this modified infrastructure.
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) | How does one get the definition for this? |
mlir/include/mlir/Conversion/GPUToNVVM/GPUToNVVMPass.h | ||
41–45 ↗ | (On Diff #452662) | I think the comment is still relevant though |
mlir/include/mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h | ||
28–29 ↗ | (On Diff #452662) | The last two lines are irrelevant to this constructor. |
mlir/lib/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRVPass.cpp | ||
30 ↗ | (On Diff #452662) | Isn't using ConvertControlFlowToSPIRVBase::ConvertControlFlowToSPIRVBase; enough here to inherit the constructors? |
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) | The definition is inside the autogenerated Passes.h.inc, and is wrapped by an #ifdef PASS_GEN_OPTIONS. I don't know if this is the best design, but that's the only coming to my mind. I would apreciate some opinions about this. |
mlir/include/mlir/Conversion/GPUToNVVM/GPUToNVVMPass.h | ||
41–45 ↗ | (On Diff #452662) | The Passes.td file already has a description for the index option. Imho keeping the comment would be incomplete wrt the other options. |
mlir/include/mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h | ||
28–29 ↗ | (On Diff #452662) | NIce catch, thanks. I will remove them. |
mlir/lib/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRVPass.cpp | ||
30 ↗ | (On Diff #452662) | Also another nice suggestion :) I will fix this together with all the other constructors. |
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) |
Right, but my question is more immediate: what header should someone interested in creating the ConvertControlFlowToLLVMPass with some options use to be able to set these options? |
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) | mlir/Conversion/Passes.h. That header has the GEN_PASS_OPTIONS define and the Passes.h.inc inclusion, and thus the definitions of the option structures. The weird thing to my eyes is that I have to include the top level header (and not, for example, the ConvertControlFLowToLLVM.h one), and this is where I would like opinions |
I also see that these changes break flang. Maybe we should temporarily add an option inside the pass tablegen, in order to enable the structs generation, and just tell people to start adapting to this?
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) | Right, I think this is a more profound issue, I think we should change the way we handle passes to be able to have one header per pass, and kill entirely the mlir/Conversion/Passes.h style (other than for the global registration entry point). That is I could see: #define GEN_PASS_DECL_ConvertControlFlowToLLVMPass And: #define GEN_PASS_DEF_ConvertControlFlowToLLVMPass Which would generate not only the pass options but also the declaration and definition for the createConvertControlFlowToLLVMPass entirely. |
In general I rather have the "right" default and provide an opt-out flag: that let people adapt to it but when they opt out they at least do so conscientiously and can add a "todo" and/or a tracking bug for upgrading.
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) | You may not believe it, but I thought about generating that specialized define for just options and I stopped because I considered it a bit ugly for users. Glad we both arrived to the same solution :). I will give a try asap and report back. |
I agree about that, but in this case I would have to modify the whole flang project to usethat opt-out flag. At that point, I would just fix it to use the new infrastructure. Atm the build bots are screaming about flang not being coherent with the new changes (the new changes we just discussed will come, but I don't think they will improve the situation).
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) | Wouldnt it be a less intrusive change if the generation of this options struct is controllable from the tablegen definition of the pass, say, a boolean field that when set generates the options struct. Then you could also generate the constructor for the pass that takes the generated struct as argument and initializes the pass options. Its upto user to then either have a new create method or not.... |
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) | Right, we could trigger this on whenever the let constructor = isn't present? Could also add a flag let generatePassOptions = 1;, but I'd want this to be the default and it is much harder to update every single pass to opt-out rather than the TableGen invocation (for flang isn't it a simple grep to find the instances followed by a sed to add the tablegen flag to opt out?) |
How are you supposed to access the pass options struct outside of the libraries? The pass class definitions aren't exposed publicly and you've added the struct definitions to the PassDetail.h files, which are not visible outside the libraries implementation code.
mlir/lib/Dialect/Transform/Transforms/CheckUses.cpp | ||
---|---|---|
364–368 ↗ | (On Diff #452662) | |
mlir/tools/mlir-tblgen/PassGen.cpp | ||
35 | I would class this {0}PassOptions |
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) |
+1 |
The options structs are declared inside the mlir/Conversion/Passes.h header. PassDetails.h includes only the pass base classes.
So, just to confirm, do we want a GEN_PASS_PassName define that enables both the options struct and the pass base class? Shouldn't the base class be available only in the PassDetails.h header? With a single define we either miss the public visibility of options (which makes all this useless) or have to accept the base classes having public visibility.
P.S: sorry for messing up with inline comments. Still quite new with the platform.
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #452662) | You will need to fix the flang build |
So, just to confirm, do we want a GEN_PASS_PassName define that enables both the options struct and the pass base class? Shouldn't the base class be available only in the PassDetails.h header?
There are two GEN_PASS_PassName I mentioned: one for the public header and the other for the private implementation. The Base class goes in the private part.
Oh yes sorry, I wrongly read them as if they had the same name. I proceed in implementing the required changes.
Introduced both the PASS_GEN_DECL_PassName and PASS_GEN_DEF_PassName. The former allows to import the options struct and the constructors (createPassNamePass() and createPassNamePass(const PassNamePassOptions &options)); these two methods are automatically declared in case of a missing constructor inside the pass TableGen. The latter allows to import the definition of the pass base class.
The declarations can be emitted through the option -gen-pass-decls, like it was before, while the definitions can be generated with the new option -gen-pass-defs.
I've introduced what we have been discussing yesterday. The flang build still needs to be fixed, but I would like to first reach consensus on the design.
An update wrt one of my previous answers: the definition of struct containing a pass options can now be obtained by including the header of the pass (e.g ConvertMemRefToLLVMPassOptions can be obtained by including mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h)
Wow! You didn't have to update all the passes to adopt this new feature from the get go.
Actually I tend to prefer to land the TableGen feature with the test dialect, and adopt it widely in one or multiple subsequent commits. This also help to show when something is backward compatible: can you clarify if this change is gonna be a breakage for all users (that is you had to update the entire codebase?).
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #453114) | Is this forward declaration still needed here? |
mlir/include/mlir/Conversion/Passes.td | ||
104 ↗ | (On Diff #453114) | This may show a limitation of the current approach: we can't generate the constructor in a namespace right? |
Well, I had to update the entire codebase due to the different autogenerated file and definitions (i.e. GEN_PASS_DECL_PassName, GEN_PASS_DEF_PassName), but it is also true that I can potentially still emit also the old stuff (under GEN_PASS_CLASSES) and thus avoid the breakage for other users. Still, at some point (that is when we decide to switch to the new design) they will have to adapt their code, and this is the reason why I preferred to update the whole MLIR project from the beginning. But I understand your point, and maybe a transitioning tablegen-ed files and individual patches for all the passes may be better in terms of readability (and potential revertibility). If the temporary coexistence of both old and new stuff is ok, I will switch to that.
mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h | ||
---|---|---|
23 ↗ | (On Diff #453114) | No, I just missed it. I will remove it in the next diff. |
mlir/include/mlir/Conversion/Passes.td | ||
104 ↗ | (On Diff #453114) | I'm not sure I get your question, atm the "constructor" (that is, the function returning the pass instance) is not generated at all and the constructor entry in tablegen is used only to make the call within the registration method. The user manually declares the createConvertArithmeticToLLVMPass() method inside the mlir::arith namespace. |
If the temporary coexistence of both old and new stuff is ok, I will switch to that.
In this case that seems desirable to me, if it is doable without overly convoluted heroics.
The old pass base class declarations are emitted in order to preserve backward compatibility.
The test reflects the usage of the patched infrastructure.
The direction of this patch LGTM. Splitting up the pass declarations to not be monolithic has been something people wanted
mlir/tools/mlir-tblgen/PassCAPIGen.cpp | ||
---|---|---|
94 | This function is called once. Can you just inline it? | |
97 | Drop braces | |
98 | +1 | |
mlir/tools/mlir-tblgen/PassGen.cpp | ||
392 | I'm hesitant to accept supporting "backwards compatibility" without a timeline to actually migrate all the upstream passes over (which you have already done, actually, so hopefully this timeline is small!) and deleting the old one. |
mlir/include/mlir/Pass/PassBase.td | ||
---|---|---|
79 | Can you please use an empty string to indicate "not present"? It's not possible to pass ? as a template argument in tablegen, so the former is much more convenient for writing something like class FooPass<string ctor = ""> : Pass { let constructor = ctor; } | |
mlir/tools/mlir-tblgen/PassCAPIGen.cpp | ||
95 | Please spell out this auto | |
102 | A string stream here isn't necessary. You can just call formatv(...).str() | |
mlir/tools/mlir-tblgen/PassGen.cpp | ||
104 | I would prefer to uppercase passName here, to get GEN_PASS_DECL_MYPASSNAME. @mehdi_amini thoughts? | |
124 | Ditto. Can you just inline this? |
This patch also has two things munged together: the pass options and reworking the way passes are generated. I personally don't mind that they're munged together, but can you edit the patch title and description to document all of these changes?
Address comments
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
104 | Sounds good to me, but I will wait also for other opinions before changing | |
392 | As you can see from my previous diff, updating the whole codebase in just one patch is quite huge (also, there are sometimes some "issues" with namespaces which may be worth discussing individually with whoever takes care of that part). I will split that into multiple commits (one for each pass), and being the work already done it shouldn't take long, as you correctly said. |
Nice, I'm excited to see a less monolithic approach to GEN_PASS_CLASSES, this will help for passes.td files with multiple passes that have differing dialect requirements etc. Right now you have to forward declare a lot just because they are used by other passes. very cool!
Is there any doc to update?
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
104 | I"m fine with UPPER :) |
lgtm. Please address river's comments
mlir/include/mlir/Pass/PassBase.td | ||
---|---|---|
79–83 | ||
mlir/tools/mlir-tblgen/PassGen.cpp | ||
392 |
I would just throw up one huge patch that migrates all the passes at once, to be honest, since the work is already done. The individual changes are small enough that it's not too burdensome. Can you upload the patch and mark it as Depends on D131839? | |
mlir/unittests/TableGen/PassGenTest.cpp | ||
42 | It's unfortunate that these can't be autogenerated as well due to the CRTP base class. |
mlir/tools/mlir-tblgen/PassCAPIGen.cpp | ||
---|---|---|
101–103 | I wouldn't say ugly (at least not to me). Stylistically I effectively never see cases with a newline in between (or at least, it's very uncommon) | |
mlir/unittests/TableGen/PassGenTest.cpp | ||
42 | Technically we could if we enforced that the pass name was the same as the ODS def name (e.g. with some static assert or something). |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 | Not a bad idea. Not having to manually define these default constructors that are mostly all identical would be nice! |
mlir/tools/mlir-tblgen/PassCAPIGen.cpp | ||
---|---|---|
101–103 | No problem, removing :) | |
mlir/unittests/TableGen/PassGenTest.cpp | ||
42 | I think I'm missing something. How would the definition look like? Tablegen doesn't know the derived class to be instantiated. // .h.inc std::unique_ptr<mlir::Pass> createTestPass(); // cpp.inc class Test : public TestBase { ... } std::unique_ptr<mlir::Pass> createTestPass() { return std::make_unique<?>(); // <-- TestBase ? } |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 | Oh well, I think I got what you mean (it's summer, my brain slows down :D). You just want a static assert into the base constructor checking for the derived class name to be equal to the one defined in tablegen. Atm I don't exactly know how to perform that check though. |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 | Remove "Base" suffix and done? I actually missed that you were not generating these yet, I thought the _DEF macro would :) |
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
392 | I have to update it with the latest changes first. I will try to do it tomorrow but I'm not sure I will be able to gather enough time to complete it. I will be on vacation for the next few days and in case I will upload it again on 24th or 25th. | |
mlir/unittests/TableGen/PassGenTest.cpp | ||
42 | I'm thinking about it and it may effectively be that simple. def TestPass : PassBase ... { ... } We would get the following: // .h.inc std::unique_ptr<mlir::Pass> createTestPass(); std::unique_ptr<mlir::Pass> createTestPass(const TestPassOptions &options) // .cpp.inc class TestPass : public TestPassBase { ... } std::unique_ptr<mlir::Pass> createTestPass() { return std::make_unique<TestPass>(); } std::unique_ptr<mlir::Pass> createTestPass(const TestPassOptions &options) { return std::make_unique<TestPass>(options); } Also, one unrelated consideration: the patched tablegen would emit a class named TestPassPassOption, should we append just "Options" instead of "PassOptions"? I see some passes already do define such a class though, and thus would clash. Should we just go on and then fix the clashing passes when updating them to use the new infra? |
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
392 | You don't need a review from *every* person for that stuff, just add me, @mehdi_amini, @jpienaar, @Mogball etc. | |
mlir/unittests/TableGen/PassGenTest.cpp | ||
42 |
We should decide on the "right" way to define these and just handle that, and then fix up the current places defining it incorrectly. We intended to do this while ago, but never had time. |
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
392 | Sharding the updates to various community members owning areas is fine to me. We've been doing this for other things, like the getters/setters: the project at some point becomes too big to require someone adding a new feature to migrate everyone. | |
mlir/unittests/TableGen/PassGenTest.cpp | ||
42 | I think it should be: // .cpp class TestPass : public TestPassBase { ... } // .cpp.inc std::unique_ptr<mlir::Pass> createTestPass() { return std::make_unique<TestPass>(); } ... That is: the pass is user-written and not generated, by design. |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 | You'll see remnants of a patch where I started fixing the PassPass generation in name but never finished and I never got back to ... ( there I had gone for all Pass's should have Pass suffix as that match how we do Ops, Types and Attr.). So +1 to River's comment here. |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 |
No problem, we all have our stuff to do. My two cents: partially answering to myself, we should just keep appending "Pass" to the pass name and "PassOptions" for the options struct. This way, passes like ConvertXToY would become ConvertXToYPass and generate the createConvertXToYPass constructor (and NOT createConvertXToY, which is a bit weird), while passes like Bufferize would generate BufferizePass and createBufferizePass (and not createBufferize). |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 |
So if I get it right you're suggesting the opposite path wrt to my last comment, assuming that the user manually writes the Pass suffix in the tablegen declaration? (asking just clarity, I don't have a strong opinion about this).
Right, it matches with my example. |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 |
To be clear: the comments // .cpp and // .cpp.inc differ from your previous example, unless I am missing what you're referring to. |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 | You're right, and it's a good thing you made me notice that because I'm seeing one more problem in the constructor definition. GEN_PASS_DEF_PASSNAME wraps the pass base class, and now it would also wrap the create method. However, the actual pass class has to be implemented by the user, and thus first needs to include the .cpp.inc. But the constructor then would come before the class definition. It would be equivalent to manually writing this into the .cpp, which would not compile: // Automatically generated class TestBase { ... }; // Automatically generated std::unique_ptr<Pass> createTestPass() { return std::make_unique<TestPass>(); } // Manually defined by the user class TestPass : public TestBase { }; On the other hand, moving the #include .cpp.inc after the TestPass class definition would lead to TestBase not being defined. |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 | Ah! Annoying... Any other solution than yet one more macro? |
mlir/unittests/TableGen/PassGenTest.cpp | ||
---|---|---|
42 | Well, I got something to compile in godbolt using friend functions: |
I've updated the documentation. Please give it a read and tell if it's not clear enough or if I missed something.
Also, I realized that the list options were not handled correctly. Now they generate an ArrayRef variable within the options struct. I've also added a list option within the test pass to check for the correct behaviour.
Edit: forgot to mention that I've implemented the emission of the constructors' definitions, based on the suggestion from @rriddle
mlir/include/mlir/Pass/PassBase.td | ||
---|---|---|
79–83 | I would omit the diamond operator around PassName. With the new patches, the generated method would like create<PassName>() in the docs, which seems like a template specialization. createPassName() is clear enough imho. |
Looks good, thanks for working on this!
mlir/docs/PassManagement.md | ||
---|---|---|
882 | ||
mlir/tools/mlir-tblgen/PassGen.cpp | ||
97–99 | ||
233–235 | Do we always generate an Options struct? I assume we wouldn't in the case where the pass has no options. | |
345–353 | Maybe a FIXME/TODO/or something to indicate that ideally this should be killed? |
Hi there,
This change is triggering a warning (which we treat as error) in one of our builds:
/usr/bin/clang++ -DMLIR_CUDA_CONVERSIONS_ENABLED=0 -DMLIR_INCLUDE_TESTS -DMLIR_ROCM_CONVERSIONS_ENABLED=0 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/__w/1/b/llvm/Release/tools/mlir/unittests/TableGen -I/__w/1/llvm-project/mlir/unittests/TableGen -I/__w/1/b/llvm/Release/include -I/__w/1/llvm-project/llvm/include -I/__w/1/llvm-project/mlir/include -I/__w/1/b/llvm/Release/tools/mlir/include -I/__w/1/llvm-project/mlir/unittests/TableGen/../../test/lib/Dialect/Test -I/__w/1/b/llvm/Release/tools/mlir/unittests/TableGen/../../test/lib/Dialect/Test -I/__w/1/llvm-project/llvm/utils/unittest/googletest/include -I/__w/1/llvm-project/llvm/utils/unittest/googlemock/include -fPIC -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Werror=mismatched-tags -O3 -DNDEBUG -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments -fno-exceptions -UNDEBUG -Wno-suggest-override -std=c++17 -MD -MT tools/mlir/unittests/TableGen/CMakeFiles/MLIRTableGenTests.dir/PassGenTest.cpp.o -MF tools/mlir/unittests/TableGen/CMakeFiles/MLIRTableGenTests.dir/PassGenTest.cpp.o.d -o tools/mlir/unittests/TableGen/CMakeFiles/MLIRTableGenTests.dir/PassGenTest.cpp.o -c /__w/1/llvm-project/mlir/unittests/TableGen/PassGenTest.cpp In file included from /__w/1/llvm-project/mlir/unittests/TableGen/PassGenTest.cpp:12: In file included from /__w/1/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock.h:58: In file included from /__w/1/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-actions.h:53: In file included from /__w/1/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-internal-utils.h:50: /__w/1/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest.h:1526:11: error: comparison of integers of different signs: 'const unsigned int' and 'const int' [-Werror,-Wsign-compare] if (lhs == rhs) { ~~~ ^ ~~~ /__w/1/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest.h:1553:12: note: in instantiation of function template specialization 'testing::internal::CmpHelperEQ<unsigned int, int>' requested here return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); ^ /__w/1/llvm-project/mlir/unittests/TableGen/PassGenTest.cpp:86:3: note: in instantiation of function template specialization 'testing::internal::EqHelper::Compare<unsigned int, int, nullptr>' requested here EXPECT_EQ(unwrap(pass)->getTestOption(), 57); ^ /__w/1/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest.h:2027:54: note: expanded from macro 'EXPECT_EQ' EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
Thanks for reporting. Fixed with d467515602fc55deddc910267f83c70c2e15f613.
mlir/tools/mlir-tblgen/PassGen.cpp | ||
---|---|---|
233–235 | Fixed |
@rriddle @mehdi_amini I'm updating my previous modifications to the existing passes but I've realized that the friend trick is not going to work, leading to undefined symbols at link time for what regard the createPassName methods. I suspect that the only solution is to split the GEN_PASS_DEF macro into something like GEN_PASS_DEF_BASECLASS_PASSNAME and GEN_PASS_DEF_CONSTRUCTOR_PASSNAME and include the .cpp.inc autogenerated file both before and after the actual class definition.
If that's ok, I will open a new review for this.