Stonepia:

tfg by design does not allow optimizations like constant_folding, which would modify tensor’s data. (Or have to recreate a new node and replace the old one).


The attribute is immutable, but the node has a mutable dictionary of attribute (this isn’t specific to TFG, this is standard MLIR): so you can just update the attribute on a node.
That said, when you do constant folding, in general you replace some nodes with a constant node so you have to recreate a new node and replace the old one regardless.



 Stonepia:


Why not create a type instead of attribute in TFG MLIR? As type would allow mutable part  listed in the link.



Types aren’t mutable, the exception you’re pointing at is only intended to be able to implement recursive types (you need to create the Type and then mutate it to add a reference to itself).
Regardless, I’m not sure what is the problem you’re trying to solve with this?



 Stonepia:

As tfg is designed to replace grappler, in grappler, it could easily change those things in NodeDef, how could tfg do these things? Should tfg always create a new node and replace the old one?


As mentioned above, you can’t change the content of an attribute in-place, but you swap individual attributes on an operation. Similarly you can swap the type of individual results of an operation in place. Doing so you don’t modify a type itself, you create a new type and swap it from the old type.
In general MLIR is much more efficient than the proto representation used by Grappler.
If you haven’t seen it yet, I invite you to look into the MLIR tutorial (slides - recording - online step-by-step) as well as this doc that explains the in-memory representation of the IR and in particular the def-use chains.