Use analysis results in transform dialect operations?

I am implementing a transform dialect operation where I would like to resolve function calls to their callee operations and region. In order to do this, I would need the CallGraph analysis.

Are there examples of using results of an analysis in a transform dialect operation?

Is there a somewhat canonical way to provide the result of an analysis to a transform dialect operation from the transform dialect interpreter?

Slight tangent: sounds like you’re trying to implement an inliner as a transform. If that’s right, I’m curious as to what are the benefits over a simple pass.

Generally, we are experimenting with transform dialect operations as a way to exert more fine-grained control over manipulation of the IR :slight_smile:

1 Like

I’m not aware of any attempts to access an analysis, so you’ll have to be the trailblazer. Please report back on the results :slight_smile:

I’d suggest using the TransformState extension mechanism to add a new extension holding a reference to the analysis object. Individual ops can then fetch the extension from the state and access the object. You may need some minor hacks on top of upstream and/or to duplicate the applyTransforms code to get access to the TransformState at the pass level in order to construct the extension at a place that also has access to the analysis manager.

Note that the transform dialect may be overlapping with passes in ways not yet fully understood. Specifically, some transforms driven by ops may be invalidating the analyses, but there’s no way to force them to be recomputed. Feedback and suggestions are most welcome in this area!

3 Likes

Thank you for the tip, that makes sense!

Regarding the comment on overlapping with passes: Indeed this is tricky, and there are potentially issues even with applying canonicalization or folding in between passes. We have found that we need to be quite careful with what cleanup we do in order for the sequence to continue to be valid.

The transform dialect is a super powerful tool for us so far! What I’ve missed the most is strong typing of payloads, although I can’t rule out that I just didn’t figure out how to do it.

For canonicalization, there is a workaround in IREE, but it is a bit heavy. Essentially, it creates a custom version of the canonicalization driver that can notify when an op is replaced with something else in a pattern. That notification is then used to identify, in op-specific way, the op that should replace the erased op in the transform-handle<->payload-op mapping.

On a more general compiler construction side of things, I think we should use canonicalization less often and more localized than what we currently do.

Have you seen [RFC] Type System for the Transform Dialect ? It has been implemented and is available, although not all transform dialect extensions migrated to use it. It is not as strongly typed as it could be, and I wanted to avoid a proliferation of casts, but you may be able to harden it a bit in the dialect. For example, add a custom cast op that statically verifies whether types are compatible (e.g., !transform.op<"scf.for"> should not be casted to !transform.op<"anything-else">.

2 Likes