This is an archive of the discontinued LLVM Phabricator instance.

[mlir][ods] Cleanup of handling Op vs OpAdaptor
ClosedPublic

Authored by Mogball on Nov 3 2021, 10:48 AM.

Details

Summary

In preparation for implementation subrange lookup on attributes.

Depends on D113039

Diff Detail

Event Timeline

Mogball created this revision.Nov 3 2021, 10:48 AM
Mogball requested review of this revision.Nov 3 2021, 10:48 AM
jpienaar added inline comments.Nov 4 2021, 10:27 AM
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
231

Why do we need to pass in isVariadic here? (don't know we know this from the index + Operator)

Mogball marked an inline comment as done.Nov 4 2021, 10:54 AM
Mogball added inline comments.
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
231

True

Mogball updated this revision to Diff 384823.Nov 4 2021, 11:26 AM
Mogball marked an inline comment as done.

Don't pass in isVariadic

Looks good!

mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
196–201

Not sure do we need this? I thought the operator overloading down below is enough?

454

While seeing auto &op = emit.getOp();, I may consider passing Operator and create the OpOrAdaptorHelper locally because it's more like a helper function for local codegen. (The isOp can be an argument as well)

1001

I think we can keep the type here. the getGetterName doesn't tell it returns StringRef or std::string

1089

ditto

2089–2099

How about early exit for !type.isArg()

2152

I'm thinking if there's a better name which tells its a helper class. Like a pure helper or opAccessor?

Mogball marked 5 inline comments as done.Nov 9 2021, 9:49 AM
Mogball added inline comments.
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
196–201

Sometimes we need formatv(...).str() because the results of the format need to be stored and, for example, passed into a method signature.

454

From my perspective, it looks cleaner when these huge functions have fewer arguments, and since the helper also contains the gen info (the Operator and isOp) it's easier to just pass it in instead of passing all the individual arguments everywhere and creating the helper everywhere.

jpienaar accepted this revision.Nov 9 2021, 10:01 AM

Looks good, thanks (it seems a couple of done items [re: type] was not done, perhaps just missing in the upload)

mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
187

isOp confused me a bit as you are passing in an Operator called op. WDYT about something like emitForOp or something like that?

254

Nit: new line in between for consistency

This revision is now accepted and ready to land.Nov 9 2021, 10:01 AM
Chia-hungDuan added inline comments.Nov 9 2021, 10:23 AM
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
196–201

I think the Formatter is used to build the string in formatv() with stream operator and the conversion to str() is done by formatv_object. Does formatv(...).str() need to invoke the Formatter::str()?

454

I think for this case it'll be 3 arguments and it seems fine and The creation of helper is not a noticeable cost. I think either ways should be fine. I don't have a strong opinion here. Let's just stick on your plan!

Mogball marked 2 inline comments as done.Nov 9 2021, 10:35 AM
Mogball added inline comments.
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
196–201

No, but sometimes I need to invoke emitHelper.getAttr("attr_name").str() which is calling this function. Otherwise I'd need to call formatv("{0}", emitHelper.getAttr("attr_name")).str()

454

It's just messier passing in tons of arguments into every function.

Mogball marked 3 inline comments as done.Nov 9 2021, 10:38 AM
Mogball added inline comments.
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
454

The example I have in my head is something like this:

struct HelperInfo {
  int a;
  bool bunch;
  std::string of;
  raw_ostream &info;

  void do_something_with_info();
};

// Instead of:
static void genFunction(int a, bool bunch, std::string of, raw_ostream &info) {
  HelperInfo helper{a, bunch, of, info};
  helper.do_something_with_info();
}

// Do:
static void genFunction(HelperInfo &helper) {
  helper.do_something_with_info();
}

Especially when you have 3, 4, or more functions that need to accept all these arguments and construct the helper object.

Mogball updated this revision to Diff 385899.Nov 9 2021, 10:59 AM

Rebase, and review comments

Chia-hungDuan added inline comments.Nov 9 2021, 11:41 AM
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
196–201

With this use case then I got it! Thanks

454

Sorry, I didn't say it clear. To construct a OpOrAdpatorHelper you need two arguments. I was thinking we could pass the two arguments instead of passing the constrcuted OpOrAdaptorHelper. Thus the number of arguments would increase only 1, right?

I think whether we should pack the arguments it depends on the case. Too many arguments may be a warning but it may be not always the bad thing. (I know you just want to give a quick example)

Take this function as an example, populateSubstitutions, I would expect I call this function it'll do the substitutions of attributes, operands and results and I only need to tell it what operation I want it to work with.

But now, I may also need to know what data structure the function would like to use and this data structure is only used in the function. If the data structure contains some information is used across different functions like,

Foo data
Init(&data);
DoSomething(&data);
DoIfDataHasBlabla(&data);

Then I will say it's fine. But OpOrAdapter is more like a pure function wrapper here. It doesn't convey many data nor handle any logic. It's more like an internal use only structure by certain functions.

We have packed those boilerplate and it does look cleaner now. Thus I was wondering maybe we don't need to pass the helper.

It always has pros and cons in between designs so I just give my opinion over this. Again, I'm fine with the current design.

Chia-hungDuan accepted this revision.Nov 9 2021, 11:47 AM
Chia-hungDuan added inline comments.
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
741–742

Just curious, is this style done by the formatter? The "?:" operator part

This revision was automatically updated to reflect the committed changes.