diff --git a/mlir/include/mlir/IR/SymbolInterfaces.td b/mlir/include/mlir/IR/SymbolInterfaces.td --- a/mlir/include/mlir/IR/SymbolInterfaces.td +++ b/mlir/include/mlir/IR/SymbolInterfaces.td @@ -219,6 +219,9 @@ // Symbol Traits //===----------------------------------------------------------------------===// +// Op defines a global symbol. +def GlobalSymbol : NativeOpTrait<"GlobalSymbol", [Symbol]>; + // Op defines a symbol table. def SymbolTable : NativeOpTrait<"SymbolTable">; diff --git a/mlir/include/mlir/IR/SymbolTable.h b/mlir/include/mlir/IR/SymbolTable.h --- a/mlir/include/mlir/IR/SymbolTable.h +++ b/mlir/include/mlir/IR/SymbolTable.h @@ -448,4 +448,25 @@ /// Include the generated symbol interfaces. #include "mlir/IR/SymbolInterfaces.h.inc" +namespace mlir { +namespace OpTrait { +/// This trait is for operations defining a global value within the context of a +/// module, whether variable or constant. These operations must also implement +/// the Symbol trait and cannot produce results. Examples of such operations +/// include `llvm.global`, `memref.global`, and `gpu.binary`. Operations with a +/// more complex internal structure, such as functions, modules, or other +/// values, should not use this trait. +template +class GlobalSymbol : public TraitBase { + static LogicalResult verifyTrait(Operation *op) { + static_assert(ConcreteType::template hasTrait(), + "expected operation must have zero results"); + static_assert(ConcreteType::template hasTrait(), + "expected operation must inherit the `Symbol` trait"); + return success(); + } +}; +} // namespace OpTrait +} // namespace mlir + #endif // MLIR_IR_SYMBOLTABLE_H diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -699,7 +699,8 @@ } /// Create named global variables that correspond to llvm.mlir.global -/// definitions. Convert llvm.global_ctors and global_dtors ops. +/// definitions. Convert llvm.global_ctors and global_dtors ops. Finally convert +/// operations with the `GlobalSymbol` trait. LogicalResult ModuleTranslation::convertGlobals() { for (auto op : getModuleBody(mlirModule).getOps()) { llvm::Type *type = convertType(op.getType()); @@ -802,6 +803,18 @@ if (failed(convertDialectAttributes(op))) return failure(); + // Convert operations having the `GlobalSymbol` trait. + { + llvm::IRBuilder<> llvmBuilder(llvmModule->getContext()); + for (Operation &op : getModuleBody(mlirModule).getOperations()) { + if (!isa(&op) && + op.hasTrait() && + failed(convertOperation(op, llvmBuilder))) { + return failure(); + } + } + } + return success(); } @@ -1400,6 +1413,7 @@ if (!isa(&o) && !o.hasTrait() && + !o.hasTrait() && failed(translator.convertOperation(o, llvmBuilder))) { return nullptr; }