From c46a88625d09a656f7be8778e0df3d8332b27346 Mon Sep 17 00:00:00 2001 From: clementval Date: Mon, 19 Apr 2021 21:45:01 -0400 Subject: [PATCH] [mlir][llvm] Add UnnamedAddr attribute to GlobalOp This patch add the UnnamedAddr attribute for the GlobalOp in the LLVM dialect. The attribute is also handled to and from LLVM IR. This is meant to be used in a follow up patch to lower OpenACC/OpenMP ops to call to kmp and tgt runtime calls (D100678). Reviewed By: mehdi_amini Differential Revision: https://reviews.llvm.org/D100677 --- mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 14 +++++++++++++- mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 16 +++++++++++++++- mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp | 3 +++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 3 +++ mlir/test/Dialect/LLVMIR/global.mlir | 6 ++++++ mlir/test/Target/LLVMIR/import.ll | 14 +++++++++++++- mlir/test/Target/LLVMIR/llvmir.mlir | 10 ++++++++++ 7 files changed, 63 insertions(+), 3 deletions(-) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 3623565d169f..1ff060a41850 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -780,6 +780,17 @@ def Linkage : LLVM_EnumAttr< let cppNamespace = "::mlir::LLVM"; } +def UnnamedAddrNone : LLVM_EnumAttrCase<"None", "", "None", 0>; +def UnnamedAddrLocal : LLVM_EnumAttrCase<"Local", "local_unnamed_addr", "Local", 1>; +def UnnamedAddrGlobal : LLVM_EnumAttrCase<"Global", "unnamed_addr", "Global", 2>; + +def UnnamedAddr : LLVM_EnumAttr< + "UnnamedAddr", + "::llvm::GlobalValue::UnnamedAddr", + "LLVM GlobalValue UnnamedAddr", + [UnnamedAddrNone, UnnamedAddrLocal, UnnamedAddrGlobal]> { + let cppNamespace = "::mlir::LLVM"; +} def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof"> { let arguments = (ins FlatSymbolRefAttr:$global_name); @@ -896,7 +907,8 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global", StrAttr:$sym_name, Linkage:$linkage, OptionalAttr:$value, - DefaultValuedAttr, "0">:$addr_space + DefaultValuedAttr, "0">:$addr_space, + OptionalAttr:$unnamed_addr ); let summary = "LLVM dialect global."; let description = [{ diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index bfc90b2ac674..e1ad37e75d86 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -1244,6 +1244,10 @@ static LogicalResult verify(AddressOfOp op) { /// the name of the attribute in ODS. static StringRef getLinkageAttrName() { return "linkage"; } +/// Returns the name used for the unnamed_addr attribute. This *must* correspond +/// to the name of the attribute in ODS. +static StringRef getUnnamedAddrAttrName() { return "unnamed_addr"; } + void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type, bool isConstant, Linkage linkage, StringRef name, Attribute value, unsigned addrSpace, @@ -1265,6 +1269,8 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type, static void printGlobalOp(OpAsmPrinter &p, GlobalOp op) { p << op.getOperationName() << ' ' << stringifyLinkage(op.linkage()) << ' '; + if (op.unnamed_addr()) + p << stringifyUnnamedAddr(*op.unnamed_addr()) << ' '; if (op.constant()) p << "constant "; p.printSymbolName(op.sym_name()); @@ -1274,7 +1280,8 @@ static void printGlobalOp(OpAsmPrinter &p, GlobalOp op) { p << ')'; p.printOptionalAttrDict(op->getAttrs(), {SymbolTable::getSymbolAttrName(), "type", "constant", - "value", getLinkageAttrName()}); + "value", getLinkageAttrName(), + getUnnamedAddrAttrName()}); // Print the trailing type unless it's a string global. if (op.getValueOrNull().dyn_cast_or_null()) @@ -1495,6 +1502,7 @@ template struct EnumTraits {}; } REGISTER_ENUM_TYPE(Linkage); +REGISTER_ENUM_TYPE(UnnamedAddr); } // end namespace template @@ -1524,6 +1532,12 @@ static ParseResult parseGlobalOp(OpAsmParser &parser, OperationState &result) { parser.getBuilder().getI64IntegerAttr( static_cast(LLVM::Linkage::External))); + if (failed(parseOptionalLLVMKeyword(parser, result, + getUnnamedAddrAttrName()))) + result.addAttribute(getUnnamedAddrAttrName(), + parser.getBuilder().getI64IntegerAttr( + static_cast(LLVM::UnnamedAddr::None))); + if (succeeded(parser.parseOptionalKeyword("constant"))) result.addAttribute("constant", parser.getBuilder().getUnitAttr()); diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp index 8044ff62f642..e1e57bbc405f 100644 --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -487,6 +487,9 @@ GlobalOp Importer::processGlobal(llvm::GlobalVariable *GV) { return nullptr; b.create(op.getLoc(), ArrayRef({v})); } + if (GV->hasAtLeastLocalUnnamedAddr()) + op.unnamed_addrAttr(UnnamedAddrAttr::get( + context, convertUnnamedAddrFromLLVM(GV->getUnnamedAddr()))); return globals[GV] = op; } diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 01939f10ff4c..33d439d8afd3 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -407,6 +407,9 @@ LogicalResult ModuleTranslation::convertGlobals() { op.sym_name(), /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal, addrSpace); + if (op.unnamed_addr().hasValue()) + var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.unnamed_addr())); + globalsMapping.try_emplace(op, var); } diff --git a/mlir/test/Dialect/LLVMIR/global.mlir b/mlir/test/Dialect/LLVMIR/global.mlir index 0484f4ad2eae..23f77ab37fe5 100644 --- a/mlir/test/Dialect/LLVMIR/global.mlir +++ b/mlir/test/Dialect/LLVMIR/global.mlir @@ -63,6 +63,12 @@ func @references() { llvm.return } +// CHECK: llvm.mlir.global private local_unnamed_addr constant @local(42 : i64) : i64 +llvm.mlir.global private local_unnamed_addr constant @local(42 : i64) : i64 + +// CHECK: llvm.mlir.global private unnamed_addr constant @foo(42 : i64) : i64 +llvm.mlir.global private unnamed_addr constant @foo(42 : i64) : i64 + // ----- // expected-error @+1 {{requires string attribute 'sym_name'}} diff --git a/mlir/test/Target/LLVMIR/import.ll b/mlir/test/Target/LLVMIR/import.ll index df4de3713dca..c208b7612d41 100644 --- a/mlir/test/Target/LLVMIR/import.ll +++ b/mlir/test/Target/LLVMIR/import.ll @@ -49,6 +49,18 @@ ; CHECK: llvm.mlir.global external @external() : i32 @external = external global i32 +; +; UnnamedAddr attribute. +; + + +; CHECK: llvm.mlir.global private constant @no_unnamed_addr(42 : i64) : i64 +@no_unnamed_addr = private constant i64 42 +; CHECK: llvm.mlir.global private local_unnamed_addr constant @local_unnamed_addr(42 : i64) : i64 +@local_unnamed_addr = private local_unnamed_addr constant i64 42 +; CHECK: llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) : i64 +@unnamed_addr = private unnamed_addr constant i64 42 + ; ; Sequential constants. ; @@ -109,7 +121,7 @@ entry: if.then: ; CHECK: llvm.return %[[c42]] : i32 ret i32 42 - + ; CHECK: ^bb2: if.end: ; CHECK: %[[orcond:[0-9]+]] = llvm.or %[[e]], %[[c1]] : i1 diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index abf997cef4fd..abaec730ef12 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -59,6 +59,16 @@ llvm.mlir.global weak_odr @weak_odr(42 : i32) : i32 // CHECK: @external = external global i32 llvm.mlir.global external @external() : i32 +// +// UnnamedAddr attribute. +// + +// CHECK: @no_unnamed_addr = private constant i64 42 +llvm.mlir.global private constant @no_unnamed_addr(42 : i64) : i64 +// CHECK: @local_unnamed_addr = private local_unnamed_addr constant i64 42 +llvm.mlir.global private local_unnamed_addr constant @local_unnamed_addr(42 : i64) : i64 +// CHECK: @unnamed_addr = private unnamed_addr constant i64 42 +llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) : i64 // // Declarations of the allocation functions to be linked against. These are