@@ -51,6 +51,55 @@ class PyPassManager {
5151
5252} // namespace
5353
54+ class PythonPass {
55+ public:
56+ explicit PythonPass (py::object passObj) : passObj(std::move(passObj)) {}
57+
58+ void *construct () {}
59+ void *destruct () {}
60+
61+ MlirLogicalResult *initialize (MlirContext ctx) {}
62+ void *clone () {}
63+
64+ void run (MlirOperation op, MlirExternalPass pass) {}
65+
66+ py::object passObj;
67+ };
68+
69+ template <typename T, typename R>
70+ void *void_cast (R (T::*f)()) {
71+ union {
72+ R (T::*pf)();
73+ void *p;
74+ };
75+ pf = f;
76+ return p;
77+ }
78+
79+ template <typename classT, typename memberT>
80+ union u_ptm_cast {
81+ memberT pmember;
82+ void *pvoid;
83+ };
84+
85+ MlirExternalPassCallbacks makeTestExternalPassCallbacks () {
86+ return (MlirExternalPassCallbacks){
87+ reinterpret_cast <decltype (MlirExternalPassCallbacks::construct)>(
88+ void_cast (&PythonPass::construct)),
89+ reinterpret_cast <decltype (MlirExternalPassCallbacks::destruct)>(
90+ void_cast (&PythonPass::destruct)),
91+ nullptr ,
92+ reinterpret_cast <decltype (MlirExternalPassCallbacks::clone)>(
93+ void_cast (&PythonPass::clone)),
94+ reinterpret_cast <decltype (MlirExternalPassCallbacks::run)>(
95+ u_ptm_cast<PythonPass,
96+ void (PythonPass::*)(MlirOperation, MlirExternalPass)>{
97+ &PythonPass::run}
98+ .pvoid ),
99+
100+ };
101+ }
102+
54103// / Create the `mlir.passmanager` here.
55104void mlir::python::populatePassManagerSubmodule (py::module &m) {
56105 // ----------------------------------------------------------------------------
@@ -114,6 +163,27 @@ void mlir::python::populatePassManagerSubmodule(py::module &m) {
114163 " pipeline" _a,
115164 " Add textual pipeline elements to the pass manager. Throws a "
116165 " ValueError if the pipeline can't be parsed." )
166+ .def_static (
167+ " create_external_pass" ,
168+ [](py::object &passObj) {
169+ PythonPass pass = PythonPass (passObj);
170+
171+ MlirTypeIDAllocator typeIDAllocator = mlirTypeIDAllocatorCreate ();
172+ MlirTypeID passID =
173+ mlirTypeIDAllocatorAllocateTypeID (typeIDAllocator);
174+ MlirStringRef name =
175+ mlirStringRefCreateFromCString (" TestExternalPass" );
176+ MlirStringRef description = mlirStringRefCreateFromCString (" " );
177+ MlirStringRef emptyOpName = mlirStringRefCreateFromCString (" " );
178+ MlirStringRef argument =
179+ mlirStringRefCreateFromCString (" test-external-pass" );
180+
181+ auto cbs = makeTestExternalPassCallbacks ();
182+
183+ MlirPass externalPass =
184+ mlirCreateExternalPass (passID, name, argument, description,
185+ emptyOpName, 0 , NULL , cbs, &pass);
186+ })
117187 .def (
118188 " run" ,
119189 [](PyPassManager &passManager, PyOperationBase &op,
@@ -144,4 +214,8 @@ void mlir::python::populatePassManagerSubmodule(py::module &m) {
144214 },
145215 " Print the textual representation for this PassManager, suitable to "
146216 " be passed to `parse` for round-tripping." );
217+
218+ py::class_<PythonPass>(m, " PythonPass" , py::module_local ())
219+ .def (py::init<>(
220+ [](py::object pass) { return PythonPass (std::move (pass)); }));
147221}
0 commit comments