1 //===- TypeID.cpp - MLIR TypeID -------------------------------------------===// 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 #include "mlir/Support/TypeID.h" 10 #include "llvm/ADT/DenseMap.h" 11 #include "llvm/ADT/StringRef.h" 12 #include "llvm/Support/Debug.h" 13 #include "llvm/Support/RWMutex.h" 14 15 #include "llvm/Support/Signals.h" 16 #include "llvm/Support/raw_ostream.h" 17 18 using namespace mlir; 19 20 #define DEBUG_TYPE "typeid" 21 22 //===----------------------------------------------------------------------===// 23 // TypeID Registry 24 //===----------------------------------------------------------------------===// 25 26 namespace { 27 struct ImplicitTypeIDRegistry { 28 /// Lookup or insert a TypeID for the given type name. lookupOrInsert__anonb6f672770111::ImplicitTypeIDRegistry29 TypeID lookupOrInsert(StringRef typeName) { 30 LLVM_DEBUG(llvm::dbgs() << "ImplicitTypeIDRegistry::lookupOrInsert(" 31 << typeName << ")\n"); 32 33 // Perform a heuristic check to see if this type is in an anonymous 34 // namespace. String equality is not valid for anonymous types, so we try to 35 // abort whenever we see them. 36 #ifndef NDEBUG 37 #if defined(_MSC_VER) 38 if (typeName.contains("anonymous-namespace")) { 39 #else 40 if (typeName.contains("anonymous namespace")) { 41 #endif 42 std::string errorStr; 43 { 44 llvm::raw_string_ostream errorOS(errorStr); 45 errorOS << "TypeID::get<" << typeName 46 << ">(): Using TypeID on a class with an anonymous " 47 "namespace requires an explicit TypeID definition. The " 48 "implicit fallback uses string name, which does not " 49 "guarantee uniqueness in anonymous contexts. Define an " 50 "explicit TypeID instantiation for this type using " 51 "`MLIR_DECLARE_EXPLICIT_TYPE_ID`/" 52 "`MLIR_DEFINE_EXPLICIT_TYPE_ID` or " 53 "`MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID`.\n"; 54 } 55 llvm::report_fatal_error(errorStr); 56 } 57 #endif 58 59 { // Try a read-only lookup first. 60 llvm::sys::SmartScopedReader<true> guard(mutex); 61 auto it = typeNameToID.find(typeName); 62 if (it != typeNameToID.end()) 63 return it->second; 64 } 65 llvm::sys::SmartScopedWriter<true> guard(mutex); 66 auto it = typeNameToID.try_emplace(typeName, TypeID()); 67 if (it.second) 68 it.first->second = typeIDAllocator.allocate(); 69 return it.first->second; 70 } 71 72 /// A mutex that guards access to the registry. 73 llvm::sys::SmartRWMutex<true> mutex; 74 75 /// An allocator used for TypeID objects. 76 TypeIDAllocator typeIDAllocator; 77 78 /// A map type name to TypeID. 79 DenseMap<StringRef, TypeID> typeNameToID; 80 }; 81 } // end namespace 82 registerImplicitTypeID(StringRef name)83TypeID detail::FallbackTypeIDResolver::registerImplicitTypeID(StringRef name) { 84 static ImplicitTypeIDRegistry registry; 85 return registry.lookupOrInsert(name); 86 } 87 88 //===----------------------------------------------------------------------===// 89 // Builtin TypeIDs 90 //===----------------------------------------------------------------------===// 91 92 MLIR_DEFINE_EXPLICIT_TYPE_ID(void) 93