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