This is an archive of the discontinued LLVM Phabricator instance.

[mlir] Add Cpp emitter
ClosedPublic

Authored by marbre on Jun 21 2021, 3:47 AM.
Tokens
"Hungry Hippo" token, awarded by post.kadirselcuk.

Details

Summary

This upstreams the Cpp emitter, initially presented with [1], from [2]
to MLIR core. Together with the previously upstreamed EmitC dialect [3],
the target allows to translate MLIR to C/C++.

[1] https://reviews.llvm.org/D76571
[2] https://github.com/iml130/mlir-emitc
[3] https://reviews.llvm.org/D103969

Co-authored-by: Jacques Pienaar <jpienaar@google.com>
Co-authored-by: Simon Camphausen <simon.camphausen@iml.fraunhofer.de>
Co-authored-by: Oliver Scherf <oliver.scherf@iml.fraunhofer.de>

Diff Detail

Event Timeline

marbre created this revision.Jun 21 2021, 3:47 AM
marbre requested review of this revision.Jun 21 2021, 3:47 AM
marbre updated this revision to Diff 353592.Jun 22 2021, 3:31 AM

Take care of clang-tidy warnings

marbre updated this revision to Diff 353606.Jun 22 2021, 4:26 AM

Take care of clang-tidy warnings

Thanks! Starting to piece through, but have some high level questions:

Can you add proper .md documentation? We should give the user an idea of what is being generated from a high level, and understand the rationale/tradeoff behind our decisions.

What version of C/C++ are you targeting here? (Part of the previous question) Users should have an idea of the minimum toolchain requirements of the generated code.

mlir/include/mlir/Target/Cpp/CppEmitter.h
26

Can you document this class and API?

66

Is this API intended to be exposed to users? Or is this emitted simply an implementation detail?

rriddle added inline comments.Jun 24 2021, 11:40 AM
mlir/lib/Target/Cpp/TranslateToCpp.cpp
809–841
862

nit: Please drop trivial braces here. (and elsewhere in the commit)

Thanks! Starting to piece through, but have some high level questions:

Thanks River, I appreciate this! Trying to answer some of your questions prior to sending the next revision.

Can you add proper .md documentation? We should give the user an idea of what is being generated from a high level, and understand the rationale/tradeoff behind our decisions.

Sure! Do you have a suggestion where to place it? I think the other MLIR targets are not documented in a single place like e.g. all dialects are.

What version of C/C++ are you targeting here? (Part of the previous question) Users should have an idea of the minimum toolchain requirements of the generated code.

Well it depends on the conversions one writes. For ops with multiple return values the code emitted requires C++11 as those got emitted as std::tuple. Further, one can write conversions to emitc::CallOps that have floating-point type template argument, making C++20 mandatory. Such code can be emitted, but it doesn't has to. We intended to not limit this in the emitter, but I absolutely agree that we need to document this!

mlir/include/mlir/Target/Cpp/CppEmitter.h
26

Even simpler, I will delete the struct which the next revision as it is an unused leftover. Sorry for this.

66

Well I think it depends on how we define the user level. E.g. in IREE the emitter is initialized in the translateModuleToC() function of the CModuleTarget. So one can use the API outside the MLIR core repo. Would you call this user level?

mlir/lib/Target/Cpp/TranslateToCpp.cpp
862

Uh, I was following the Google style guide too closely and assumed dropping trivial braces is only allowed when you don't have an else block. Will go over all those places with the next revision. Thanks!

The handling of C/C++ isn't clear to me, I looked at restrictedToC uses and it seems that ForOp and ConstOp are doing something special but it isn't clear to me. It likely deserves more docs.

Otherwise I'm not convinced that erroring out on constructs that aren't valid in C is really worth the complexity, nor that this belongs to the emitter itself (it is also incomplete, for example the return op can do std::make_tuple without error right now).

mlir/include/mlir/Target/Cpp/CppEmitter.h
66

To me that looks like a very large C++ surface API for this. Would it be possible to start smaller, keep more things private until this gets mileage and carefully expose more APIs later?

We could start with only translateToCpp exposed for example.

156

Can you use verbs for API when it makes sense? getForwardDeclaredVariabled isRestrictedToC

192

Please document the options, I don't know what trailingSemicolon means for example.

mlir/lib/Target/Cpp/TranslateToCpp.cpp
289

Can you document what's happening here?

434

Why these hardcoded includes?

443

This won't respect the interleaving of includes and other operations in the module.

mlir/test/Target/Cpp/common-cpp.mlir
7

Can we change the custom syntax to be emit.include <myheader.h> for standard include? (or emit.include <"myheader.h"> if we can't parse the former)?

mehdi_amini added inline comments.Jun 24 2021, 1:33 PM
mlir/include/mlir/Target/Cpp/CppEmitter.h
172

ValueMapper valueMapper : there is really no need to skip on two characters here.

mlir/lib/Target/Cpp/TranslateToCpp.cpp
474

I don't know what "forward declare" really means for variables: this seems to imply a difference between declaration and definition like for functions.

It also is the kind of things that makes the IR definition incompatible with some emission mode, it'd be best to avoid this and remove the option and just do the right thing: do we need to move all variable to the top when there are multiple blocks or only for the SSA value that are defined in a block and used in another one?

Thanks for your review Mehdi! Trying to answer some of your questions below and inline prior to sending the next revision. I will address those I did not respond to with the updated patch.

The handling of C/C++ isn't clear to me, I looked at restrictedToC uses and it seems that ForOp and ConstOp are doing something special but it isn't clear to me. It likely deserves more docs.

I agree that this clearly deserves more documentation. The one difference here is that the emitted code contains curly-brace-delimited initializer lists when generating C++ code. When emiting C code, the initialization is expressed with =.

Otherwise I'm not convinced that erroring out on constructs that aren't valid in C is really worth the complexity, nor that this belongs to the emitter itself (it is also incomplete, for example the return op can do std::make_tuple without error right now).

We started with emitting C++ code and added the ability to restrict the emitter to C code later, as this was needed for IREE. We internally discussed to split into two separate emitters, but decided against it as we assumed that it would probably result in to much code duplication. Designing a single emitter, for the initialization discussed above the alternative would have been to always use an = to express it. As we need to error out some types (anything not a fundamental type in C) we thought differentiating for the initialization would be fine.
For std::make_tupe your are absolutely right, this is bug and we need to return an error in that case.

mlir/include/mlir/Target/Cpp/CppEmitter.h
66

That was what we had with the initial proposal https://reviews.llvm.org/D76571. However, for IREE we need an emitter that is able to translate e.g. IREE::VM::ModuleOp, IREE::VM::FuncOp and others to C. There we reuse e.g. emitType() which we have to duplicate otherwise. So I would prefer to not make all things private, but for sure we can go over and carefully go over and see if there is something we can make private easily. Hope this might be acceptable?

mlir/lib/Target/Cpp/TranslateToCpp.cpp
434

The #include <cmath> can indeed be dropped. The ones emitted when emitting C are required for the types, but we can also drop those as they can be expressed via emitc::IncludeOps.

443

This is true. Do you propose to emit includes wherever they are in the IR file?

474

We introduced this when support for emitting code that contains branches was added. Probably Simon, who implemented this, can comment best (will ping him).

mlir/test/Target/Cpp/common-cpp.mlir
7

Just to make sure I got you right, you suggest
emitc.include <myheader>
for standard includes and
emitc.include "myheader"
for non-standard includes?

I can give it a try, but would send a separate patch as it's already landed this way and is not directly related to this patch.

[..]
Otherwise I'm not convinced that erroring out on constructs that aren't valid in C is really worth the complexity, nor that this belongs to the emitter itself (it is also incomplete, for example the return op can do std::make_tuple without error right now).

Indeed hard to test. At least I cant create an IR snippet that hits an error when trying to create std::make_tuple while restricted to C. The snippet

func @func_tuple(%arg0: i32,  %arg1 : i32) -> (i32, i32) {
  return %arg0, %arg1 : i32, i32
}

is translated to C++ as

std::tuple<int32_t, int32_t> func_tuple(int32_t v1, int32_t v2) {
return std::make_tuple(v1, v2);
}

Even if restricted to C, one does not hit an error trying to emit the std::make_tuple in printReturnOp(). This is because emitTupleType() already returns an error when trying to create the function's return type std::tuple. Nevertheless, I will add a check taking care of std::make_tuple as well as additional C specific test snippets.

. We internally discussed to split into two separate emitters,

I wouldn't suggest this, I would suggest a single emitter, and a single mode, capturing the difference in the IR. If the only thing is the curly brace default initialization, can we always use = in the C++ emitter so that we have C-compatible output from the C++ emitter (assuming the absence of C++ features like returning multiple values from a function or templates).

As we need to error out some types (anything not a fundamental type in C) we thought differentiating for the initialization would be fine.

This does not need to be part of the emitter, it can be a validation on the module itself that you can run ahead of time for example.

mehdi_amini added inline comments.Jun 24 2021, 5:08 PM
mlir/include/mlir/Target/Cpp/CppEmitter.h
66

Your use-case indicates to me a problem with the design of the emitter itself.
It seems that the user may want to have custom emitter for their operations instead of targeting what is supported by the emitter.
But the design you're taking is exposing the internal of the emitter allowing the user to extend it in a standalone way, which unfortunately isn't composable.

It also seems to partially defeat the original point of having a dialect, since the motivation was to be able to always use dialect conversion to bottom out into a representation that can be emitted to C/C++.
If this isn't possible then we're back to adding a mechanism where operations could define an interface or something like this to plug into the emitter. But this is weirdly going against the motivation for the dialect as I understood it, since it was trying to avoid this.

mlir/lib/Target/Cpp/TranslateToCpp.cpp
443

I would do this, as it provide the control back to the IR. Any downside to do this?

We can also imagine that some include requires to have some other construct defined before the inclusion.

stellaraccident added inline comments.
mlir/include/mlir/Target/Cpp/CppEmitter.h
66

That was what we had with the initial proposal https://reviews.llvm.org/D76571. However, for IREE we need an emitter that is able to translate e.g. IREE::VM::ModuleOp, IREE::VM::FuncOp and others to C. There we reuse e.g. emitType() which we have to duplicate otherwise. So I would prefer to not make all things private, but for sure we can go over and carefully go over and see if there is something we can make private easily. Hope this might be acceptable?

I generally agree with River/Mehdi's critique of the API surface area here and think we should land this with a limited API surface area.

Considering IREE::VM::ModuleOp and IREE::VM::FuncOp, it feels to me like your ConvertVMToEmitC pass just stopped to soon and should have also converted those ops (I know they are tricky to convert, and it may be easier to have a subsequent pass that finalizes the module and function conversion). Looking at that code a bit, it appears to me as if this point alone accounts for no small amount of the divergence and need to expose API surface area, with some more being accounted for by the correlated IREE::VM::ReturnOp.

This alone brings up a design question for EmitC: namely does it *have* to be tied to builtin ModuleOp and FuncOp? In this upstream version, you've basically encoded this assumption. I feel like you could relax the assumption that the top-level is ModuleOp (just let it be an Operation* -- although it is unfortunate that the Translation API declares this as ModuleOp and it should probably be generalized in a followon) and you could key off of FunctionLike instead, if you wanted to be a bit more friendly to users who are bringing their own module/function ops.

However, even with the above, there are further design points: you will need to model somehow some of the header/trailer things that you are currently doing ad-hoc in the IREE-side translation function. We should probably discuss more, but I would tend to want to introduce something like emitc.ModuleMetaAttr and emitc.FuncMetaAttr to let such things be encoded. (I'd tend that way because it would likely reduce the conversion burden for users, but the alternatives are to bring your own ModuleOp/FuncOp that carries this stuff, define additional operations to model this, etc).

On the IREE side, it appears that you are using the chance to control the overall emission to cover for some things that really should be modeled in EmitC itself (ie. headers/trailers/etc). This isn't so bad for a single use in IREE, but widening this to common infra means that we should really start in the pure form and then iterate to implement the needed features to fully represent what you are doing on the IREE side (as opposed to relying on some backdoors that look to me largely there to cover for features that just haven't been implemented yet). I'm looking at some of those items and finishing it doesn't seem insurmountable -- not really big design issues there, just work.

I haven't done a complete detailed review of everything in this diff, but I think that if, in this patch, we made the emitter private, it would hold together as a pretty good initial submission. I realize this doesn't get you to carving out the IREE VM->EmitC translation in one step, but it looks like there are important points to work out to finish the features and it would be better to do so incrementally. We can always carry a copy of this code in IREE during the conversion (i.e. use the upstream dialect and progressively finish the emitter until it is complete enough to swap entirely).

I know this can feel a bit slow, but starting restricted and expanding will help us deal with (I'm guessing) the 3-6 additional features and landing them well so that the feature has a better chance of working for everyone in a non ad-hoc fashion.

Thank you for working with us on it!

marbre added inline comments.Jun 25 2021, 5:11 AM
mlir/include/mlir/Target/Cpp/CppEmitter.h
66

Thanks for all the feedback and the comments. Unfortunately, I only have time for a rather short reply.

First of all, I got the point and agree that we should rather start with only exposing translateToCpp. It's fine for me if we cant use the upstreamed emitter 1:1 in IREE. I mainly intended to give background information on why it is the way it is, although we could have done better. As proposed, I would refactor to only expose translateToCpp with the next revision. I hope we can build upon this, without having something which is contrary to the actual motivation. It already came to my mind that we might need our own EmitC ModuleOpand FuncOp, but the alternative Stella mentioned is quite interesting. I would be glad if we could continue this discussion. Is discourse preferred to do so?

simon-camp added inline comments.
mlir/lib/Target/Cpp/TranslateToCpp.cpp
474

We could technically declare variables for "block local" SSA values in their corresponding blocks. (Or more generally move them to the dominating Block if we iterate over blocks in dominance order I think).

We would still need to split the variable initialization into a declaration followed by an assignment because jumping over variables with initializers is ill-formed in C++. (cppreference)

I tried different variants for the SSA value %b here.

marbre added inline comments.Jul 1 2021, 7:06 AM
mlir/test/Target/Cpp/common-cpp.mlir
7

@mehdi_amini please see https://reviews.llvm.org/D105281 which Simon has sent and which addresses the parsing and printing of the custom format.

marbre added inline comments.Jul 2 2021, 6:01 AM
mlir/lib/Target/Cpp/TranslateToCpp.cpp
443

I think we need the capability to emit include directives at the top level of source file and thus prior to any forward declared function. Types used in the forward declared functions can rely on those top level includes, for example when using tensors.
However, I agree that giving control back to the IR is better . Would you mind if we add an attribute like emit_at_top to the include op?

jpienaar added inline comments.Jul 2 2021, 6:22 AM
mlir/lib/Target/Cpp/TranslateToCpp.cpp
443

I think lets start there: why is forward declaration needed? Is there a way to represent fwd declaration as an op? An alternative I could see here would be to go in order (so you can still have have interleaving, still things at the top with no changes to the ops), once you encounter a function you can fwd declare all functions until the next include (which couldn't rely on an include below them anyway) and continue. The alternative seems more opaque though/could easily be implemented as a "prepare for export" pass on emitc dialect. This function becomes dead simple if all are explicit.

mehdi_amini added inline comments.Jul 2 2021, 11:09 AM
mlir/lib/Target/Cpp/TranslateToCpp.cpp
443

Would you mind if we add an attribute like emit_at_top to the include op?

Why add such an attribute instead of relying on the IR ordering?

443

I mean: if I am in a position to add this include with the emit_at_top attribute, I can just as well add the op at the top of the module directly?

marbre marked 12 inline comments as done.Jul 9 2021, 11:16 AM

Thanks for all review comments. Most comments should be addressed with the next revision. As discussed, the emitter's API is now significantly closed (only translateToCpp is accessible). The revision also drops the emitter's restriction to only generate C code. This is of course still possible and depends (as before) on the implemented conversions, but isn't checked in the emitter itself anymore. What the revision lacks is a dedicated markdown documentation. Suggestion to where to place such docs in the docs/ folder are welcome. So far the other targets don't have separate docs or should those live side-by-side to the EmitC dialect?

mlir/include/mlir/Target/Cpp/CppEmitter.h
156

restrictedToC is dropped and forwardDeclaredVariables is renamed to shouldDeclareVariablesAtTop with the next revision.

192

With the next revision, trailingSemicolon is removed from translateToC and it is documented were appropriate.

mlir/lib/Target/Cpp/TranslateToCpp.cpp
289

This is refactored with dropping emitting braced initializers.

443

I think lets start there: why is forward declaration needed? Is there a way to represent fwd declaration as an op? An alternative I could see here would be to go in order (so you can still have have interleaving, still things at the top with no changes to the ops), once you encounter a function you can fwd declare all functions until the next include (which couldn't rely on an include below them anyway) and continue. The alternative seems more opaque though/could easily be implemented as a "prepare for export" pass on emitc dialect. This function becomes dead simple if all are explicit.

443

I think lets start there: why is forward declaration needed? Is there a way to represent fwd declaration as an op? An alternative I could see here would be to go in order (so you can still have have interleaving, still things at the top with no changes to the ops), once you encounter a function you can fwd declare all functions until the next include (which couldn't rely on an include below them anyway) and continue. The alternative seems more opaque though/could easily be implemented as a "prepare for export" pass on emitc dialect. This function becomes dead simple if all are explicit.

Thanks for your suggestion. I really like the idea of adding an operation that explicitly allows to indicate that a declaration should be forward declared. This could look like emitc.forwarddeclare @func. The alternative, going in order and to declare all functions forward till hitting the next include op seems even more implicit than what we already have.
For now, I simply removed forward declaring functions at all. I am aware that you, Jacques, probably had good reasons to add it to the original proposal. However, I have refactored our MHLO/TOSA to EmitC conversion passes in a way that we don't need any forward declarations for now. I think best would to re-enable this by adding an explicit op as you proposed as soon as we have a use case.

443

I am fine with relying on the IR ordering and thus I removed to code that forward declared the functions + implemented include op handling as for any other op. Just relying on the IR ordering for include ops wouldn't have been enough as function were always forward at the top of an module. That was probably the root issue, but that's now resolved and we'll follow Jacques suggestion of adding a new op if we really want to get this ability back.

474

I have renamed forwardDeclaredVariables to shouldDeclareVariablesAtTop. Hopefully that makes it clearer. We further improved the comments to make it clearer what's happening.

809–841

Thanks for the suggestion. Done with the next revision.

marbre updated this revision to Diff 357581.Jul 9 2021, 11:17 AM
marbre marked 6 inline comments as done.

Updating D104632: [mlir] Add Cpp emitter

For the doc, what about adding a section in the dialect doc? It'll show up on this page then: https://mlir.llvm.org/docs/Dialects/EmitC/

See how other dialect have a fairly large doc as well: https://mlir.llvm.org/docs/Dialects/TOSA/ or https://mlir.llvm.org/docs/Dialects/Linalg/

marbre updated this revision to Diff 367831.Aug 20 2021, 10:42 AM
marbre marked 4 inline comments as done.

Add markdown documentation and dialect description

With https://github.com/llvm/mlir-www/pull/83 merged (allowing to include custom docs in auto-generated ones) and me having finally had some time to write a first markdown documentation (we can still iterate and improve that one!) I would kindly ask @rriddle, @mehdi_amini and @jpienaar to re-review the patch :)

Nice, thanks for all the changes

mlir/docs/Dialects/emitc.md
5

Could the version required of the generated code perhaps be printed? This seems like an easy gotcha (generate code use it in X, it works until you make one change and suddenly end up requiring different version of C++ and the user doesn't know why).

6

Could we make this more "active"? E.g.,

The following convention is followed:

  • If multiple ..., C++11 is required
  • If floating ..., C++20 is required
  • Else the generated code is compatible with C99 ?

[also could we test these?]

10

C++20 is a bit unfortunate as most consumers here incl MLIR core can't use it.

23

This doesn't seem like documenting the dialect, but the Cpp emitter and so should be documented along with it,

31

Why the gap? If to signify different dialects, why not indented list? (I'm not sure what markdown generated will show with space, but feels like making the structure explicit is nicer)

mlir/include/mlir/Target/Cpp/CppEmitter.h
30

Operation *op would result in nicer implicit conversions AFAIK, e.g., should be able to just do translateToCpp(module, os, false) below and ModuleOp would get converted.

mlir/lib/Target/Cpp/TranslateRegistration.cpp
42

I would have expected something like

--mlir-to-cpp --cpp-declare-variables-at-top

as that is how the other translates work (SavedModel one having a lot of args)

mlir/lib/Target/Cpp/TranslateToCpp.cpp
32

Nit: STLExtras , to not confuse with C++ STL

72

Why do you need to pass in an Operation when emitting an Attribute?

162

I would have used raw_indented_ostream here, especially as it would work well with Scope helper to do indentation

177

Why is this not in the Scope construct too?

244

Errors emitted are sentence fragments that start with lower case and don't end with punctuation

626

Is this as it is redundant for these? I believe for CondBranchOp it is required due to goto, but not sure

703

So this requires cmath header?

775

Seems like you are using op here only to get a Location. Could we rather just pass a Location?

908

Mmm, I'd almost prefer this to be shouldMapToUnsigned: signed and signless are both mapped to intX_t, while unsigned is mapped to uintX_t.

simon-camp added inline comments.Aug 25 2021, 4:11 AM
mlir/lib/Target/Cpp/TranslateToCpp.cpp
177

Wouldn't we need a stack<Scope> then? ScopedHashTableScope is not copy/move constructible.

Is there a way to directly calculate the size of a ScopedHashTable? Then we wouldn't need the stack at allI think.

marbre updated this revision to Diff 368647.Aug 25 2021, 8:26 AM

Address review comments

marbre marked 13 inline comments as done.Aug 25 2021, 8:49 AM

Thanks for the review @jpienaar! I have updated our patch accordingly.

mlir/docs/Dialects/emitc.md
5

Initially we had mlir-to-cpp and mlir-to-c. We have removed all checks in the emitter, as Mehdi proposed to rather add a verifier pass. So yes, we could just print if a feature requiring C++XX is used of we implement a verifier pass. Anyway, I would like to do so in a follow up if acceptable.

6

Done.

[also could we test these?]

I think this is related to the verifier pass isn't it?

10

It is, but that's a decision to be made by the user. If somebody really wants to generate code that contains floating-point type template arguments, the user can do so.

23

Yes, this documents the emitter. Mehdi proposed so before:

For the doc, what about adding a section in the dialect doc? It'll show up on this page then: https://mlir.llvm.org/docs/Dialects/EmitC/

See how other dialect have a fairly large doc as well: https://mlir.llvm.org/docs/Dialects/TOSA/ or https://mlir.llvm.org/docs/Dialects/Linalg/

31

It's now explicit.

mlir/include/mlir/Target/Cpp/CppEmitter.h
30

Good point, have refactored this.

mlir/lib/Target/Cpp/TranslateRegistration.cpp
42

This is what we had in iml130/mlir-emitc before commit #1a87d97. However, with add_flag_if_supported("-Werror=global-constructors" WERROR_GLOBAL_CONSTRUCTOR) set in mlir/lib/CMakeLists.txt this solution cannot be taken over 1:1. Instead one would need to touch mlir/lib/Translation/Translation.cpp, adding static llvm::cl::opt parameters there. However, these options would be always present, even if the Cpp emitter isn't build. I assumed that this would therefore be undesired and decided to go with the current implementation.

mlir/lib/Target/Cpp/TranslateToCpp.cpp
72

This was used to make use of op.emitError(). I have refactored this and now a location is passed to the functions emitAttribute, emitType, emitTypes and emitTupleType.

162

Thanks for the suggestion, I wasn't aware of raw_indented_ostream. Have refactored accordingly and we now emit indented code!

626

We've updated to comment to better describe why this is needed.

703

It does. This can be emitted via an emitc.include. However, this has to be done in the conversion pass and we do not emit any includes by default as suggested in the first rounds of the review.

775

As commented above, this was refactored as proposed.

mehdi_amini added inline comments.Aug 25 2021, 8:59 AM
mlir/lib/Target/Cpp/TranslateRegistration.cpp
42

You could just create a static cl::opt in this function (registerToCppTranslation) and use it inside the lambda:

static cl::opt<bool> declareVariablesAtTop("mlir-to-cpp-declare-variables-at-top");
TranslateFromMLIRRegistration reg(
     "mlir-to-cpp",
     [&](ModuleOp module, raw_ostream &output) {
       return emitc::translateToCpp(module, output, declareVariablesAtTop);
     },
     [](DialectRegistry &registry) {
       // clang-format off
       registry.insert<emitc::EmitCDialect,
                       StandardOpsDialect,
                       scf::SCFDialect>();
       // clang-format on
     });
marbre added inline comments.Aug 26 2021, 12:04 AM
mlir/lib/Target/Cpp/TranslateRegistration.cpp
42

You could just create a static cl::opt in this function (registerToCppTranslation) and use it inside the lambda: [..]

Thanks for the suggestion, I really appreciate the support. Unfortunately, the also this approach fails due to add_flag_if_supported("-Werror=global-constructors" WERROR_GLOBAL_CONSTRUCTOR) in mlir/lib/CMakeLists.txt:

[build] mlir/lib/Target/Cpp/TranslateRegistration.cpp:26:28: error: declaration requires a global destructor [-Werror,-Wglobal-constructors]
[build] static llvm::cl::opt<bool> declareVariablesAtTop("declare-variables-at-top");
[build]                            ^
mehdi_amini added inline comments.Aug 26 2021, 8:46 AM
mlir/lib/Target/Cpp/TranslateRegistration.cpp
42
marbre added inline comments.Aug 26 2021, 8:57 AM
mlir/lib/Target/Cpp/TranslateRegistration.cpp
42

You're right! I accidentally placed the cl::opt<bool> outside the function scope and not within the scope of void registerToCppTranslation(). Will update our patch asap. Thanks again for your help with this!

marbre updated this revision to Diff 368914.Aug 26 2021, 9:45 AM

Refactor translation cmdline arguments

marbre marked 14 inline comments as done.Aug 26 2021, 9:47 AM

I'll leave approval to @jpienaar, the current version is fine with me, thanks!

I'll leave approval to @jpienaar, the current version is fine with me, thanks!

Thanks a lot for the feedback! Beside @jpienaar's opinion, which of course is important, would the current version also be fine for @rriddle?

jpienaar accepted this revision.Aug 31 2021, 4:07 PM

Nice, thanks, LG

This revision is now accepted and ready to land.Aug 31 2021, 4:07 PM
This revision was automatically updated to reflect the committed changes.

Did a scan, looks good thanks!