MLIR  20.0.0git
IRModule.h
Go to the documentation of this file.
1 //===- IRModules.h - IR Submodules of pybind module -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef MLIR_BINDINGS_PYTHON_IRMODULES_H
11 #define MLIR_BINDINGS_PYTHON_IRMODULES_H
12 
13 #include <optional>
14 #include <utility>
15 #include <vector>
16 
17 #include "Globals.h"
18 #include "PybindUtils.h"
19 
20 #include "mlir-c/AffineExpr.h"
21 #include "mlir-c/AffineMap.h"
22 #include "mlir-c/Diagnostics.h"
23 #include "mlir-c/IR.h"
24 #include "mlir-c/IntegerSet.h"
25 #include "mlir-c/Transforms.h"
27 #include "llvm/ADT/DenseMap.h"
28 
29 namespace mlir {
30 namespace python {
31 
32 class PyBlock;
33 class PyDiagnostic;
34 class PyDiagnosticHandler;
35 class PyInsertionPoint;
36 class PyLocation;
37 class DefaultingPyLocation;
38 class PyMlirContext;
39 class DefaultingPyMlirContext;
40 class PyModule;
41 class PyOperation;
42 class PyOperationBase;
43 class PyType;
44 class PySymbolTable;
45 class PyValue;
46 
47 /// Template for a reference to a concrete type which captures a python
48 /// reference to its underlying python object.
49 template <typename T>
50 class PyObjectRef {
51 public:
52  PyObjectRef(T *referrent, pybind11::object object)
53  : referrent(referrent), object(std::move(object)) {
54  assert(this->referrent &&
55  "cannot construct PyObjectRef with null referrent");
56  assert(this->object && "cannot construct PyObjectRef with null object");
57  }
58  PyObjectRef(PyObjectRef &&other) noexcept
59  : referrent(other.referrent), object(std::move(other.object)) {
60  other.referrent = nullptr;
61  assert(!other.object);
62  }
63  PyObjectRef(const PyObjectRef &other)
64  : referrent(other.referrent), object(other.object /* copies */) {}
65  ~PyObjectRef() = default;
66 
67  int getRefCount() {
68  if (!object)
69  return 0;
70  return object.ref_count();
71  }
72 
73  /// Releases the object held by this instance, returning it.
74  /// This is the proper thing to return from a function that wants to return
75  /// the reference. Note that this does not work from initializers.
76  pybind11::object releaseObject() {
77  assert(referrent && object);
78  referrent = nullptr;
79  auto stolen = std::move(object);
80  return stolen;
81  }
82 
83  T *get() { return referrent; }
84  T *operator->() {
85  assert(referrent && object);
86  return referrent;
87  }
88  pybind11::object getObject() {
89  assert(referrent && object);
90  return object;
91  }
92  operator bool() const { return referrent && object; }
93 
94 private:
95  T *referrent;
96  pybind11::object object;
97 };
98 
99 /// Tracks an entry in the thread context stack. New entries are pushed onto
100 /// here for each with block that activates a new InsertionPoint, Context or
101 /// Location.
102 ///
103 /// Pushing either a Location or InsertionPoint also pushes its associated
104 /// Context. Pushing a Context will not modify the Location or InsertionPoint
105 /// unless if they are from a different context, in which case, they are
106 /// cleared.
108 public:
109  enum class FrameKind {
110  Context,
112  Location,
113  };
114 
115  PyThreadContextEntry(FrameKind frameKind, pybind11::object context,
116  pybind11::object insertionPoint,
117  pybind11::object location)
118  : context(std::move(context)), insertionPoint(std::move(insertionPoint)),
119  location(std::move(location)), frameKind(frameKind) {}
120 
121  /// Gets the top of stack context and return nullptr if not defined.
123 
124  /// Gets the top of stack insertion point and return nullptr if not defined.
126 
127  /// Gets the top of stack location and returns nullptr if not defined.
128  static PyLocation *getDefaultLocation();
129 
133  FrameKind getFrameKind() { return frameKind; }
134 
135  /// Stack management.
137  static pybind11::object pushContext(PyMlirContext &context);
138  static void popContext(PyMlirContext &context);
139  static pybind11::object pushInsertionPoint(PyInsertionPoint &insertionPoint);
140  static void popInsertionPoint(PyInsertionPoint &insertionPoint);
141  static pybind11::object pushLocation(PyLocation &location);
142  static void popLocation(PyLocation &location);
143 
144  /// Gets the thread local stack.
145  static std::vector<PyThreadContextEntry> &getStack();
146 
147 private:
148  static void push(FrameKind frameKind, pybind11::object context,
149  pybind11::object insertionPoint, pybind11::object location);
150 
151  /// An object reference to the PyContext.
152  pybind11::object context;
153  /// An object reference to the current insertion point.
154  pybind11::object insertionPoint;
155  /// An object reference to the current location.
156  pybind11::object location;
157  // The kind of push that was performed.
158  FrameKind frameKind;
159 };
160 
161 /// Wrapper around MlirContext.
164 public:
165  PyMlirContext() = delete;
166  PyMlirContext(const PyMlirContext &) = delete;
168 
169  /// For the case of a python __init__ (py::init) method, pybind11 is quite
170  /// strict about needing to return a pointer that is not yet associated to
171  /// an py::object. Since the forContext() method acts like a pool, possibly
172  /// returning a recycled context, it does not satisfy this need. The usual
173  /// way in python to accomplish such a thing is to override __new__, but
174  /// that is also not supported by pybind11. Instead, we use this entry
175  /// point which always constructs a fresh context (which cannot alias an
176  /// existing one because it is fresh).
178 
179  /// Returns a context reference for the singleton PyMlirContext wrapper for
180  /// the given context.
181  static PyMlirContextRef forContext(MlirContext context);
182  ~PyMlirContext();
183 
184  /// Accesses the underlying MlirContext.
185  MlirContext get() { return context; }
186 
187  /// Gets a strong reference to this context, which will ensure it is kept
188  /// alive for the life of the reference.
190  return PyMlirContextRef(this, pybind11::cast(this));
191  }
192 
193  /// Gets a capsule wrapping the void* within the MlirContext.
194  pybind11::object getCapsule();
195 
196  /// Creates a PyMlirContext from the MlirContext wrapped by a capsule.
197  /// Note that PyMlirContext instances are uniqued, so the returned object
198  /// may be a pre-existing object. Ownership of the underlying MlirContext
199  /// is taken by calling this function.
200  static pybind11::object createFromCapsule(pybind11::object capsule);
201 
202  /// Gets the count of live context objects. Used for testing.
203  static size_t getLiveCount();
204 
205  /// Get a list of Python objects which are still in the live context map.
206  std::vector<PyOperation *> getLiveOperationObjects();
207 
208  /// Gets the count of live operations associated with this context.
209  /// Used for testing.
210  size_t getLiveOperationCount();
211 
212  /// Clears the live operations map, returning the number of entries which were
213  /// invalidated. To be used as a safety mechanism so that API end-users can't
214  /// corrupt by holding references they shouldn't have accessed in the first
215  /// place.
216  size_t clearLiveOperations();
217 
218  /// Removes an operation from the live operations map and sets it invalid.
219  /// This is useful for when some non-bindings code destroys the operation and
220  /// the bindings need to made aware. For example, in the case when pass
221  /// manager is run.
222  ///
223  /// Note that this does *NOT* clear the nested operations.
224  void clearOperation(MlirOperation op);
225 
226  /// Clears all operations nested inside the given op using
227  /// `clearOperation(MlirOperation)`.
229  void clearOperationsInside(MlirOperation op);
230 
231  /// Clears the operaiton _and_ all operations inside using
232  /// `clearOperation(MlirOperation)`.
234 
235  /// Gets the count of live modules associated with this context.
236  /// Used for testing.
237  size_t getLiveModuleCount();
238 
239  /// Enter and exit the context manager.
240  pybind11::object contextEnter();
241  void contextExit(const pybind11::object &excType,
242  const pybind11::object &excVal,
243  const pybind11::object &excTb);
244 
245  /// Attaches a Python callback as a diagnostic handler, returning a
246  /// registration object (internally a PyDiagnosticHandler).
247  pybind11::object attachDiagnosticHandler(pybind11::object callback);
248 
249  /// Controls whether error diagnostics should be propagated to diagnostic
250  /// handlers, instead of being captured by `ErrorCapture`.
251  void setEmitErrorDiagnostics(bool value) { emitErrorDiagnostics = value; }
252  struct ErrorCapture;
253 
254 private:
255  PyMlirContext(MlirContext context);
256 
257  // Interns the mapping of live MlirContext::ptr to PyMlirContext instances,
258  // preserving the relationship that an MlirContext maps to a single
259  // PyMlirContext wrapper. This could be replaced in the future with an
260  // extension mechanism on the MlirContext for stashing user pointers.
261  // Note that this holds a handle, which does not imply ownership.
262  // Mappings will be removed when the context is destructed.
263  using LiveContextMap = llvm::DenseMap<void *, PyMlirContext *>;
264  static LiveContextMap &getLiveContexts();
265 
266  // Interns all live modules associated with this context. Modules tracked
267  // in this map are valid. When a module is invalidated, it is removed
268  // from this map, and while it still exists as an instance, any
269  // attempt to access it will raise an error.
270  using LiveModuleMap =
272  LiveModuleMap liveModules;
273 
274  // Interns all live operations associated with this context. Operations
275  // tracked in this map are valid. When an operation is invalidated, it is
276  // removed from this map, and while it still exists as an instance, any
277  // attempt to access it will raise an error.
278  using LiveOperationMap =
280  LiveOperationMap liveOperations;
281 
282  bool emitErrorDiagnostics = false;
283 
284  MlirContext context;
285  friend class PyModule;
286  friend class PyOperation;
287 };
288 
289 /// Used in function arguments when None should resolve to the current context
290 /// manager set instance.
292  : public Defaulting<DefaultingPyMlirContext, PyMlirContext> {
293 public:
295  static constexpr const char kTypeDescription[] = "mlir.ir.Context";
296  static PyMlirContext &resolve();
297 };
298 
299 /// Base class for all objects that directly or indirectly depend on an
300 /// MlirContext. The lifetime of the context will extend at least to the
301 /// lifetime of these instances.
302 /// Immutable objects that depend on a context extend this directly.
304 public:
305  BaseContextObject(PyMlirContextRef ref) : contextRef(std::move(ref)) {
306  assert(this->contextRef &&
307  "context object constructed with null context ref");
308  }
309 
310  /// Accesses the context reference.
311  PyMlirContextRef &getContext() { return contextRef; }
312 
313 private:
314  PyMlirContextRef contextRef;
315 };
316 
317 /// Wrapper around an MlirLocation.
319 public:
320  PyLocation(PyMlirContextRef contextRef, MlirLocation loc)
321  : BaseContextObject(std::move(contextRef)), loc(loc) {}
322 
323  operator MlirLocation() const { return loc; }
324  MlirLocation get() const { return loc; }
325 
326  /// Enter and exit the context manager.
327  pybind11::object contextEnter();
328  void contextExit(const pybind11::object &excType,
329  const pybind11::object &excVal,
330  const pybind11::object &excTb);
331 
332  /// Gets a capsule wrapping the void* within the MlirLocation.
333  pybind11::object getCapsule();
334 
335  /// Creates a PyLocation from the MlirLocation wrapped by a capsule.
336  /// Note that PyLocation instances are uniqued, so the returned object
337  /// may be a pre-existing object. Ownership of the underlying MlirLocation
338  /// is taken by calling this function.
339  static PyLocation createFromCapsule(pybind11::object capsule);
340 
341 private:
342  MlirLocation loc;
343 };
344 
345 /// Python class mirroring the C MlirDiagnostic struct. Note that these structs
346 /// are only valid for the duration of a diagnostic callback and attempting
347 /// to access them outside of that will raise an exception. This applies to
348 /// nested diagnostics (in the notes) as well.
350 public:
351  PyDiagnostic(MlirDiagnostic diagnostic) : diagnostic(diagnostic) {}
352  void invalidate();
353  bool isValid() { return valid; }
356  pybind11::str getMessage();
357  pybind11::tuple getNotes();
358 
359  /// Materialized diagnostic information. This is safe to access outside the
360  /// diagnostic callback.
361  struct DiagnosticInfo {
364  std::string message;
365  std::vector<DiagnosticInfo> notes;
366  };
368 
369 private:
370  MlirDiagnostic diagnostic;
371 
372  void checkValid();
373  /// If notes have been materialized from the diagnostic, then this will
374  /// be populated with the corresponding objects (all castable to
375  /// PyDiagnostic).
376  std::optional<pybind11::tuple> materializedNotes;
377  bool valid = true;
378 };
379 
380 /// Represents a diagnostic handler attached to the context. The handler's
381 /// callback will be invoked with PyDiagnostic instances until the detach()
382 /// method is called or the context is destroyed. A diagnostic handler can be
383 /// the subject of a `with` block, which will detach it when the block exits.
384 ///
385 /// Since diagnostic handlers can call back into Python code which can do
386 /// unsafe things (i.e. recursively emitting diagnostics, raising exceptions,
387 /// etc), this is generally not deemed to be a great user-level API. Users
388 /// should generally use some form of DiagnosticCollector. If the handler raises
389 /// any exceptions, they will just be emitted to stderr and dropped.
390 ///
391 /// The unique usage of this class means that its lifetime management is
392 /// different from most other parts of the API. Instances are always created
393 /// in an attached state and can transition to a detached state by either:
394 /// a) The context being destroyed and unregistering all handlers.
395 /// b) An explicit call to detach().
396 /// The object may remain live from a Python perspective for an arbitrary time
397 /// after detachment, but there is nothing the user can do with it (since there
398 /// is no way to attach an existing handler object).
400 public:
401  PyDiagnosticHandler(MlirContext context, pybind11::object callback);
403 
404  bool isAttached() { return registeredID.has_value(); }
405  bool getHadError() { return hadError; }
406 
407  /// Detaches the handler. Does nothing if not attached.
408  void detach();
409 
410  pybind11::object contextEnter() { return pybind11::cast(this); }
411  void contextExit(const pybind11::object &excType,
412  const pybind11::object &excVal,
413  const pybind11::object &excTb) {
414  detach();
415  }
416 
417 private:
418  MlirContext context;
419  pybind11::object callback;
420  std::optional<MlirDiagnosticHandlerID> registeredID;
421  bool hadError = false;
422  friend class PyMlirContext;
423 };
424 
425 /// RAII object that captures any error diagnostics emitted to the provided
426 /// context.
429  : ctx(ctx), handlerID(mlirContextAttachDiagnosticHandler(
430  ctx->get(), handler, /*userData=*/this,
431  /*deleteUserData=*/nullptr)) {}
433  mlirContextDetachDiagnosticHandler(ctx->get(), handlerID);
434  assert(errors.empty() && "unhandled captured errors");
435  }
436 
437  std::vector<PyDiagnostic::DiagnosticInfo> take() {
438  return std::move(errors);
439  };
440 
441 private:
442  PyMlirContextRef ctx;
443  MlirDiagnosticHandlerID handlerID;
444  std::vector<PyDiagnostic::DiagnosticInfo> errors;
445 
446  static MlirLogicalResult handler(MlirDiagnostic diag, void *userData);
447 };
448 
449 /// Wrapper around an MlirDialect. This is exported as `DialectDescriptor` in
450 /// order to differentiate it from the `Dialect` base class which is extended by
451 /// plugins which extend dialect functionality through extension python code.
452 /// This should be seen as the "low-level" object and `Dialect` as the
453 /// high-level, user facing object.
455 public:
456  PyDialectDescriptor(PyMlirContextRef contextRef, MlirDialect dialect)
457  : BaseContextObject(std::move(contextRef)), dialect(dialect) {}
458 
459  MlirDialect get() { return dialect; }
460 
461 private:
462  MlirDialect dialect;
463 };
464 
465 /// User-level object for accessing dialects with dotted syntax such as:
466 /// ctx.dialect.std
468 public:
470  : BaseContextObject(std::move(contextRef)) {}
471 
472  MlirDialect getDialectForKey(const std::string &key, bool attrError);
473 };
474 
475 /// User-level dialect object. For dialects that have a registered extension,
476 /// this will be the base class of the extension dialect type. For un-extended,
477 /// objects of this type will be returned directly.
478 class PyDialect {
479 public:
480  PyDialect(pybind11::object descriptor) : descriptor(std::move(descriptor)) {}
481 
482  pybind11::object getDescriptor() { return descriptor; }
483 
484 private:
485  pybind11::object descriptor;
486 };
487 
488 /// Wrapper around an MlirDialectRegistry.
489 /// Upon construction, the Python wrapper takes ownership of the
490 /// underlying MlirDialectRegistry.
492 public:
494  PyDialectRegistry(MlirDialectRegistry registry) : registry(registry) {}
496  if (!mlirDialectRegistryIsNull(registry))
497  mlirDialectRegistryDestroy(registry);
498  }
501  : registry(other.registry) {
502  other.registry = {nullptr};
503  }
504 
505  operator MlirDialectRegistry() const { return registry; }
506  MlirDialectRegistry get() const { return registry; }
507 
508  pybind11::object getCapsule();
509  static PyDialectRegistry createFromCapsule(pybind11::object capsule);
510 
511 private:
512  MlirDialectRegistry registry;
513 };
514 
515 /// Used in function arguments when None should resolve to the current context
516 /// manager set instance.
518  : public Defaulting<DefaultingPyLocation, PyLocation> {
519 public:
521  static constexpr const char kTypeDescription[] = "mlir.ir.Location";
522  static PyLocation &resolve();
523 
524  operator MlirLocation() const { return *get(); }
525 };
526 
527 /// Wrapper around MlirModule.
528 /// This is the top-level, user-owned object that contains regions/ops/blocks.
529 class PyModule;
531 class PyModule : public BaseContextObject {
532 public:
533  /// Returns a PyModule reference for the given MlirModule. This may return
534  /// a pre-existing or new object.
535  static PyModuleRef forModule(MlirModule module);
536  PyModule(PyModule &) = delete;
537  PyModule(PyMlirContext &&) = delete;
538  ~PyModule();
539 
540  /// Gets the backing MlirModule.
541  MlirModule get() { return module; }
542 
543  /// Gets a strong reference to this module.
545  return PyModuleRef(this,
546  pybind11::reinterpret_borrow<pybind11::object>(handle));
547  }
548 
549  /// Gets a capsule wrapping the void* within the MlirModule.
550  /// Note that the module does not (yet) provide a corresponding factory for
551  /// constructing from a capsule as that would require uniquing PyModule
552  /// instances, which is not currently done.
553  pybind11::object getCapsule();
554 
555  /// Creates a PyModule from the MlirModule wrapped by a capsule.
556  /// Note that PyModule instances are uniqued, so the returned object
557  /// may be a pre-existing object. Ownership of the underlying MlirModule
558  /// is taken by calling this function.
559  static pybind11::object createFromCapsule(pybind11::object capsule);
560 
561 private:
562  PyModule(PyMlirContextRef contextRef, MlirModule module);
563  MlirModule module;
564  pybind11::handle handle;
565 };
566 
567 class PyAsmState;
568 
569 /// Base class for PyOperation and PyOpView which exposes the primary, user
570 /// visible methods for manipulating it.
572 public:
573  virtual ~PyOperationBase() = default;
574  /// Implements the bound 'print' method and helps with others.
575  void print(std::optional<int64_t> largeElementsLimit, bool enableDebugInfo,
576  bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope,
577  bool assumeVerified, py::object fileObject, bool binary,
578  bool skipRegions);
579  void print(PyAsmState &state, py::object fileObject, bool binary);
580 
581  pybind11::object getAsm(bool binary,
582  std::optional<int64_t> largeElementsLimit,
583  bool enableDebugInfo, bool prettyDebugInfo,
584  bool printGenericOpForm, bool useLocalScope,
585  bool assumeVerified, bool skipRegions);
586 
587  // Implement the bound 'writeBytecode' method.
588  void writeBytecode(const pybind11::object &fileObject,
589  std::optional<int64_t> bytecodeVersion);
590 
591  // Implement the walk method.
592  void walk(std::function<MlirWalkResult(MlirOperation)> callback,
593  MlirWalkOrder walkOrder);
594 
595  /// Moves the operation before or after the other operation.
596  void moveAfter(PyOperationBase &other);
597  void moveBefore(PyOperationBase &other);
598 
599  /// Verify the operation. Throws `MLIRError` if verification fails, and
600  /// returns `true` otherwise.
601  bool verify();
602 
603  /// Each must provide access to the raw Operation.
604  virtual PyOperation &getOperation() = 0;
605 };
606 
607 /// Wrapper around PyOperation.
608 /// Operations exist in either an attached (dependent) or detached (top-level)
609 /// state. In the detached state (as on creation), an operation is owned by
610 /// the creator and its lifetime extends either until its reference count
611 /// drops to zero or it is attached to a parent, at which point its lifetime
612 /// is bounded by its top-level parent reference.
613 class PyOperation;
616 public:
617  ~PyOperation() override;
618  PyOperation &getOperation() override { return *this; }
619 
620  /// Returns a PyOperation for the given MlirOperation, optionally associating
621  /// it with a parentKeepAlive.
622  static PyOperationRef
623  forOperation(PyMlirContextRef contextRef, MlirOperation operation,
624  pybind11::object parentKeepAlive = pybind11::object());
625 
626  /// Creates a detached operation. The operation must not be associated with
627  /// any existing live operation.
628  static PyOperationRef
629  createDetached(PyMlirContextRef contextRef, MlirOperation operation,
630  pybind11::object parentKeepAlive = pybind11::object());
631 
632  /// Parses a source string (either text assembly or bytecode), creating a
633  /// detached operation.
634  static PyOperationRef parse(PyMlirContextRef contextRef,
635  const std::string &sourceStr,
636  const std::string &sourceName);
637 
638  /// Detaches the operation from its parent block and updates its state
639  /// accordingly.
642  setDetached();
643  parentKeepAlive = pybind11::object();
644  }
645 
646  /// Gets the backing operation.
647  operator MlirOperation() const { return get(); }
648  MlirOperation get() const {
649  checkValid();
650  return operation;
651  }
652 
654  return PyOperationRef(
655  this, pybind11::reinterpret_borrow<pybind11::object>(handle));
656  }
657 
658  bool isAttached() { return attached; }
659  void setAttached(const pybind11::object &parent = pybind11::object()) {
660  assert(!attached && "operation already attached");
661  attached = true;
662  }
663  void setDetached() {
664  assert(attached && "operation already detached");
665  attached = false;
666  }
667  void checkValid() const;
668 
669  /// Gets the owning block or raises an exception if the operation has no
670  /// owning block.
671  PyBlock getBlock();
672 
673  /// Gets the parent operation or raises an exception if the operation has
674  /// no parent.
675  std::optional<PyOperationRef> getParentOperation();
676 
677  /// Gets a capsule wrapping the void* within the MlirOperation.
678  pybind11::object getCapsule();
679 
680  /// Creates a PyOperation from the MlirOperation wrapped by a capsule.
681  /// Ownership of the underlying MlirOperation is taken by calling this
682  /// function.
683  static pybind11::object createFromCapsule(pybind11::object capsule);
684 
685  /// Creates an operation. See corresponding python docstring.
686  static pybind11::object
687  create(const std::string &name, std::optional<std::vector<PyType *>> results,
688  std::optional<std::vector<PyValue *>> operands,
689  std::optional<pybind11::dict> attributes,
690  std::optional<std::vector<PyBlock *>> successors, int regions,
691  DefaultingPyLocation location, const pybind11::object &ip,
692  bool inferType);
693 
694  /// Creates an OpView suitable for this operation.
695  pybind11::object createOpView();
696 
697  /// Erases the underlying MlirOperation, removes its pointer from the
698  /// parent context's live operations map, and sets the valid bit false.
699  void erase();
700 
701  /// Invalidate the operation.
702  void setInvalid() { valid = false; }
703 
704  /// Clones this operation.
705  pybind11::object clone(const pybind11::object &ip);
706 
707 private:
708  PyOperation(PyMlirContextRef contextRef, MlirOperation operation);
709  static PyOperationRef createInstance(PyMlirContextRef contextRef,
710  MlirOperation operation,
711  pybind11::object parentKeepAlive);
712 
713  MlirOperation operation;
714  pybind11::handle handle;
715  // Keeps the parent alive, regardless of whether it is an Operation or
716  // Module.
717  // TODO: As implemented, this facility is only sufficient for modeling the
718  // trivial module parent back-reference. Generalize this to also account for
719  // transitions from detached to attached and address TODOs in the
720  // ir_operation.py regarding testing corresponding lifetime guarantees.
721  pybind11::object parentKeepAlive;
722  bool attached = true;
723  bool valid = true;
724 
725  friend class PyOperationBase;
726  friend class PySymbolTable;
727 };
728 
729 /// A PyOpView is equivalent to the C++ "Op" wrappers: these are the basis for
730 /// providing more instance-specific accessors and serve as the base class for
731 /// custom ODS-style operation classes. Since this class is subclass on the
732 /// python side, it must present an __init__ method that operates in pure
733 /// python types.
734 class PyOpView : public PyOperationBase {
735 public:
736  PyOpView(const pybind11::object &operationObject);
737  PyOperation &getOperation() override { return operation; }
738 
739  pybind11::object getOperationObject() { return operationObject; }
740 
741  static pybind11::object buildGeneric(
742  const pybind11::object &cls, std::optional<pybind11::list> resultTypeList,
743  pybind11::list operandList, std::optional<pybind11::dict> attributes,
744  std::optional<std::vector<PyBlock *>> successors,
745  std::optional<int> regions, DefaultingPyLocation location,
746  const pybind11::object &maybeIp);
747 
748  /// Construct an instance of a class deriving from OpView, bypassing its
749  /// `__init__` method. The derived class will typically define a constructor
750  /// that provides a convenient builder, but we need to side-step this when
751  /// constructing an `OpView` for an already-built operation.
752  ///
753  /// The caller is responsible for verifying that `operation` is a valid
754  /// operation to construct `cls` with.
755  static pybind11::object constructDerived(const pybind11::object &cls,
756  const PyOperation &operation);
757 
758 private:
759  PyOperation &operation; // For efficient, cast-free access from C++
760  pybind11::object operationObject; // Holds the reference.
761 };
762 
763 /// Wrapper around an MlirRegion.
764 /// Regions are managed completely by their containing operation. Unlike the
765 /// C++ API, the python API does not support detached regions.
766 class PyRegion {
767 public:
768  PyRegion(PyOperationRef parentOperation, MlirRegion region)
769  : parentOperation(std::move(parentOperation)), region(region) {
770  assert(!mlirRegionIsNull(region) && "python region cannot be null");
771  }
772  operator MlirRegion() const { return region; }
773 
774  MlirRegion get() { return region; }
775  PyOperationRef &getParentOperation() { return parentOperation; }
776 
777  void checkValid() { return parentOperation->checkValid(); }
778 
779 private:
780  PyOperationRef parentOperation;
781  MlirRegion region;
782 };
783 
784 /// Wrapper around an MlirAsmState.
785 class PyAsmState {
786 public:
787  PyAsmState(MlirValue value, bool useLocalScope) {
788  flags = mlirOpPrintingFlagsCreate();
789  // The OpPrintingFlags are not exposed Python side, create locally and
790  // associate lifetime with the state.
791  if (useLocalScope)
793  state = mlirAsmStateCreateForValue(value, flags);
794  }
795 
796  PyAsmState(PyOperationBase &operation, bool useLocalScope) {
797  flags = mlirOpPrintingFlagsCreate();
798  // The OpPrintingFlags are not exposed Python side, create locally and
799  // associate lifetime with the state.
800  if (useLocalScope)
802  state =
803  mlirAsmStateCreateForOperation(operation.getOperation().get(), flags);
804  }
806  // Delete copy constructors.
807  PyAsmState(PyAsmState &other) = delete;
808  PyAsmState(const PyAsmState &other) = delete;
809 
810  MlirAsmState get() { return state; }
811 
812 private:
813  MlirAsmState state;
814  MlirOpPrintingFlags flags;
815 };
816 
817 /// Wrapper around an MlirBlock.
818 /// Blocks are managed completely by their containing operation. Unlike the
819 /// C++ API, the python API does not support detached blocks.
820 class PyBlock {
821 public:
822  PyBlock(PyOperationRef parentOperation, MlirBlock block)
823  : parentOperation(std::move(parentOperation)), block(block) {
824  assert(!mlirBlockIsNull(block) && "python block cannot be null");
825  }
826 
827  MlirBlock get() { return block; }
828  PyOperationRef &getParentOperation() { return parentOperation; }
829 
830  void checkValid() { return parentOperation->checkValid(); }
831 
832  /// Gets a capsule wrapping the void* within the MlirBlock.
833  pybind11::object getCapsule();
834 
835 private:
836  PyOperationRef parentOperation;
837  MlirBlock block;
838 };
839 
840 /// An insertion point maintains a pointer to a Block and a reference operation.
841 /// Calls to insert() will insert a new operation before the
842 /// reference operation. If the reference operation is null, then appends to
843 /// the end of the block.
845 public:
846  /// Creates an insertion point positioned after the last operation in the
847  /// block, but still inside the block.
848  PyInsertionPoint(PyBlock &block);
849  /// Creates an insertion point positioned before a reference operation.
850  PyInsertionPoint(PyOperationBase &beforeOperationBase);
851 
852  /// Shortcut to create an insertion point at the beginning of the block.
853  static PyInsertionPoint atBlockBegin(PyBlock &block);
854  /// Shortcut to create an insertion point before the block terminator.
856 
857  /// Inserts an operation.
858  void insert(PyOperationBase &operationBase);
859 
860  /// Enter and exit the context manager.
861  pybind11::object contextEnter();
862  void contextExit(const pybind11::object &excType,
863  const pybind11::object &excVal,
864  const pybind11::object &excTb);
865 
866  PyBlock &getBlock() { return block; }
867  std::optional<PyOperationRef> &getRefOperation() { return refOperation; }
868 
869 private:
870  // Trampoline constructor that avoids null initializing members while
871  // looking up parents.
872  PyInsertionPoint(PyBlock block, std::optional<PyOperationRef> refOperation)
873  : refOperation(std::move(refOperation)), block(std::move(block)) {}
874 
875  std::optional<PyOperationRef> refOperation;
876  PyBlock block;
877 };
878 /// Wrapper around the generic MlirType.
879 /// The lifetime of a type is bound by the PyContext that created it.
880 class PyType : public BaseContextObject {
881 public:
882  PyType(PyMlirContextRef contextRef, MlirType type)
883  : BaseContextObject(std::move(contextRef)), type(type) {}
884  bool operator==(const PyType &other) const;
885  operator MlirType() const { return type; }
886  MlirType get() const { return type; }
887 
888  /// Gets a capsule wrapping the void* within the MlirType.
889  pybind11::object getCapsule();
890 
891  /// Creates a PyType from the MlirType wrapped by a capsule.
892  /// Note that PyType instances are uniqued, so the returned object
893  /// may be a pre-existing object. Ownership of the underlying MlirType
894  /// is taken by calling this function.
895  static PyType createFromCapsule(pybind11::object capsule);
896 
897 private:
898  MlirType type;
899 };
900 
901 /// A TypeID provides an efficient and unique identifier for a specific C++
902 /// type. This allows for a C++ type to be compared, hashed, and stored in an
903 /// opaque context. This class wraps around the generic MlirTypeID.
904 class PyTypeID {
905 public:
906  PyTypeID(MlirTypeID typeID) : typeID(typeID) {}
907  // Note, this tests whether the underlying TypeIDs are the same,
908  // not whether the wrapper MlirTypeIDs are the same, nor whether
909  // the PyTypeID objects are the same (i.e., PyTypeID is a value type).
910  bool operator==(const PyTypeID &other) const;
911  operator MlirTypeID() const { return typeID; }
912  MlirTypeID get() { return typeID; }
913 
914  /// Gets a capsule wrapping the void* within the MlirTypeID.
915  pybind11::object getCapsule();
916 
917  /// Creates a PyTypeID from the MlirTypeID wrapped by a capsule.
918  static PyTypeID createFromCapsule(pybind11::object capsule);
919 
920 private:
921  MlirTypeID typeID;
922 };
923 
924 /// CRTP base classes for Python types that subclass Type and should be
925 /// castable from it (i.e. via something like IntegerType(t)).
926 /// By default, type class hierarchies are one level deep (i.e. a
927 /// concrete type class extends PyType); however, intermediate python-visible
928 /// base classes can be modeled by specifying a BaseTy.
929 template <typename DerivedTy, typename BaseTy = PyType>
930 class PyConcreteType : public BaseTy {
931 public:
932  // Derived classes must define statics for:
933  // IsAFunctionTy isaFunction
934  // const char *pyClassName
935  using ClassTy = pybind11::class_<DerivedTy, BaseTy>;
936  using IsAFunctionTy = bool (*)(MlirType);
937  using GetTypeIDFunctionTy = MlirTypeID (*)();
938  static constexpr GetTypeIDFunctionTy getTypeIdFunction = nullptr;
939 
940  PyConcreteType() = default;
941  PyConcreteType(PyMlirContextRef contextRef, MlirType t)
942  : BaseTy(std::move(contextRef), t) {}
944  : PyConcreteType(orig.getContext(), castFrom(orig)) {}
945 
946  static MlirType castFrom(PyType &orig) {
947  if (!DerivedTy::isaFunction(orig)) {
948  auto origRepr = pybind11::repr(pybind11::cast(orig)).cast<std::string>();
949  throw py::value_error((llvm::Twine("Cannot cast type to ") +
950  DerivedTy::pyClassName + " (from " + origRepr +
951  ")")
952  .str());
953  }
954  return orig;
955  }
956 
957  static void bind(pybind11::module &m) {
958  auto cls = ClassTy(m, DerivedTy::pyClassName, pybind11::module_local());
959  cls.def(pybind11::init<PyType &>(), pybind11::keep_alive<0, 1>(),
960  pybind11::arg("cast_from_type"));
961  cls.def_static(
962  "isinstance",
963  [](PyType &otherType) -> bool {
964  return DerivedTy::isaFunction(otherType);
965  },
966  pybind11::arg("other"));
967  cls.def_property_readonly_static(
968  "static_typeid", [](py::object & /*class*/) -> MlirTypeID {
969  if (DerivedTy::getTypeIdFunction)
970  return DerivedTy::getTypeIdFunction();
971  throw py::attribute_error(
972  (DerivedTy::pyClassName + llvm::Twine(" has no typeid.")).str());
973  });
974  cls.def_property_readonly("typeid", [](PyType &self) {
975  return py::cast(self).attr("typeid").cast<MlirTypeID>();
976  });
977  cls.def("__repr__", [](DerivedTy &self) {
978  PyPrintAccumulator printAccum;
979  printAccum.parts.append(DerivedTy::pyClassName);
980  printAccum.parts.append("(");
981  mlirTypePrint(self, printAccum.getCallback(), printAccum.getUserData());
982  printAccum.parts.append(")");
983  return printAccum.join();
984  });
985 
986  if (DerivedTy::getTypeIdFunction) {
988  DerivedTy::getTypeIdFunction(),
989  pybind11::cpp_function(
990  [](PyType pyType) -> DerivedTy { return pyType; }));
991  }
992 
993  DerivedTy::bindDerived(cls);
994  }
995 
996  /// Implemented by derived classes to add methods to the Python subclass.
997  static void bindDerived(ClassTy &m) {}
998 };
999 
1000 /// Wrapper around the generic MlirAttribute.
1001 /// The lifetime of a type is bound by the PyContext that created it.
1003 public:
1004  PyAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
1005  : BaseContextObject(std::move(contextRef)), attr(attr) {}
1006  bool operator==(const PyAttribute &other) const;
1007  operator MlirAttribute() const { return attr; }
1008  MlirAttribute get() const { return attr; }
1009 
1010  /// Gets a capsule wrapping the void* within the MlirAttribute.
1011  pybind11::object getCapsule();
1012 
1013  /// Creates a PyAttribute from the MlirAttribute wrapped by a capsule.
1014  /// Note that PyAttribute instances are uniqued, so the returned object
1015  /// may be a pre-existing object. Ownership of the underlying MlirAttribute
1016  /// is taken by calling this function.
1017  static PyAttribute createFromCapsule(pybind11::object capsule);
1018 
1019 private:
1020  MlirAttribute attr;
1021 };
1022 
1023 /// Represents a Python MlirNamedAttr, carrying an optional owned name.
1024 /// TODO: Refactor this and the C-API to be based on an Identifier owned
1025 /// by the context so as to avoid ownership issues here.
1027 public:
1028  /// Constructs a PyNamedAttr that retains an owned name. This should be
1029  /// used in any code that originates an MlirNamedAttribute from a python
1030  /// string.
1031  /// The lifetime of the PyNamedAttr must extend to the lifetime of the
1032  /// passed attribute.
1033  PyNamedAttribute(MlirAttribute attr, std::string ownedName);
1034 
1036 
1037 private:
1038  // Since the MlirNamedAttr contains an internal pointer to the actual
1039  // memory of the owned string, it must be heap allocated to remain valid.
1040  // Otherwise, strings that fit within the small object optimization threshold
1041  // will have their memory address change as the containing object is moved,
1042  // resulting in an invalid aliased pointer.
1043  std::unique_ptr<std::string> ownedName;
1044 };
1045 
1046 /// CRTP base classes for Python attributes that subclass Attribute and should
1047 /// be castable from it (i.e. via something like StringAttr(attr)).
1048 /// By default, attribute class hierarchies are one level deep (i.e. a
1049 /// concrete attribute class extends PyAttribute); however, intermediate
1050 /// python-visible base classes can be modeled by specifying a BaseTy.
1051 template <typename DerivedTy, typename BaseTy = PyAttribute>
1052 class PyConcreteAttribute : public BaseTy {
1053 public:
1054  // Derived classes must define statics for:
1055  // IsAFunctionTy isaFunction
1056  // const char *pyClassName
1057  using ClassTy = pybind11::class_<DerivedTy, BaseTy>;
1058  using IsAFunctionTy = bool (*)(MlirAttribute);
1059  using GetTypeIDFunctionTy = MlirTypeID (*)();
1060  static constexpr GetTypeIDFunctionTy getTypeIdFunction = nullptr;
1061 
1062  PyConcreteAttribute() = default;
1063  PyConcreteAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
1064  : BaseTy(std::move(contextRef), attr) {}
1066  : PyConcreteAttribute(orig.getContext(), castFrom(orig)) {}
1067 
1068  static MlirAttribute castFrom(PyAttribute &orig) {
1069  if (!DerivedTy::isaFunction(orig)) {
1070  auto origRepr = pybind11::repr(pybind11::cast(orig)).cast<std::string>();
1071  throw py::value_error((llvm::Twine("Cannot cast attribute to ") +
1072  DerivedTy::pyClassName + " (from " + origRepr +
1073  ")")
1074  .str());
1075  }
1076  return orig;
1077  }
1078 
1079  static void bind(pybind11::module &m) {
1080  auto cls = ClassTy(m, DerivedTy::pyClassName, pybind11::buffer_protocol(),
1081  pybind11::module_local());
1082  cls.def(pybind11::init<PyAttribute &>(), pybind11::keep_alive<0, 1>(),
1083  pybind11::arg("cast_from_attr"));
1084  cls.def_static(
1085  "isinstance",
1086  [](PyAttribute &otherAttr) -> bool {
1087  return DerivedTy::isaFunction(otherAttr);
1088  },
1089  pybind11::arg("other"));
1090  cls.def_property_readonly(
1091  "type", [](PyAttribute &attr) { return mlirAttributeGetType(attr); });
1092  cls.def_property_readonly_static(
1093  "static_typeid", [](py::object & /*class*/) -> MlirTypeID {
1094  if (DerivedTy::getTypeIdFunction)
1095  return DerivedTy::getTypeIdFunction();
1096  throw py::attribute_error(
1097  (DerivedTy::pyClassName + llvm::Twine(" has no typeid.")).str());
1098  });
1099  cls.def_property_readonly("typeid", [](PyAttribute &self) {
1100  return py::cast(self).attr("typeid").cast<MlirTypeID>();
1101  });
1102  cls.def("__repr__", [](DerivedTy &self) {
1103  PyPrintAccumulator printAccum;
1104  printAccum.parts.append(DerivedTy::pyClassName);
1105  printAccum.parts.append("(");
1106  mlirAttributePrint(self, printAccum.getCallback(),
1107  printAccum.getUserData());
1108  printAccum.parts.append(")");
1109  return printAccum.join();
1110  });
1111 
1112  if (DerivedTy::getTypeIdFunction) {
1114  DerivedTy::getTypeIdFunction(),
1115  pybind11::cpp_function([](PyAttribute pyAttribute) -> DerivedTy {
1116  return pyAttribute;
1117  }));
1118  }
1119 
1120  DerivedTy::bindDerived(cls);
1121  }
1122 
1123  /// Implemented by derived classes to add methods to the Python subclass.
1124  static void bindDerived(ClassTy &m) {}
1125 };
1126 
1127 /// Wrapper around the generic MlirValue.
1128 /// Values are managed completely by the operation that resulted in their
1129 /// definition. For op result value, this is the operation that defines the
1130 /// value. For block argument values, this is the operation that contains the
1131 /// block to which the value is an argument (blocks cannot be detached in Python
1132 /// bindings so such operation always exists).
1133 class PyValue {
1134 public:
1135  // The virtual here is "load bearing" in that it enables RTTI
1136  // for PyConcreteValue CRTP classes that support maybeDownCast.
1137  // See PyValue::maybeDownCast.
1138  virtual ~PyValue() = default;
1139  PyValue(PyOperationRef parentOperation, MlirValue value)
1140  : parentOperation(std::move(parentOperation)), value(value) {}
1141  operator MlirValue() const { return value; }
1142 
1143  MlirValue get() { return value; }
1144  PyOperationRef &getParentOperation() { return parentOperation; }
1145 
1146  void checkValid() { return parentOperation->checkValid(); }
1147 
1148  /// Gets a capsule wrapping the void* within the MlirValue.
1149  pybind11::object getCapsule();
1150 
1151  pybind11::object maybeDownCast();
1152 
1153  /// Creates a PyValue from the MlirValue wrapped by a capsule. Ownership of
1154  /// the underlying MlirValue is still tied to the owning operation.
1155  static PyValue createFromCapsule(pybind11::object capsule);
1156 
1157 private:
1158  PyOperationRef parentOperation;
1159  MlirValue value;
1160 };
1161 
1162 /// Wrapper around MlirAffineExpr. Affine expressions are owned by the context.
1164 public:
1165  PyAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
1166  : BaseContextObject(std::move(contextRef)), affineExpr(affineExpr) {}
1167  bool operator==(const PyAffineExpr &other) const;
1168  operator MlirAffineExpr() const { return affineExpr; }
1169  MlirAffineExpr get() const { return affineExpr; }
1170 
1171  /// Gets a capsule wrapping the void* within the MlirAffineExpr.
1172  pybind11::object getCapsule();
1173 
1174  /// Creates a PyAffineExpr from the MlirAffineExpr wrapped by a capsule.
1175  /// Note that PyAffineExpr instances are uniqued, so the returned object
1176  /// may be a pre-existing object. Ownership of the underlying MlirAffineExpr
1177  /// is taken by calling this function.
1178  static PyAffineExpr createFromCapsule(pybind11::object capsule);
1179 
1180  PyAffineExpr add(const PyAffineExpr &other) const;
1181  PyAffineExpr mul(const PyAffineExpr &other) const;
1182  PyAffineExpr floorDiv(const PyAffineExpr &other) const;
1183  PyAffineExpr ceilDiv(const PyAffineExpr &other) const;
1184  PyAffineExpr mod(const PyAffineExpr &other) const;
1185 
1186 private:
1187  MlirAffineExpr affineExpr;
1188 };
1189 
1191 public:
1192  PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
1193  : BaseContextObject(std::move(contextRef)), affineMap(affineMap) {}
1194  bool operator==(const PyAffineMap &other) const;
1195  operator MlirAffineMap() const { return affineMap; }
1196  MlirAffineMap get() const { return affineMap; }
1197 
1198  /// Gets a capsule wrapping the void* within the MlirAffineMap.
1199  pybind11::object getCapsule();
1200 
1201  /// Creates a PyAffineMap from the MlirAffineMap wrapped by a capsule.
1202  /// Note that PyAffineMap instances are uniqued, so the returned object
1203  /// may be a pre-existing object. Ownership of the underlying MlirAffineMap
1204  /// is taken by calling this function.
1205  static PyAffineMap createFromCapsule(pybind11::object capsule);
1206 
1207 private:
1208  MlirAffineMap affineMap;
1209 };
1210 
1212 public:
1213  PyIntegerSet(PyMlirContextRef contextRef, MlirIntegerSet integerSet)
1214  : BaseContextObject(std::move(contextRef)), integerSet(integerSet) {}
1215  bool operator==(const PyIntegerSet &other) const;
1216  operator MlirIntegerSet() const { return integerSet; }
1217  MlirIntegerSet get() const { return integerSet; }
1218 
1219  /// Gets a capsule wrapping the void* within the MlirIntegerSet.
1220  pybind11::object getCapsule();
1221 
1222  /// Creates a PyIntegerSet from the MlirAffineMap wrapped by a capsule.
1223  /// Note that PyIntegerSet instances may be uniqued, so the returned object
1224  /// may be a pre-existing object. Integer sets are owned by the context.
1225  static PyIntegerSet createFromCapsule(pybind11::object capsule);
1226 
1227 private:
1228  MlirIntegerSet integerSet;
1229 };
1230 
1231 /// Bindings for MLIR symbol tables.
1233 public:
1234  /// Constructs a symbol table for the given operation.
1235  explicit PySymbolTable(PyOperationBase &operation);
1236 
1237  /// Destroys the symbol table.
1239 
1240  /// Returns the symbol (opview) with the given name, throws if there is no
1241  /// such symbol in the table.
1242  pybind11::object dunderGetItem(const std::string &name);
1243 
1244  /// Removes the given operation from the symbol table and erases it.
1245  void erase(PyOperationBase &symbol);
1246 
1247  /// Removes the operation with the given name from the symbol table and erases
1248  /// it, throws if there is no such symbol in the table.
1249  void dunderDel(const std::string &name);
1250 
1251  /// Inserts the given operation into the symbol table. The operation must have
1252  /// the symbol trait.
1253  MlirAttribute insert(PyOperationBase &symbol);
1254 
1255  /// Gets and sets the name of a symbol op.
1256  static MlirAttribute getSymbolName(PyOperationBase &symbol);
1257  static void setSymbolName(PyOperationBase &symbol, const std::string &name);
1258 
1259  /// Gets and sets the visibility of a symbol op.
1260  static MlirAttribute getVisibility(PyOperationBase &symbol);
1261  static void setVisibility(PyOperationBase &symbol,
1262  const std::string &visibility);
1263 
1264  /// Replaces all symbol uses within an operation. See the API
1265  /// mlirSymbolTableReplaceAllSymbolUses for all caveats.
1266  static void replaceAllSymbolUses(const std::string &oldSymbol,
1267  const std::string &newSymbol,
1268  PyOperationBase &from);
1269 
1270  /// Walks all symbol tables under and including 'from'.
1271  static void walkSymbolTables(PyOperationBase &from, bool allSymUsesVisible,
1272  pybind11::object callback);
1273 
1274  /// Casts the bindings class into the C API structure.
1275  operator MlirSymbolTable() { return symbolTable; }
1276 
1277 private:
1278  PyOperationRef operation;
1279  MlirSymbolTable symbolTable;
1280 };
1281 
1282 /// Custom exception that allows access to error diagnostic information. This is
1283 /// converted to the `ir.MLIRError` python exception when thrown.
1284 struct MLIRError {
1285  MLIRError(llvm::Twine message,
1286  std::vector<PyDiagnostic::DiagnosticInfo> &&errorDiagnostics = {})
1287  : message(message.str()), errorDiagnostics(std::move(errorDiagnostics)) {}
1288  std::string message;
1289  std::vector<PyDiagnostic::DiagnosticInfo> errorDiagnostics;
1290 };
1291 
1292 void populateIRAffine(pybind11::module &m);
1293 void populateIRAttributes(pybind11::module &m);
1294 void populateIRCore(pybind11::module &m);
1295 void populateIRInterfaces(pybind11::module &m);
1296 void populateIRTypes(pybind11::module &m);
1297 
1298 } // namespace python
1299 } // namespace mlir
1300 
1301 namespace pybind11 {
1302 namespace detail {
1303 
1304 template <>
1305 struct type_caster<mlir::python::DefaultingPyMlirContext>
1306  : MlirDefaultingCaster<mlir::python::DefaultingPyMlirContext> {};
1307 template <>
1308 struct type_caster<mlir::python::DefaultingPyLocation>
1309  : MlirDefaultingCaster<mlir::python::DefaultingPyLocation> {};
1310 
1311 } // namespace detail
1312 } // namespace pybind11
1313 
1314 #endif // MLIR_BINDINGS_PYTHON_IRMODULES_H
static std::string diag(const llvm::Value &value)
Base class for all objects that directly or indirectly depend on an MlirContext.
Definition: IRModule.h:303
PyMlirContextRef & getContext()
Accesses the context reference.
Definition: IRModule.h:311
BaseContextObject(PyMlirContextRef ref)
Definition: IRModule.h:305
Used in function arguments when None should resolve to the current context manager set instance.
Definition: IRModule.h:518
static PyLocation & resolve()
Definition: IRCore.cpp:1065
static constexpr const char kTypeDescription[]
Definition: IRModule.h:521
Used in function arguments when None should resolve to the current context manager set instance.
Definition: IRModule.h:292
static constexpr const char kTypeDescription[]
Definition: IRModule.h:295
static PyMlirContext & resolve()
Definition: IRCore.cpp:789
CRTP template for special wrapper types that are allowed to be passed in as 'None' function arguments...
Definition: PybindUtils.h:39
Defaulting()=default
Type casters require the type to be default constructible, but using such an instance is illegal.
Wrapper around MlirAffineExpr. Affine expressions are owned by the context.
Definition: IRModule.h:1163
static PyAffineExpr createFromCapsule(pybind11::object capsule)
Creates a PyAffineExpr from the MlirAffineExpr wrapped by a capsule.
Definition: IRAffine.cpp:373
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineExpr.
Definition: IRAffine.cpp:368
PyAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
Definition: IRModule.h:1165
PyAffineExpr ceilDiv(const PyAffineExpr &other) const
PyAffineExpr mul(const PyAffineExpr &other) const
PyAffineExpr mod(const PyAffineExpr &other) const
PyAffineExpr floorDiv(const PyAffineExpr &other) const
bool operator==(const PyAffineExpr &other) const
Definition: IRAffine.cpp:364
PyAffineExpr add(const PyAffineExpr &other) const
MlirAffineExpr get() const
Definition: IRModule.h:1169
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineMap.
Definition: IRAffine.cpp:427
PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
Definition: IRModule.h:1192
bool operator==(const PyAffineMap &other) const
Definition: IRAffine.cpp:423
MlirAffineMap get() const
Definition: IRModule.h:1196
static PyAffineMap createFromCapsule(pybind11::object capsule)
Creates a PyAffineMap from the MlirAffineMap wrapped by a capsule.
Definition: IRAffine.cpp:431
Wrapper around an MlirAsmState.
Definition: IRModule.h:785
PyAsmState(PyOperationBase &operation, bool useLocalScope)
Definition: IRModule.h:796
PyAsmState(MlirValue value, bool useLocalScope)
Definition: IRModule.h:787
PyAsmState(PyAsmState &other)=delete
PyAsmState(const PyAsmState &other)=delete
MlirAsmState get()
Definition: IRModule.h:810
Wrapper around the generic MlirAttribute.
Definition: IRModule.h:1002
PyAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
Definition: IRModule.h:1004
static PyAttribute createFromCapsule(pybind11::object capsule)
Creates a PyAttribute from the MlirAttribute wrapped by a capsule.
Definition: IRCore.cpp:1933
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirAttribute.
Definition: IRCore.cpp:1929
MlirAttribute get() const
Definition: IRModule.h:1008
bool operator==(const PyAttribute &other) const
Definition: IRCore.cpp:1925
Wrapper around an MlirBlock.
Definition: IRModule.h:820
MlirBlock get()
Definition: IRModule.h:827
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirBlock.
Definition: IRCore.cpp:292
PyOperationRef & getParentOperation()
Definition: IRModule.h:828
PyBlock(PyOperationRef parentOperation, MlirBlock block)
Definition: IRModule.h:822
CRTP base classes for Python attributes that subclass Attribute and should be castable from it (i....
Definition: IRModule.h:1052
pybind11::class_< DerivedTy, BaseTy > ClassTy
Definition: IRModule.h:1057
MlirTypeID(*)() GetTypeIDFunctionTy
Definition: IRModule.h:1059
static MlirAttribute castFrom(PyAttribute &orig)
Definition: IRModule.h:1068
static void bind(pybind11::module &m)
Definition: IRModule.h:1079
static constexpr GetTypeIDFunctionTy getTypeIdFunction
Definition: IRModule.h:1060
bool(*)(MlirAttribute) IsAFunctionTy
Definition: IRModule.h:1058
PyConcreteAttribute(PyAttribute &orig)
Definition: IRModule.h:1065
PyConcreteAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
Definition: IRModule.h:1063
static void bindDerived(ClassTy &m)
Implemented by derived classes to add methods to the Python subclass.
Definition: IRModule.h:1124
CRTP base classes for Python types that subclass Type and should be castable from it (i....
Definition: IRModule.h:930
static void bind(pybind11::module &m)
Definition: IRModule.h:957
pybind11::class_< DerivedTy, BaseTy > ClassTy
Definition: IRModule.h:935
PyConcreteType(PyType &orig)
Definition: IRModule.h:943
MlirTypeID(*)() GetTypeIDFunctionTy
Definition: IRModule.h:937
bool(*)(MlirType) IsAFunctionTy
Definition: IRModule.h:936
static void bindDerived(ClassTy &m)
Implemented by derived classes to add methods to the Python subclass.
Definition: IRModule.h:997
static constexpr GetTypeIDFunctionTy getTypeIdFunction
Definition: IRModule.h:938
PyConcreteType(PyMlirContextRef contextRef, MlirType t)
Definition: IRModule.h:941
static MlirType castFrom(PyType &orig)
Definition: IRModule.h:946
Represents a diagnostic handler attached to the context.
Definition: IRModule.h:399
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
Definition: IRModule.h:411
void detach()
Detaches the handler. Does nothing if not attached.
Definition: IRCore.cpp:951
PyDiagnosticHandler(MlirContext context, pybind11::object callback)
Definition: IRCore.cpp:945
pybind11::object contextEnter()
Definition: IRModule.h:410
Python class mirroring the C MlirDiagnostic struct.
Definition: IRModule.h:349
pybind11::str getMessage()
Definition: IRCore.cpp:981
PyLocation getLocation()
Definition: IRCore.cpp:974
DiagnosticInfo getInfo()
Definition: IRCore.cpp:1002
PyDiagnostic(MlirDiagnostic diagnostic)
Definition: IRModule.h:351
MlirDiagnosticSeverity getSeverity()
Definition: IRCore.cpp:969
pybind11::tuple getNotes()
Definition: IRCore.cpp:989
Wrapper around an MlirDialect.
Definition: IRModule.h:454
PyDialectDescriptor(PyMlirContextRef contextRef, MlirDialect dialect)
Definition: IRModule.h:456
Wrapper around an MlirDialectRegistry.
Definition: IRModule.h:491
PyDialectRegistry(PyDialectRegistry &&other) noexcept
Definition: IRModule.h:500
PyDialectRegistry(PyDialectRegistry &)=delete
static PyDialectRegistry createFromCapsule(pybind11::object capsule)
Definition: IRCore.cpp:1031
MlirDialectRegistry get() const
Definition: IRModule.h:506
pybind11::object getCapsule()
Definition: IRCore.cpp:1026
PyDialectRegistry(MlirDialectRegistry registry)
Definition: IRModule.h:494
User-level dialect object.
Definition: IRModule.h:478
PyDialect(pybind11::object descriptor)
Definition: IRModule.h:480
pybind11::object getDescriptor()
Definition: IRModule.h:482
User-level object for accessing dialects with dotted syntax such as: ctx.dialect.std.
Definition: IRModule.h:467
PyDialects(PyMlirContextRef contextRef)
Definition: IRModule.h:469
MlirDialect getDialectForKey(const std::string &key, bool attrError)
Definition: IRCore.cpp:1013
void registerTypeCaster(MlirTypeID mlirTypeID, pybind11::function typeCaster, bool replace=false)
Adds a user-friendly type caster.
Definition: IRModule.cpp:81
static PyGlobals & get()
Most code should get the globals via this static accessor.
Definition: Globals.h:34
An insertion point maintains a pointer to a Block and a reference operation.
Definition: IRModule.h:844
static PyInsertionPoint atBlockTerminator(PyBlock &block)
Shortcut to create an insertion point before the block terminator.
Definition: IRCore.cpp:1902
PyInsertionPoint(PyBlock &block)
Creates an insertion point positioned after the last operation in the block, but still inside the blo...
Definition: IRCore.cpp:1857
static PyInsertionPoint atBlockBegin(PyBlock &block)
Shortcut to create an insertion point at the beginning of the block.
Definition: IRCore.cpp:1889
void insert(PyOperationBase &operationBase)
Inserts an operation.
Definition: IRCore.cpp:1863
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
Definition: IRCore.cpp:1915
std::optional< PyOperationRef > & getRefOperation()
Definition: IRModule.h:867
pybind11::object contextEnter()
Enter and exit the context manager.
Definition: IRCore.cpp:1911
static PyIntegerSet createFromCapsule(pybind11::object capsule)
Creates a PyIntegerSet from the MlirAffineMap wrapped by a capsule.
Definition: IRAffine.cpp:509
MlirIntegerSet get() const
Definition: IRModule.h:1217
bool operator==(const PyIntegerSet &other) const
Definition: IRAffine.cpp:500
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirIntegerSet.
Definition: IRAffine.cpp:504
PyIntegerSet(PyMlirContextRef contextRef, MlirIntegerSet integerSet)
Definition: IRModule.h:1213
Wrapper around an MlirLocation.
Definition: IRModule.h:318
PyLocation(PyMlirContextRef contextRef, MlirLocation loc)
Definition: IRModule.h:320
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirLocation.
Definition: IRCore.cpp:1043
static PyLocation createFromCapsule(pybind11::object capsule)
Creates a PyLocation from the MlirLocation wrapped by a capsule.
Definition: IRCore.cpp:1047
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
Definition: IRCore.cpp:1059
pybind11::object contextEnter()
Enter and exit the context manager.
Definition: IRCore.cpp:1055
MlirLocation get() const
Definition: IRModule.h:324
pybind11::object attachDiagnosticHandler(pybind11::object callback)
Attaches a Python callback as a diagnostic handler, returning a registration object (internally a PyD...
Definition: IRCore.cpp:724
PyMlirContext(const PyMlirContext &)=delete
PyMlirContext(PyMlirContext &&)=delete
MlirContext get()
Accesses the underlying MlirContext.
Definition: IRModule.h:185
PyMlirContextRef getRef()
Gets a strong reference to this context, which will ensure it is kept alive for the life of the refer...
Definition: IRModule.h:189
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyMlirContext from the MlirContext wrapped by a capsule.
Definition: IRCore.cpp:615
void clearOperationsInside(PyOperationBase &op)
Clears all operations nested inside the given op using clearOperation(MlirOperation).
Definition: IRCore.cpp:676
static size_t getLiveCount()
Gets the count of live context objects. Used for testing.
Definition: IRCore.cpp:649
void clearOperationAndInside(PyOperationBase &op)
Clears the operaiton and all operations inside using clearOperation(MlirOperation).
Definition: IRCore.cpp:701
static PyMlirContext * createNewContextForInit()
For the case of a python init (py::init) method, pybind11 is quite strict about needing to return a p...
Definition: IRCore.cpp:622
size_t getLiveModuleCount()
Gets the count of live modules associated with this context.
Definition: IRCore.cpp:712
pybind11::object contextEnter()
Enter and exit the context manager.
Definition: IRCore.cpp:714
size_t clearLiveOperations()
Clears the live operations map, returning the number of entries which were invalidated.
Definition: IRCore.cpp:660
std::vector< PyOperation * > getLiveOperationObjects()
Get a list of Python objects which are still in the live context map.
Definition: IRCore.cpp:653
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
Definition: IRCore.cpp:718
void clearOperation(MlirOperation op)
Removes an operation from the live operations map and sets it invalid.
Definition: IRCore.cpp:668
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
Definition: IRCore.cpp:627
size_t getLiveOperationCount()
Gets the count of live operations associated with this context.
Definition: IRCore.cpp:651
void setEmitErrorDiagnostics(bool value)
Controls whether error diagnostics should be propagated to diagnostic handlers, instead of being capt...
Definition: IRModule.h:251
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirContext.
Definition: IRCore.cpp:611
MlirModule get()
Gets the backing MlirModule.
Definition: IRModule.h:541
static PyModuleRef forModule(MlirModule module)
Returns a PyModule reference for the given MlirModule.
Definition: IRCore.cpp:1092
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirModule.
Definition: IRCore.cpp:1125
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyModule from the MlirModule wrapped by a capsule.
Definition: IRCore.cpp:1118
PyModuleRef getRef()
Gets a strong reference to this module.
Definition: IRModule.h:544
PyModule(PyModule &)=delete
PyModule(PyMlirContext &&)=delete
Represents a Python MlirNamedAttr, carrying an optional owned name.
Definition: IRModule.h:1026
PyNamedAttribute(MlirAttribute attr, std::string ownedName)
Constructs a PyNamedAttr that retains an owned name.
Definition: IRCore.cpp:1945
MlirNamedAttribute namedAttr
Definition: IRModule.h:1035
Template for a reference to a concrete type which captures a python reference to its underlying pytho...
Definition: IRModule.h:50
PyObjectRef(T *referrent, pybind11::object object)
Definition: IRModule.h:52
pybind11::object getObject()
Definition: IRModule.h:88
pybind11::object releaseObject()
Releases the object held by this instance, returning it.
Definition: IRModule.h:76
PyObjectRef(PyObjectRef &&other) noexcept
Definition: IRModule.h:58
PyObjectRef(const PyObjectRef &other)
Definition: IRModule.h:63
A PyOpView is equivalent to the C++ "Op" wrappers: these are the basis for providing more instance-sp...
Definition: IRModule.h:734
PyOpView(const pybind11::object &operationObject)
Definition: IRCore.cpp:1847
pybind11::object getOperationObject()
Definition: IRModule.h:739
static pybind11::object buildGeneric(const pybind11::object &cls, std::optional< pybind11::list > resultTypeList, pybind11::list operandList, std::optional< pybind11::dict > attributes, std::optional< std::vector< PyBlock * >> successors, std::optional< int > regions, DefaultingPyLocation location, const pybind11::object &maybeIp)
Definition: IRCore.cpp:1658
static pybind11::object constructDerived(const pybind11::object &cls, const PyOperation &operation)
Construct an instance of a class deriving from OpView, bypassing its __init__ method.
Definition: IRCore.cpp:1836
PyOperation & getOperation() override
Each must provide access to the raw Operation.
Definition: IRModule.h:737
Base class for PyOperation and PyOpView which exposes the primary, user visible methods for manipulat...
Definition: IRModule.h:571
void print(std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified, py::object fileObject, bool binary, bool skipRegions)
Implements the bound 'print' method and helps with others.
Definition: IRCore.cpp:1221
void walk(std::function< MlirWalkResult(MlirOperation)> callback, MlirWalkOrder walkOrder)
Definition: IRCore.cpp:1284
virtual PyOperation & getOperation()=0
Each must provide access to the raw Operation.
void writeBytecode(const pybind11::object &fileObject, std::optional< int64_t > bytecodeVersion)
Definition: IRCore.cpp:1263
virtual ~PyOperationBase()=default
void moveAfter(PyOperationBase &other)
Moves the operation before or after the other operation.
Definition: IRCore.cpp:1340
void moveBefore(PyOperationBase &other)
Definition: IRCore.cpp:1349
bool verify()
Verify the operation.
Definition: IRCore.cpp:1358
pybind11::object getAsm(bool binary, std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified, bool skipRegions)
Definition: IRCore.cpp:1316
pybind11::object clone(const pybind11::object &ip)
Clones this operation.
Definition: IRCore.cpp:1540
void detachFromParent()
Detaches the operation from its parent block and updates its state accordingly.
Definition: IRModule.h:640
void erase()
Erases the underlying MlirOperation, removes its pointer from the parent context's live operations ma...
Definition: IRCore.cpp:1560
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirOperation.
Definition: IRCore.cpp:1385
PyOperation & getOperation() override
Each must provide access to the raw Operation.
Definition: IRModule.h:618
PyOperationRef getRef()
Definition: IRModule.h:653
MlirOperation get() const
Definition: IRModule.h:648
void setAttached(const pybind11::object &parent=pybind11::object())
Definition: IRModule.h:659
static pybind11::object create(const std::string &name, std::optional< std::vector< PyType * >> results, std::optional< std::vector< PyValue * >> operands, std::optional< pybind11::dict > attributes, std::optional< std::vector< PyBlock * >> successors, int regions, DefaultingPyLocation location, const pybind11::object &ip, bool inferType)
Creates an operation. See corresponding python docstring.
Definition: IRCore.cpp:1414
pybind11::object createOpView()
Creates an OpView suitable for this operation.
Definition: IRCore.cpp:1549
static PyOperationRef forOperation(PyMlirContextRef contextRef, MlirOperation operation, pybind11::object parentKeepAlive=pybind11::object())
Returns a PyOperation for the given MlirOperation, optionally associating it with a parentKeepAlive.
Definition: IRCore.cpp:1173
std::optional< PyOperationRef > getParentOperation()
Gets the parent operation or raises an exception if the operation has no parent.
Definition: IRCore.cpp:1366
PyBlock getBlock()
Gets the owning block or raises an exception if the operation has no owning block.
Definition: IRCore.cpp:1376
static PyOperationRef createDetached(PyMlirContextRef contextRef, MlirOperation operation, pybind11::object parentKeepAlive=pybind11::object())
Creates a detached operation.
Definition: IRCore.cpp:1189
static PyOperationRef parse(PyMlirContextRef contextRef, const std::string &sourceStr, const std::string &sourceName)
Parses a source string (either text assembly or bytecode), creating a detached operation.
Definition: IRCore.cpp:1203
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyOperation from the MlirOperation wrapped by a capsule.
Definition: IRCore.cpp:1390
void checkValid() const
Definition: IRCore.cpp:1215
void setInvalid()
Invalidate the operation.
Definition: IRModule.h:702
Wrapper around an MlirRegion.
Definition: IRModule.h:766
PyRegion(PyOperationRef parentOperation, MlirRegion region)
Definition: IRModule.h:768
PyOperationRef & getParentOperation()
Definition: IRModule.h:775
MlirRegion get()
Definition: IRModule.h:774
Bindings for MLIR symbol tables.
Definition: IRModule.h:1232
void dunderDel(const std::string &name)
Removes the operation with the given name from the symbol table and erases it, throws if there is no ...
Definition: IRCore.cpp:2065
static void replaceAllSymbolUses(const std::string &oldSymbol, const std::string &newSymbol, PyOperationBase &from)
Replaces all symbol uses within an operation.
Definition: IRCore.cpp:2136
static void setVisibility(PyOperationBase &symbol, const std::string &visibility)
Definition: IRCore.cpp:2118
static void setSymbolName(PyOperationBase &symbol, const std::string &name)
Definition: IRCore.cpp:2092
~PySymbolTable()
Destroys the symbol table.
Definition: IRModule.h:1238
MlirAttribute insert(PyOperationBase &symbol)
Inserts the given operation into the symbol table.
Definition: IRCore.cpp:2070
void erase(PyOperationBase &symbol)
Removes the given operation from the symbol table and erases it.
Definition: IRCore.cpp:2055
PySymbolTable(PyOperationBase &operation)
Constructs a symbol table for the given operation.
Definition: IRCore.cpp:2035
static MlirAttribute getSymbolName(PyOperationBase &symbol)
Gets and sets the name of a symbol op.
Definition: IRCore.cpp:2080
pybind11::object dunderGetItem(const std::string &name)
Returns the symbol (opview) with the given name, throws if there is no such symbol in the table.
Definition: IRCore.cpp:2043
static MlirAttribute getVisibility(PyOperationBase &symbol)
Gets and sets the visibility of a symbol op.
Definition: IRCore.cpp:2107
static void walkSymbolTables(PyOperationBase &from, bool allSymUsesVisible, pybind11::object callback)
Walks all symbol tables under and including 'from'.
Definition: IRCore.cpp:2148
Tracks an entry in the thread context stack.
Definition: IRModule.h:107
static PyThreadContextEntry * getTopOfStack()
Stack management.
Definition: IRCore.cpp:809
static void popLocation(PyLocation &location)
Definition: IRCore.cpp:921
PyThreadContextEntry(FrameKind frameKind, pybind11::object context, pybind11::object insertionPoint, pybind11::object location)
Definition: IRModule.h:115
static pybind11::object pushContext(PyMlirContext &context)
Definition: IRCore.cpp:871
static PyLocation * getDefaultLocation()
Gets the top of stack location and returns nullptr if not defined.
Definition: IRCore.cpp:866
static void popInsertionPoint(PyInsertionPoint &insertionPoint)
Definition: IRCore.cpp:901
static void popContext(PyMlirContext &context)
Definition: IRCore.cpp:879
static PyInsertionPoint * getDefaultInsertionPoint()
Gets the top of stack insertion point and return nullptr if not defined.
Definition: IRCore.cpp:861
static pybind11::object pushInsertionPoint(PyInsertionPoint &insertionPoint)
Definition: IRCore.cpp:890
static pybind11::object pushLocation(PyLocation &location)
Definition: IRCore.cpp:912
PyMlirContext * getContext()
Definition: IRCore.cpp:838
static PyMlirContext * getDefaultContext()
Gets the top of stack context and return nullptr if not defined.
Definition: IRCore.cpp:856
static std::vector< PyThreadContextEntry > & getStack()
Gets the thread local stack.
Definition: IRCore.cpp:804
PyInsertionPoint * getInsertionPoint()
Definition: IRCore.cpp:844
A TypeID provides an efficient and unique identifier for a specific C++ type.
Definition: IRModule.h:904
MlirTypeID get()
Definition: IRModule.h:912
bool operator==(const PyTypeID &other) const
Definition: IRCore.cpp:1987
static PyTypeID createFromCapsule(pybind11::object capsule)
Creates a PyTypeID from the MlirTypeID wrapped by a capsule.
Definition: IRCore.cpp:1981
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirTypeID.
Definition: IRCore.cpp:1977
PyTypeID(MlirTypeID typeID)
Definition: IRModule.h:906
Wrapper around the generic MlirType.
Definition: IRModule.h:880
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirType.
Definition: IRCore.cpp:1961
static PyType createFromCapsule(pybind11::object capsule)
Creates a PyType from the MlirType wrapped by a capsule.
Definition: IRCore.cpp:1965
PyType(PyMlirContextRef contextRef, MlirType type)
Definition: IRModule.h:882
MlirType get() const
Definition: IRModule.h:886
bool operator==(const PyType &other) const
Definition: IRCore.cpp:1957
Wrapper around the generic MlirValue.
Definition: IRModule.h:1133
static PyValue createFromCapsule(pybind11::object capsule)
Creates a PyValue from the MlirValue wrapped by a capsule.
Definition: IRCore.cpp:2014
PyValue(PyOperationRef parentOperation, MlirValue value)
Definition: IRModule.h:1139
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirValue.
Definition: IRCore.cpp:1995
virtual ~PyValue()=default
pybind11::object maybeDownCast()
Definition: IRCore.cpp:1999
PyOperationRef & getParentOperation()
Definition: IRModule.h:1144
MlirDiagnosticSeverity
Severity of a diagnostic.
Definition: Diagnostics.h:32
MLIR_CAPI_EXPORTED MlirDiagnosticHandlerID mlirContextAttachDiagnosticHandler(MlirContext context, MlirDiagnosticHandler handler, void *userData, void(*deleteUserData)(void *))
Attaches the diagnostic handler to the context.
Definition: Diagnostics.cpp:56
MLIR_CAPI_EXPORTED void mlirContextDetachDiagnosticHandler(MlirContext context, MlirDiagnosticHandlerID id)
Detaches an attached diagnostic handler from the context given its identifier.
Definition: Diagnostics.cpp:72
uint64_t MlirDiagnosticHandlerID
Opaque identifier of a diagnostic handler, useful to detach a handler.
Definition: Diagnostics.h:41
MlirWalkOrder
Traversal order for operation walk.
Definition: IR.h:728
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsUseLocalScope(MlirOpPrintingFlags flags)
Use local scope when printing the operation.
Definition: IR.cpp:219
MLIR_CAPI_EXPORTED void mlirDialectRegistryDestroy(MlirDialectRegistry registry)
Takes a dialect registry owned by the caller and destroys it.
Definition: IR.cpp:139
MLIR_CAPI_EXPORTED MlirType mlirAttributeGetType(MlirAttribute attribute)
Gets the type of this attribute.
Definition: IR.cpp:1086
MLIR_CAPI_EXPORTED void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData tocallback`.
Definition: IR.cpp:1067
MLIR_CAPI_EXPORTED void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback, void *userData)
Prints an attribute by sending chunks of the string representation and forwarding userData tocallback...
Definition: IR.cpp:1105
MlirWalkResult
Operation walk result.
Definition: IR.h:721
MLIR_CAPI_EXPORTED MlirAsmState mlirAsmStateCreateForOperation(MlirOperation op, MlirOpPrintingFlags flags)
Creates new AsmState, as with AsmState the IR should not be mutated in-between using this state.
Definition: IR.cpp:147
static bool mlirBlockIsNull(MlirBlock block)
Checks whether a block is null.
Definition: IR.h:817
MLIR_CAPI_EXPORTED void mlirSymbolTableDestroy(MlirSymbolTable symbolTable)
Destroys the symbol table created with mlirSymbolTableCreate.
Definition: IR.cpp:1156
static bool mlirDialectRegistryIsNull(MlirDialectRegistry registry)
Checks if the dialect registry is null.
Definition: IR.h:235
static bool mlirRegionIsNull(MlirRegion region)
Checks whether a region is null.
Definition: IR.h:756
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsDestroy(MlirOpPrintingFlags flags)
Destroys printing flags created with mlirOpPrintingFlagsCreate.
Definition: IR.cpp:196
MLIR_CAPI_EXPORTED MlirDialectRegistry mlirDialectRegistryCreate(void)
Creates a dialect registry and transfers its ownership to the caller.
Definition: IR.cpp:135
MLIR_CAPI_EXPORTED void mlirOperationRemoveFromParent(MlirOperation op)
Removes the given operation from its parent block.
Definition: IR.cpp:508
MLIR_CAPI_EXPORTED MlirOpPrintingFlags mlirOpPrintingFlagsCreate(void)
Creates new printing flags with defaults, intended for customization.
Definition: IR.cpp:192
MLIR_CAPI_EXPORTED MlirAsmState mlirAsmStateCreateForValue(MlirValue value, MlirOpPrintingFlags flags)
Creates new AsmState from value.
Definition: IR.cpp:168
void populateIRAttributes(pybind11::module &m)
void populateIRTypes(pybind11::module &m)
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
Definition: IRModule.h:162
void populateIRAffine(pybind11::module &m)
PyObjectRef< PyModule > PyModuleRef
Definition: IRModule.h:530
void populateIRCore(pybind11::module &m)
PyObjectRef< PyOperation > PyOperationRef
Definition: IRModule.h:614
void populateIRInterfaces(py::module &m)
Include the generated interface declarations.
An opaque reference to a diagnostic, always owned by the diagnostics engine (context).
Definition: Diagnostics.h:26
A logical result value, essentially a boolean with named states.
Definition: Support.h:116
Named MLIR attribute.
Definition: IR.h:76
Accumulates into a python string from a method that accepts an MlirStringCallback.
Definition: PybindUtils.h:102
pybind11::list parts
Definition: PybindUtils.h:103
pybind11::str join()
Definition: PybindUtils.h:117
MlirStringCallback getCallback()
Definition: PybindUtils.h:107
Custom exception that allows access to error diagnostic information.
Definition: IRModule.h:1284
MLIRError(llvm::Twine message, std::vector< PyDiagnostic::DiagnosticInfo > &&errorDiagnostics={})
Definition: IRModule.h:1285
std::vector< PyDiagnostic::DiagnosticInfo > errorDiagnostics
Definition: IRModule.h:1289
Materialized diagnostic information.
Definition: IRModule.h:361
std::vector< DiagnosticInfo > notes
Definition: IRModule.h:365
RAII object that captures any error diagnostics emitted to the provided context.
Definition: IRModule.h:427
std::vector< PyDiagnostic::DiagnosticInfo > take()
Definition: IRModule.h:437
ErrorCapture(PyMlirContextRef ctx)
Definition: IRModule.h:428