Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mlir
diff options
context:
space:
mode:
authorShraiysh Vaishay <Shraiysh.Vaishay@amd.com>2022-04-13 05:50:56 +0300
committerShraiysh Vaishay <Shraiysh.Vaishay@amd.com>2022-04-13 06:01:01 +0300
commitf0ba32d6667b2ea9a58c7dbd5f27984da9d335fc (patch)
tree002d5808beff16b501888550487400293f9bf229 /mlir
parent36de2d639eca4cead62a6c6d288a501cee8bb6e7 (diff)
[mlir][LLVM-IR] Added support for global variable attributes
This patch adds thread_local to llvm.mlir.global and adds translation for dso_local and addr_space to and from LLVM IR. Reviewed By: Mogball Differential Revision: https://reviews.llvm.org/D123412
Diffstat (limited to 'mlir')
-rw-r--r--mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td2
-rw-r--r--mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp69
-rw-r--r--mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp9
-rw-r--r--mlir/lib/Target/LLVMIR/ModuleTranslation.cpp5
-rw-r--r--mlir/test/Dialect/LLVMIR/global.mlir4
-rw-r--r--mlir/test/Target/LLVMIR/import.ll49
-rw-r--r--mlir/test/Target/LLVMIR/llvmir.mlir7
7 files changed, 97 insertions, 48 deletions
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 29a3d5f06853..e5b0fc577a63 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1001,6 +1001,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
StrAttr:$sym_name,
Linkage:$linkage,
UnitAttr:$dso_local,
+ UnitAttr:$thread_local_,
OptionalAttr<AnyAttr>:$value,
OptionalAttr<I64Attr>:$alignment,
DefaultValuedAttr<Confined<I32Attr, [IntNonNegative]>, "0">:$addr_space,
@@ -1112,6 +1113,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
CArg<"uint64_t", "0">:$alignment,
CArg<"unsigned", "0">:$addrSpace,
CArg<"bool", "false">:$dsoLocal,
+ CArg<"bool", "false">:$thread_local_,
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
];
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index bf8d487ccb49..3fc042d17c57 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1579,38 +1579,38 @@ LogicalResult AddressOfOp::verify() {
// Builder, printer and verifier for LLVM::GlobalOp.
//===----------------------------------------------------------------------===//
-/// Returns the name used for the linkage attribute. This *must* correspond to
-/// 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, uint64_t alignment, unsigned addrSpace,
- bool dsoLocal, ArrayRef<NamedAttribute> attrs) {
- result.addAttribute(SymbolTable::getSymbolAttrName(),
+ bool dsoLocal, bool threadLocal,
+ ArrayRef<NamedAttribute> attrs) {
+ result.addAttribute(getSymNameAttrName(result.name),
builder.getStringAttr(name));
- result.addAttribute("global_type", TypeAttr::get(type));
+ result.addAttribute(getGlobalTypeAttrName(result.name), TypeAttr::get(type));
if (isConstant)
- result.addAttribute("constant", builder.getUnitAttr());
+ result.addAttribute(getConstantAttrName(result.name),
+ builder.getUnitAttr());
if (value)
- result.addAttribute("value", value);
+ result.addAttribute(getValueAttrName(result.name), value);
if (dsoLocal)
- result.addAttribute("dso_local", builder.getUnitAttr());
+ result.addAttribute(getDsoLocalAttrName(result.name),
+ builder.getUnitAttr());
+ if (threadLocal)
+ result.addAttribute(getThreadLocal_AttrName(result.name),
+ builder.getUnitAttr());
// Only add an alignment attribute if the "alignment" input
// is different from 0. The value must also be a power of two, but
// this is tested in GlobalOp::verify, not here.
if (alignment != 0)
- result.addAttribute("alignment", builder.getI64IntegerAttr(alignment));
+ result.addAttribute(getAlignmentAttrName(result.name),
+ builder.getI64IntegerAttr(alignment));
- result.addAttribute(::getLinkageAttrName(),
+ result.addAttribute(getLinkageAttrName(result.name),
LinkageAttr::get(builder.getContext(), linkage));
if (addrSpace != 0)
- result.addAttribute("addr_space", builder.getI32IntegerAttr(addrSpace));
+ result.addAttribute(getAddrSpaceAttrName(result.name),
+ builder.getI32IntegerAttr(addrSpace));
result.attributes.append(attrs.begin(), attrs.end());
result.addRegion();
}
@@ -1622,6 +1622,8 @@ void GlobalOp::print(OpAsmPrinter &p) {
if (!str.empty())
p << str << ' ';
}
+ if (getThreadLocal_())
+ p << "thread_local ";
if (getConstant())
p << "constant ";
p.printSymbolName(getSymName());
@@ -1632,10 +1634,11 @@ void GlobalOp::print(OpAsmPrinter &p) {
// Note that the alignment attribute is printed using the
// default syntax here, even though it is an inherent attribute
// (as defined in https://mlir.llvm.org/docs/LangRef/#attributes)
- p.printOptionalAttrDict((*this)->getAttrs(),
- {SymbolTable::getSymbolAttrName(), "global_type",
- "constant", "value", getLinkageAttrName(),
- getUnnamedAddrAttrName()});
+ p.printOptionalAttrDict(
+ (*this)->getAttrs(),
+ {SymbolTable::getSymbolAttrName(), getGlobalTypeAttrName(),
+ getConstantAttrName(), getValueAttrName(), getLinkageAttrName(),
+ getUnnamedAddrAttrName(), getThreadLocal_AttrName()});
// Print the trailing type unless it's a string global.
if (getValueOrNull().dyn_cast_or_null<StringAttr>())
@@ -1702,28 +1705,35 @@ static RetTy parseOptionalLLVMKeyword(OpAsmParser &parser,
ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
MLIRContext *ctx = parser.getContext();
// Parse optional linkage, default to External.
- result.addAttribute(::getLinkageAttrName(),
+ result.addAttribute(getLinkageAttrName(result.name),
LLVM::LinkageAttr::get(
ctx, parseOptionalLLVMKeyword<Linkage>(
parser, result, LLVM::Linkage::External)));
+
+ if (succeeded(parser.parseOptionalKeyword("thread_local")))
+ result.addAttribute(getThreadLocal_AttrName(result.name),
+ parser.getBuilder().getUnitAttr());
+
// Parse optional UnnamedAddr, default to None.
- result.addAttribute(::getUnnamedAddrAttrName(),
+ result.addAttribute(getUnnamedAddrAttrName(result.name),
parser.getBuilder().getI64IntegerAttr(
parseOptionalLLVMKeyword<UnnamedAddr, int64_t>(
parser, result, LLVM::UnnamedAddr::None)));
if (succeeded(parser.parseOptionalKeyword("constant")))
- result.addAttribute("constant", parser.getBuilder().getUnitAttr());
+ result.addAttribute(getConstantAttrName(result.name),
+ parser.getBuilder().getUnitAttr());
StringAttr name;
- if (parser.parseSymbolName(name, SymbolTable::getSymbolAttrName(),
+ if (parser.parseSymbolName(name, getSymNameAttrName(result.name),
result.attributes) ||
parser.parseLParen())
return failure();
Attribute value;
if (parser.parseOptionalRParen()) {
- if (parser.parseAttribute(value, "value", result.attributes) ||
+ if (parser.parseAttribute(value, getValueAttrName(result.name),
+ result.attributes) ||
parser.parseRParen())
return failure();
}
@@ -1755,7 +1765,8 @@ ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
return failure();
}
- result.addAttribute("global_type", TypeAttr::get(types[0]));
+ result.addAttribute(getGlobalTypeAttrName(result.name),
+ TypeAttr::get(types[0]));
return success();
}
@@ -1976,7 +1987,7 @@ void LLVMFuncOp::build(OpBuilder &builder, OperationState &result,
builder.getStringAttr(name));
result.addAttribute(getFunctionTypeAttrName(result.name),
TypeAttr::get(type));
- result.addAttribute(::getLinkageAttrName(),
+ result.addAttribute(getLinkageAttrName(result.name),
LinkageAttr::get(builder.getContext(), linkage));
result.attributes.append(attrs.begin(), attrs.end());
if (dsoLocal)
@@ -2036,7 +2047,7 @@ buildLLVMFunctionType(OpAsmParser &parser, SMLoc loc, ArrayRef<Type> inputs,
ParseResult LLVMFuncOp::parse(OpAsmParser &parser, OperationState &result) {
// Default to external linkage if no keyword is provided.
result.addAttribute(
- ::getLinkageAttrName(),
+ getLinkageAttrName(result.name),
LinkageAttr::get(parser.getContext(),
parseOptionalLLVMKeyword<Linkage>(
parser, result, LLVM::Linkage::External)));
diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
index 2f866e10dd8a..bda695c35ddb 100644
--- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
@@ -432,10 +432,11 @@ GlobalOp Importer::processGlobal(llvm::GlobalVariable *gv) {
alignment = align.value();
}
- GlobalOp op =
- b.create<GlobalOp>(UnknownLoc::get(context), type, gv->isConstant(),
- convertLinkageFromLLVM(gv->getLinkage()),
- gv->getName(), valueAttr, alignment);
+ GlobalOp op = b.create<GlobalOp>(
+ UnknownLoc::get(context), type, gv->isConstant(),
+ convertLinkageFromLLVM(gv->getLinkage()), gv->getName(), valueAttr,
+ alignment, /*addr_space=*/gv->getAddressSpace(),
+ /*dso_local=*/gv->isDSOLocal(), /*thread_local=*/gv->isThreadLocal());
if (gv->hasInitializer() && !valueAttr) {
Region &r = op.getInitializerRegion();
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 953fb2461520..127e7e15ccab 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -661,7 +661,10 @@ LogicalResult ModuleTranslation::convertGlobals() {
auto *var = new llvm::GlobalVariable(
*llvmModule, type, op.getConstant(), linkage, cst, op.getSymName(),
- /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal, addrSpace);
+ /*InsertBefore=*/nullptr,
+ op.getThreadLocal_() ? llvm::GlobalValue::GeneralDynamicTLSModel
+ : llvm::GlobalValue::NotThreadLocal,
+ addrSpace);
if (op.getUnnamedAddr().hasValue())
var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
diff --git a/mlir/test/Dialect/LLVMIR/global.mlir b/mlir/test/Dialect/LLVMIR/global.mlir
index bb0f6d7704e3..ab0f0c48042a 100644
--- a/mlir/test/Dialect/LLVMIR/global.mlir
+++ b/mlir/test/Dialect/LLVMIR/global.mlir
@@ -57,6 +57,10 @@ llvm.mlir.global extern_weak @extern_weak() : i64
llvm.mlir.global linkonce_odr @linkonce_odr() : i64
// CHECK: llvm.mlir.global weak_odr
llvm.mlir.global weak_odr @weak_odr() : i64
+// CHECK: llvm.mlir.global external @has_thr_local(42 : i64) {thr_local} : i64
+llvm.mlir.global external @has_thr_local(42 : i64) {thr_local} : i64
+// CHECK: llvm.mlir.global external @has_dso_local(42 : i64) {dso_local} : i64
+llvm.mlir.global external @has_dso_local(42 : i64) {dso_local} : i64
// CHECK-LABEL: references
func @references() {
diff --git a/mlir/test/Target/LLVMIR/import.ll b/mlir/test/Target/LLVMIR/import.ll
index c1deb500d1cf..35176a301b88 100644
--- a/mlir/test/Target/LLVMIR/import.ll
+++ b/mlir/test/Target/LLVMIR/import.ll
@@ -13,14 +13,14 @@
; CHECK: llvm.mlir.global external @g5() : vector<8xi32>
@g5 = external global <8 x i32>
-; CHECK: llvm.mlir.global private @alig32(42 : i64) {alignment = 32 : i64} : i64
+; CHECK: llvm.mlir.global private @alig32(42 : i64) {alignment = 32 : i64, dso_local} : i64
@alig32 = private global i64 42, align 32
-; CHECK: llvm.mlir.global private @alig64(42 : i64) {alignment = 64 : i64} : i64
+; CHECK: llvm.mlir.global private @alig64(42 : i64) {alignment = 64 : i64, dso_local} : i64
@alig64 = private global i64 42, align 64
@g4 = external global i32, align 8
-; CHECK: llvm.mlir.global internal constant @int_gep() : !llvm.ptr<i32> {
+; CHECK: llvm.mlir.global internal constant @int_gep() {dso_local} : !llvm.ptr<i32> {
; CHECK-DAG: %[[addr:[0-9]+]] = llvm.mlir.addressof @g4 : !llvm.ptr<i32>
; CHECK-DAG: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32
; CHECK-NEXT: %[[gepinit:[0-9]+]] = llvm.getelementptr %[[addr]][%[[c2]]] : (!llvm.ptr<i32>, i32) -> !llvm.ptr<i32>
@@ -29,12 +29,33 @@
@int_gep = internal constant i32* getelementptr (i32, i32* @g4, i32 2)
;
+; dso_local attribute
+;
+
+; CHECK: llvm.mlir.global external @dso_local_var() {dso_local} : !llvm.struct<"struct.s", (struct<"struct.t", ()>, i64)>
+@dso_local_var = external dso_local global %struct.s
+
+;
+; thread_local attribute
+;
+
+; CHECK: llvm.mlir.global external thread_local @thread_local_var() : !llvm.struct<"struct.s", (struct<"struct.t", ()>, i64)>
+@thread_local_var = external thread_local global %struct.s
+
+;
+; addr_space attribute
+;
+
+; CHECK: llvm.mlir.global external @addr_space_var(0 : i32) {addr_space = 6 : i32} : i32
+@addr_space_var = addrspace(6) global i32 0
+
+;
; Linkage attribute.
;
-; CHECK: llvm.mlir.global private @private(42 : i32) : i32
+; CHECK: llvm.mlir.global private @private(42 : i32) {dso_local} : i32
@private = private global i32 42
-; CHECK: llvm.mlir.global internal @internal(42 : i32) : i32
+; CHECK: llvm.mlir.global internal @internal(42 : i32) {dso_local} : i32
@internal = internal global i32 42
; CHECK: llvm.mlir.global available_externally @available_externally(42 : i32) : i32
@available_externally = available_externally global i32 42
@@ -60,33 +81,33 @@
;
-; CHECK: llvm.mlir.global private constant @no_unnamed_addr(42 : i64) : i64
+; CHECK: llvm.mlir.global private constant @no_unnamed_addr(42 : i64) {dso_local} : i64
@no_unnamed_addr = private constant i64 42
-; CHECK: llvm.mlir.global private local_unnamed_addr constant @local_unnamed_addr(42 : i64) : i64
+; CHECK: llvm.mlir.global private local_unnamed_addr constant @local_unnamed_addr(42 : i64) {dso_local} : i64
@local_unnamed_addr = private local_unnamed_addr constant i64 42
-; CHECK: llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) : i64
+; CHECK: llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) {dso_local} : i64
@unnamed_addr = private unnamed_addr constant i64 42
;
; Section attribute
;
-; CHECK: llvm.mlir.global internal constant @sectionvar("teststring") {section = ".mysection"}
+; CHECK: llvm.mlir.global internal constant @sectionvar("teststring") {dso_local, section = ".mysection"}
@sectionvar = internal constant [10 x i8] c"teststring", section ".mysection"
;
; Sequential constants.
;
-; CHECK: llvm.mlir.global internal constant @vector_constant(dense<[1, 2]> : vector<2xi32>) : vector<2xi32>
+; CHECK: llvm.mlir.global internal constant @vector_constant(dense<[1, 2]> : vector<2xi32>) {dso_local} : vector<2xi32>
@vector_constant = internal constant <2 x i32> <i32 1, i32 2>
-; CHECK: llvm.mlir.global internal constant @array_constant(dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf32>) : !llvm.array<2 x f32>
+; CHECK: llvm.mlir.global internal constant @array_constant(dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf32>) {dso_local} : !llvm.array<2 x f32>
@array_constant = internal constant [2 x float] [float 1., float 2.]
-; CHECK: llvm.mlir.global internal constant @nested_array_constant(dense<[{{\[}}1, 2], [3, 4]]> : tensor<2x2xi32>) : !llvm.array<2 x array<2 x i32>>
+; CHECK: llvm.mlir.global internal constant @nested_array_constant(dense<[{{\[}}1, 2], [3, 4]]> : tensor<2x2xi32>) {dso_local} : !llvm.array<2 x array<2 x i32>>
@nested_array_constant = internal constant [2 x [2 x i32]] [[2 x i32] [i32 1, i32 2], [2 x i32] [i32 3, i32 4]]
-; CHECK: llvm.mlir.global internal constant @nested_array_constant3(dense<[{{\[}}[1, 2], [3, 4]]]> : tensor<1x2x2xi32>) : !llvm.array<1 x array<2 x array<2 x i32>>>
+; CHECK: llvm.mlir.global internal constant @nested_array_constant3(dense<[{{\[}}[1, 2], [3, 4]]]> : tensor<1x2x2xi32>) {dso_local} : !llvm.array<1 x array<2 x array<2 x i32>>>
@nested_array_constant3 = internal constant [1 x [2 x [2 x i32]]] [[2 x [2 x i32]] [[2 x i32] [i32 1, i32 2], [2 x i32] [i32 3, i32 4]]]
-; CHECK: llvm.mlir.global internal constant @nested_array_vector(dense<[{{\[}}[1, 2], [3, 4]]]> : vector<1x2x2xi32>) : !llvm.array<1 x array<2 x vector<2xi32>>>
+; CHECK: llvm.mlir.global internal constant @nested_array_vector(dense<[{{\[}}[1, 2], [3, 4]]]> : vector<1x2x2xi32>) {dso_local} : !llvm.array<1 x array<2 x vector<2xi32>>>
@nested_array_vector = internal constant [1 x [2 x <2 x i32>]] [[2 x <2 x i32>] [<2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>]]
;
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 99b3f38d766d..cd14641944c3 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -129,6 +129,13 @@ llvm.mlir.global @has_dso_local(42 : i64) {dso_local} : i64
// CHECK: @has_dso_local = dso_local global i64 42
//
+// thr_local attribute.
+//
+
+llvm.mlir.global thread_local @has_thr_local(42 : i64) : i64
+// CHECK: @has_thr_local = thread_local global i64 42
+
+//
// Section attribute.
//