On that second thread, I proposed two concrete things – both accessors or simple API additions but the discussion veered in the direction of higher-level principles. Repasting from there: these are only utilities/tools to solve this problem and I feel generally useful even if we don’t change any upstream passes.
-
On querying an Operation's intrinsic (core) vs external/user-defined attributes - #20 by bondhugula
“… it’d be useful to have these two accessors auto-generated on an op:”
void getExternalAttributes(SmallVectorImpl<Attribute> &attrs);
void getIntrinsicAttributes(SmallVectorImpl<Attribute> &attrs);
Both can be auto-generated on a derived op OpTy.
-
On querying an Operation's intrinsic (core) vs external/user-defined attributes - #21 by bondhugula
rewriter.replaceOpcan have an optional argument that if true will transparently propagate all external attributes usinggetExternalAttributesto the new op. This will be useful for users typically for the same op type 1:1 replacements.
PatterRewriter::replaceOp(... , ..., bool propagateExtAttrs = false)
That’ll avoid extra trailing lines everywhere and I feel will easily make things consistent. I’m not sure how replaceOpWithNewOp should be updated – perhaps an optional template arg.
rewriter.replaceOpWithNewOp<newOpTy, /*propagateExtAttrs=*/true>(....)