MLIR  16.0.0git
MLIRContext.h
Go to the documentation of this file.
1 //===- MLIRContext.h - MLIR Global Context Class ----------------*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
8 
9 #ifndef MLIR_IR_MLIRCONTEXT_H
10 #define MLIR_IR_MLIRCONTEXT_H
11 
12 #include "mlir/Support/LLVM.h"
13 #include "mlir/Support/TypeID.h"
14 #include <functional>
15 #include <memory>
16 #include <vector>
17 
18 namespace llvm {
19 class ThreadPool;
20 } // namespace llvm
21 
22 namespace mlir {
23 class DebugActionManager;
24 class DiagnosticEngine;
25 class Dialect;
26 class DialectRegistry;
27 class DynamicDialect;
28 class InFlightDiagnostic;
29 class Location;
30 class MLIRContextImpl;
31 class RegisteredOperationName;
32 class StorageUniquer;
33 
34 /// MLIRContext is the top-level object for a collection of MLIR operations. It
35 /// holds immortal uniqued objects like types, and the tables used to unique
36 /// them.
37 ///
38 /// MLIRContext gets a redundant "MLIR" prefix because otherwise it ends up with
39 /// a very generic name ("Context") and because it is uncommon for clients to
40 /// interact with it.
41 ///
42 /// The context wrap some multi-threading facilities, and in particular by
43 /// default it will implicitly create a thread pool.
44 /// This can be undesirable if multiple context exists at the same time or if a
45 /// process will be long-lived and create and destroy contexts.
46 /// To control better thread spawning, an externally owned ThreadPool can be
47 /// injected in the context. For example:
48 ///
49 /// llvm::ThreadPool myThreadPool;
50 /// while (auto *request = nextCompilationRequests()) {
51 /// MLIRContext ctx(registry, MLIRContext::Threading::DISABLED);
52 /// ctx.setThreadPool(myThreadPool);
53 /// processRequest(request, cxt);
54 /// }
55 ///
56 class MLIRContext {
57 public:
58  enum class Threading { DISABLED, ENABLED };
59  /// Create a new Context.
60  explicit MLIRContext(Threading multithreading = Threading::ENABLED);
61  explicit MLIRContext(const DialectRegistry &registry,
62  Threading multithreading = Threading::ENABLED);
64 
65  /// Return information about all IR dialects loaded in the context.
66  std::vector<Dialect *> getLoadedDialects();
67 
68  /// Return the dialect registry associated with this context.
70 
71  /// Append the contents of the given dialect registry to the registry
72  /// associated with this context.
73  void appendDialectRegistry(const DialectRegistry &registry);
74 
75  /// Return information about all available dialects in the registry in this
76  /// context.
77  std::vector<StringRef> getAvailableDialects();
78 
79  /// Get a registered IR dialect with the given namespace. If an exact match is
80  /// not found, then return nullptr.
81  Dialect *getLoadedDialect(StringRef name);
82 
83  /// Get a registered IR dialect for the given derived dialect type. The
84  /// derived type must provide a static 'getDialectNamespace' method.
85  template <typename T>
87  return static_cast<T *>(getLoadedDialect(T::getDialectNamespace()));
88  }
89 
90  /// Get (or create) a dialect for the given derived dialect type. The derived
91  /// type must provide a static 'getDialectNamespace' method.
92  template <typename T>
94  return static_cast<T *>(
95  getOrLoadDialect(T::getDialectNamespace(), TypeID::get<T>(), [this]() {
96  std::unique_ptr<T> dialect(new T(this));
97  return dialect;
98  }));
99  }
100 
101  /// Load a dialect in the context.
102  template <typename Dialect>
103  void loadDialect() {
104  // Do not load the dialect if it is currently loading. This can happen if a
105  // dialect initializer triggers loading the same dialect recursively.
106  if (!isDialectLoading(Dialect::getDialectNamespace()))
107  getOrLoadDialect<Dialect>();
108  }
109 
110  /// Load a list dialects in the context.
111  template <typename Dialect, typename OtherDialect, typename... MoreDialects>
112  void loadDialect() {
113  loadDialect<Dialect>();
114  loadDialect<OtherDialect, MoreDialects...>();
115  }
116 
117  /// Get (or create) a dynamic dialect for the given name.
119  getOrLoadDynamicDialect(StringRef dialectNamespace,
120  function_ref<void(DynamicDialect *)> ctor);
121 
122  /// Load all dialects available in the registry in this context.
124 
125  /// Get (or create) a dialect for the given derived dialect name.
126  /// The dialect will be loaded from the registry if no dialect is found.
127  /// If no dialect is loaded for this name and none is available in the
128  /// registry, returns nullptr.
129  Dialect *getOrLoadDialect(StringRef name);
130 
131  /// Return true if we allow to create operation for unregistered dialects.
133 
134  /// Enables creating operations in unregistered dialects.
135  void allowUnregisteredDialects(bool allow = true);
136 
137  /// Return true if multi-threading is enabled by the context.
139 
140  /// Set the flag specifying if multi-threading is disabled by the context.
141  /// The command line debugging flag `--mlir-disable-threading` is overriding
142  /// this call and making it a no-op!
143  void disableMultithreading(bool disable = true);
144  void enableMultithreading(bool enable = true) {
145  disableMultithreading(!enable);
146  }
147 
148  /// Set a new thread pool to be used in this context. This method requires
149  /// that multithreading is disabled for this context prior to the call. This
150  /// allows to share a thread pool across multiple contexts, as well as
151  /// decoupling the lifetime of the threads from the contexts. The thread pool
152  /// must outlive the context. Multi-threading will be enabled as part of this
153  /// method.
154  /// The command line debugging flag `--mlir-disable-threading` will still
155  /// prevent threading from being enabled and threading won't be enabled after
156  /// this call in this case.
157  void setThreadPool(llvm::ThreadPool &pool);
158 
159  /// Return the number of threads used by the thread pool in this context. The
160  /// number of computed hardware threads can change over the lifetime of a
161  /// process based on affinity changes, so users should use the number of
162  /// threads actually in the thread pool for dispatching work. Returns 1 if
163  /// multithreading is disabled.
164  unsigned getNumThreads();
165 
166  /// Return the thread pool used by this context. This method requires that
167  /// multithreading be enabled within the context, and should generally not be
168  /// used directly. Users should instead prefer the threading utilities within
169  /// Threading.h.
170  llvm::ThreadPool &getThreadPool();
171 
172  /// Return true if we should attach the operation to diagnostics emitted via
173  /// Operation::emit.
175 
176  /// Set the flag specifying if we should attach the operation to diagnostics
177  /// emitted via Operation::emit.
178  void printOpOnDiagnostic(bool enable);
179 
180  /// Return true if we should attach the current stacktrace to diagnostics when
181  /// emitted.
183 
184  /// Set the flag specifying if we should attach the current stacktrace when
185  /// emitting diagnostics.
186  void printStackTraceOnDiagnostic(bool enable);
187 
188  /// Return a sorted array containing the information about all registered
189  /// operations.
191 
192  /// Return true if this operation name is registered in this context.
193  bool isOperationRegistered(StringRef name);
194 
195  // This is effectively private given that only MLIRContext.cpp can see the
196  // MLIRContextImpl type.
197  MLIRContextImpl &getImpl() { return *impl; }
198 
199  /// Returns the diagnostic engine for this context.
201 
202  /// Returns the storage uniquer used for creating affine constructs.
204 
205  /// Returns the storage uniquer used for constructing type storage instances.
206  /// This should not be used directly.
208 
209  /// Returns the storage uniquer used for constructing attribute storage
210  /// instances. This should not be used directly.
212 
213  /// Returns the manager of debug actions within the context.
215 
216  /// These APIs are tracking whether the context will be used in a
217  /// multithreading environment: this has no effect other than enabling
218  /// assertions on misuses of some APIs.
221 
222  /// Get a dialect for the provided namespace and TypeID: abort the program if
223  /// a dialect exist for this namespace with different TypeID. If a dialect has
224  /// not been loaded for this namespace/TypeID yet, use the provided ctor to
225  /// create one on the fly and load it. Returns a pointer to the dialect owned
226  /// by the context.
227  /// The use of this method is in general discouraged in favor of
228  /// 'getOrLoadDialect<DialectClass>()'.
229  Dialect *getOrLoadDialect(StringRef dialectNamespace, TypeID dialectID,
230  function_ref<std::unique_ptr<Dialect>()> ctor);
231 
232  /// Returns a hash of the registry of the context that may be used to give
233  /// a rough indicator of if the state of the context registry has changed. The
234  /// context registry correlates to loaded dialects and their entities
235  /// (attributes, operations, types, etc.).
236  llvm::hash_code getRegistryHash();
237 
238 private:
239  /// Return true if the given dialect is currently loading.
240  bool isDialectLoading(StringRef dialectNamespace);
241 
242  const std::unique_ptr<MLIRContextImpl> impl;
243 
244  MLIRContext(const MLIRContext &) = delete;
245  void operator=(const MLIRContext &) = delete;
246 };
247 
248 //===----------------------------------------------------------------------===//
249 // MLIRContext CommandLine Options
250 //===----------------------------------------------------------------------===//
251 
252 /// Register a set of useful command-line options that can be used to configure
253 /// various flags within the MLIRContext. These flags are used when constructing
254 /// an MLIR context for initialization.
256 
257 } // namespace mlir
258 
259 #endif // MLIR_IR_MLIRCONTEXT_H
This class represents manages debug actions, and orchestrates the communication between action querie...
Definition: DebugAction.h:43
This class is the main interface for diagnostics.
Definition: Diagnostics.h:407
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
A dialect that can be defined at runtime.
This is the implementation of the MLIRContext class, using the pImpl idiom.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:56
DebugActionManager & getDebugActionManager()
Returns the manager of debug actions within the context.
void appendDialectRegistry(const DialectRegistry &registry)
Append the contents of the given dialect registry to the registry associated with this context.
bool shouldPrintStackTraceOnDiagnostic()
Return true if we should attach the current stacktrace to diagnostics when emitted.
unsigned getNumThreads()
Return the number of threads used by the thread pool in this context.
bool isOperationRegistered(StringRef name)
Return true if this operation name is registered in this context.
MLIRContext(Threading multithreading=Threading::ENABLED)
Create a new Context.
void disableMultithreading(bool disable=true)
Set the flag specifying if multi-threading is disabled by the context.
void printStackTraceOnDiagnostic(bool enable)
Set the flag specifying if we should attach the current stacktrace when emitting diagnostics.
void setThreadPool(llvm::ThreadPool &pool)
Set a new thread pool to be used in this context.
void enableMultithreading(bool enable=true)
Definition: MLIRContext.h:144
std::vector< Dialect * > getLoadedDialects()
Return information about all IR dialects loaded in the context.
void printOpOnDiagnostic(bool enable)
Set the flag specifying if we should attach the operation to diagnostics emitted via Operation::emit.
ArrayRef< RegisteredOperationName > getRegisteredOperations()
Return a sorted array containing the information about all registered operations.
llvm::hash_code getRegistryHash()
Returns a hash of the registry of the context that may be used to give a rough indicator of if the st...
void enterMultiThreadedExecution()
These APIs are tracking whether the context will be used in a multithreading environment: this has no...
const DialectRegistry & getDialectRegistry()
Return the dialect registry associated with this context.
void loadDialect()
Load a dialect in the context.
Definition: MLIRContext.h:103
DynamicDialect * getOrLoadDynamicDialect(StringRef dialectNamespace, function_ref< void(DynamicDialect *)> ctor)
Get (or create) a dynamic dialect for the given name.
StorageUniquer & getAttributeUniquer()
Returns the storage uniquer used for constructing attribute storage instances.
StorageUniquer & getAffineUniquer()
Returns the storage uniquer used for creating affine constructs.
llvm::ThreadPool & getThreadPool()
Return the thread pool used by this context.
StorageUniquer & getTypeUniquer()
Returns the storage uniquer used for constructing type storage instances.
std::vector< StringRef > getAvailableDialects()
Return information about all available dialects in the registry in this context.
bool isMultithreadingEnabled()
Return true if multi-threading is enabled by the context.
void allowUnregisteredDialects(bool allow=true)
Enables creating operations in unregistered dialects.
bool allowsUnregisteredDialects()
Return true if we allow to create operation for unregistered dialects.
T * getLoadedDialect()
Get a registered IR dialect for the given derived dialect type.
Definition: MLIRContext.h:86
DiagnosticEngine & getDiagEngine()
Returns the diagnostic engine for this context.
void loadDialect()
Load a list dialects in the context.
Definition: MLIRContext.h:112
MLIRContextImpl & getImpl()
Definition: MLIRContext.h:197
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
Definition: MLIRContext.h:93
void exitMultiThreadedExecution()
bool shouldPrintOpOnDiagnostic()
Return true if we should attach the operation to diagnostics emitted via Operation::emit.
void loadAllAvailableDialects()
Load all dialects available in the registry in this context.
A utility class to get or create instances of "storage classes".
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
Include the generated interface declarations.
Definition: CallGraph.h:229
Include the generated interface declarations.
void registerMLIRContextCLOptions()
Register a set of useful command-line options that can be used to configure various flags within the ...
Definition: MLIRContext.cpp:86