}));
}
+ /// Return true if the given dialect is currently loading.
+ bool isDialectLoading(StringRef dialectNamespace);
+
/// Load a dialect in the context.
template <typename Dialect>
void loadDialect() {
- getOrLoadDialect<Dialect>();
+ // Do not load the dialect if it is currently loading. This can happen if a
+ // dialect initializer triggers loading the same dialect recursively.
+ if (!isDialectLoading(Dialect::getDialectNamespace()))
+ getOrLoadDialect<Dialect>();
}
/// Load a list dialects in the context.
template <typename Dialect, typename OtherDialect, typename... MoreDialects>
void loadDialect() {
- getOrLoadDialect<Dialect>();
+ loadDialect<Dialect>();
loadDialect<OtherDialect, MoreDialects...>();
}
") while in a multi-threaded execution context (maybe "
"the PassManager): this can indicate a "
"missing `dependentDialects` in a pass for example.");
-#endif
- std::unique_ptr<Dialect> &dialect =
- impl.loadedDialects.insert({dialectNamespace, ctor()}).first->second;
+#endif // NDEBUG
+ // nullptr indicates that the dialect is currently being loaded.
+ impl.loadedDialects[dialectNamespace] = nullptr;
+ std::unique_ptr<Dialect> &dialect = impl.loadedDialects[dialectNamespace] =
+ ctor();
assert(dialect && "dialect ctor failed");
// Refresh all the identifiers dialect field, this catches cases where a
return dialect.get();
}
+#ifndef NDEBUG
+ if (dialectIt->second == nullptr)
+ llvm::report_fatal_error(
+ "Loading (and getting) a dialect (" + dialectNamespace +
+ ") while the same dialect is still loading: use loadDialect instead "
+ "of getOrLoadDialect.");
+#endif // NDEBUG
+
// Abort if dialect with namespace has already been registered.
std::unique_ptr<Dialect> &dialect = dialectIt->second;
if (dialect->getTypeID() != dialectID)
return dialect.get();
}
+bool MLIRContext::isDialectLoading(StringRef dialectNamespace) {
+ auto it = getImpl().loadedDialects.find(dialectNamespace);
+ // nullptr indicates that the dialect is currently being loaded.
+ return it != getImpl().loadedDialects.end() && it->second == nullptr;
+}
+
DynamicDialect *MLIRContext::getOrLoadDynamicDialect(
StringRef dialectNamespace, function_ref<void(DynamicDialect *)> ctor) {
auto &impl = getImpl();
/// Registration for a single dependent dialect: to be inserted in the ctor
/// above for each dependent dialect.
const char *const dialectRegistrationTemplate = R"(
- getContext()->getOrLoadDialect<{0}>();
+ getContext()->loadDialect<{0}>();
)";
/// The code block for the attribute parser/printer hooks.