How to store data inside a custom op

I’ve defined a custom op inside my dialect and I would like make the op store data so I can use it between different passes. I’m using ODS and my naive approach was to do:

def MyCustomOP ... {
  ...

  let extraClassDeclaration = [{
    int data = 0;

    void setMyData(int d) { data = d; };
    int getMyData() { return data; }
  }];
}

Then, when I catch a op inside a MLIR function (specifically, in a OpRewritePattern), I’m able to do this:

myop.setMyData(10);

This works fine. The same op is then catched in another OpRewritePattern, but when I try to fetch the data, it returns 0:

myop.getMyData(); // returns 0

This happens because the smart pointer in the first case (myop) points to a different address than the second one, even though they are exactly the same operation. If I try myop op.getOperation(), it returns the same mlir::Operation on both cases, but the pointer that MLIR is passing me in each side are not the same.

How can I solve this? How should I store data inside a user defined op?

Add an attribute to the op along with other arguments (in args section in ODS). The op itself/these accessors is more a view to the underlying operation and that is where one needs to add the data.

Thanks! That works perfectly.

At first I didn’t think about that because I thought that it was a bad idea since attribute seems to be aimed to store data in ops at the mlir source file (in the .mlir file).

A user could specify an attribute with the same name in the .mlir file and I suppose it would conflict with the attribute I’m using to store data on the op? I don’t know what would happen in that case.

Correct, this boils down to the inherent attributes of an op (MLIR Language Reference - MLIR) and indeed they could but then effectively they are setting the same attribute as you are. So conflict where type is different/some other verification failure would flag theirs as invalid. Else this would effectively just set the attribute. Now as the .mlir file is the textual dump of the intermediate format, users shouldn’t really be authoring it :slight_smile: (I actually find it nice to write but one has to sometimes remind oneself it is not a programming language and there is a “real” frontend producing these).

This is a confusing common issue, so I made it into a compile-time failure with a static_assert in Add a static assertions for custom Op<> to not defined data members (… · llvm/llvm-project@c0edcec · GitHub