I am a beginner and have been experimenting with various MLIR components. While building the MLIR program for an IR dialect and understanding the various APIs, it seems like there are 2 ways to create them. One way is to define operations through the ODS framework and then use builder.create(…) which would internally call the build methods associated with every operation and thus there is a restriction offered by the dialect and its operations.The other way which offers more flexibility is to use OperationState class through which arbitrary shapes can be created with very little restrictions on how to build these operations and their respective nested regions and operations. Is my understanding correct? I will be glad if someone can share a little more perspective on this and when should either method be preferred?
Thanks.