Skip to content

Commit f0ba32d

Browse files
committed
[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
1 parent 36de2d6 commit f0ba32d

File tree

7 files changed

+97
-48
lines changed

7 files changed

+97
-48
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
10011001
StrAttr:$sym_name,
10021002
Linkage:$linkage,
10031003
UnitAttr:$dso_local,
1004+
UnitAttr:$thread_local_,
10041005
OptionalAttr<AnyAttr>:$value,
10051006
OptionalAttr<I64Attr>:$alignment,
10061007
DefaultValuedAttr<Confined<I32Attr, [IntNonNegative]>, "0">:$addr_space,
@@ -1112,6 +1113,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
11121113
CArg<"uint64_t", "0">:$alignment,
11131114
CArg<"unsigned", "0">:$addrSpace,
11141115
CArg<"bool", "false">:$dsoLocal,
1116+
CArg<"bool", "false">:$thread_local_,
11151117
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
11161118
];
11171119

mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,38 +1579,38 @@ LogicalResult AddressOfOp::verify() {
15791579
// Builder, printer and verifier for LLVM::GlobalOp.
15801580
//===----------------------------------------------------------------------===//
15811581

1582-
/// Returns the name used for the linkage attribute. This *must* correspond to
1583-
/// the name of the attribute in ODS.
1584-
static StringRef getLinkageAttrName() { return "linkage"; }
1585-
1586-
/// Returns the name used for the unnamed_addr attribute. This *must* correspond
1587-
/// to the name of the attribute in ODS.
1588-
static StringRef getUnnamedAddrAttrName() { return "unnamed_addr"; }
1589-
15901582
void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
15911583
bool isConstant, Linkage linkage, StringRef name,
15921584
Attribute value, uint64_t alignment, unsigned addrSpace,
1593-
bool dsoLocal, ArrayRef<NamedAttribute> attrs) {
1594-
result.addAttribute(SymbolTable::getSymbolAttrName(),
1585+
bool dsoLocal, bool threadLocal,
1586+
ArrayRef<NamedAttribute> attrs) {
1587+
result.addAttribute(getSymNameAttrName(result.name),
15951588
builder.getStringAttr(name));
1596-
result.addAttribute("global_type", TypeAttr::get(type));
1589+
result.addAttribute(getGlobalTypeAttrName(result.name), TypeAttr::get(type));
15971590
if (isConstant)
1598-
result.addAttribute("constant", builder.getUnitAttr());
1591+
result.addAttribute(getConstantAttrName(result.name),
1592+
builder.getUnitAttr());
15991593
if (value)
1600-
result.addAttribute("value", value);
1594+
result.addAttribute(getValueAttrName(result.name), value);
16011595
if (dsoLocal)
1602-
result.addAttribute("dso_local", builder.getUnitAttr());
1596+
result.addAttribute(getDsoLocalAttrName(result.name),
1597+
builder.getUnitAttr());
1598+
if (threadLocal)
1599+
result.addAttribute(getThreadLocal_AttrName(result.name),
1600+
builder.getUnitAttr());
16031601

16041602
// Only add an alignment attribute if the "alignment" input
16051603
// is different from 0. The value must also be a power of two, but
16061604
// this is tested in GlobalOp::verify, not here.
16071605
if (alignment != 0)
1608-
result.addAttribute("alignment", builder.getI64IntegerAttr(alignment));
1606+
result.addAttribute(getAlignmentAttrName(result.name),
1607+
builder.getI64IntegerAttr(alignment));
16091608

1610-
result.addAttribute(::getLinkageAttrName(),
1609+
result.addAttribute(getLinkageAttrName(result.name),
16111610
LinkageAttr::get(builder.getContext(), linkage));
16121611
if (addrSpace != 0)
1613-
result.addAttribute("addr_space", builder.getI32IntegerAttr(addrSpace));
1612+
result.addAttribute(getAddrSpaceAttrName(result.name),
1613+
builder.getI32IntegerAttr(addrSpace));
16141614
result.attributes.append(attrs.begin(), attrs.end());
16151615
result.addRegion();
16161616
}
@@ -1622,6 +1622,8 @@ void GlobalOp::print(OpAsmPrinter &p) {
16221622
if (!str.empty())
16231623
p << str << ' ';
16241624
}
1625+
if (getThreadLocal_())
1626+
p << "thread_local ";
16251627
if (getConstant())
16261628
p << "constant ";
16271629
p.printSymbolName(getSymName());
@@ -1632,10 +1634,11 @@ void GlobalOp::print(OpAsmPrinter &p) {
16321634
// Note that the alignment attribute is printed using the
16331635
// default syntax here, even though it is an inherent attribute
16341636
// (as defined in https://mlir.llvm.org/docs/LangRef/#attributes)
1635-
p.printOptionalAttrDict((*this)->getAttrs(),
1636-
{SymbolTable::getSymbolAttrName(), "global_type",
1637-
"constant", "value", getLinkageAttrName(),
1638-
getUnnamedAddrAttrName()});
1637+
p.printOptionalAttrDict(
1638+
(*this)->getAttrs(),
1639+
{SymbolTable::getSymbolAttrName(), getGlobalTypeAttrName(),
1640+
getConstantAttrName(), getValueAttrName(), getLinkageAttrName(),
1641+
getUnnamedAddrAttrName(), getThreadLocal_AttrName()});
16391642

16401643
// Print the trailing type unless it's a string global.
16411644
if (getValueOrNull().dyn_cast_or_null<StringAttr>())
@@ -1702,28 +1705,35 @@ static RetTy parseOptionalLLVMKeyword(OpAsmParser &parser,
17021705
ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
17031706
MLIRContext *ctx = parser.getContext();
17041707
// Parse optional linkage, default to External.
1705-
result.addAttribute(::getLinkageAttrName(),
1708+
result.addAttribute(getLinkageAttrName(result.name),
17061709
LLVM::LinkageAttr::get(
17071710
ctx, parseOptionalLLVMKeyword<Linkage>(
17081711
parser, result, LLVM::Linkage::External)));
1712+
1713+
if (succeeded(parser.parseOptionalKeyword("thread_local")))
1714+
result.addAttribute(getThreadLocal_AttrName(result.name),
1715+
parser.getBuilder().getUnitAttr());
1716+
17091717
// Parse optional UnnamedAddr, default to None.
1710-
result.addAttribute(::getUnnamedAddrAttrName(),
1718+
result.addAttribute(getUnnamedAddrAttrName(result.name),
17111719
parser.getBuilder().getI64IntegerAttr(
17121720
parseOptionalLLVMKeyword<UnnamedAddr, int64_t>(
17131721
parser, result, LLVM::UnnamedAddr::None)));
17141722

17151723
if (succeeded(parser.parseOptionalKeyword("constant")))
1716-
result.addAttribute("constant", parser.getBuilder().getUnitAttr());
1724+
result.addAttribute(getConstantAttrName(result.name),
1725+
parser.getBuilder().getUnitAttr());
17171726

17181727
StringAttr name;
1719-
if (parser.parseSymbolName(name, SymbolTable::getSymbolAttrName(),
1728+
if (parser.parseSymbolName(name, getSymNameAttrName(result.name),
17201729
result.attributes) ||
17211730
parser.parseLParen())
17221731
return failure();
17231732

17241733
Attribute value;
17251734
if (parser.parseOptionalRParen()) {
1726-
if (parser.parseAttribute(value, "value", result.attributes) ||
1735+
if (parser.parseAttribute(value, getValueAttrName(result.name),
1736+
result.attributes) ||
17271737
parser.parseRParen())
17281738
return failure();
17291739
}
@@ -1755,7 +1765,8 @@ ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
17551765
return failure();
17561766
}
17571767

1758-
result.addAttribute("global_type", TypeAttr::get(types[0]));
1768+
result.addAttribute(getGlobalTypeAttrName(result.name),
1769+
TypeAttr::get(types[0]));
17591770
return success();
17601771
}
17611772

@@ -1976,7 +1987,7 @@ void LLVMFuncOp::build(OpBuilder &builder, OperationState &result,
19761987
builder.getStringAttr(name));
19771988
result.addAttribute(getFunctionTypeAttrName(result.name),
19781989
TypeAttr::get(type));
1979-
result.addAttribute(::getLinkageAttrName(),
1990+
result.addAttribute(getLinkageAttrName(result.name),
19801991
LinkageAttr::get(builder.getContext(), linkage));
19811992
result.attributes.append(attrs.begin(), attrs.end());
19821993
if (dsoLocal)
@@ -2036,7 +2047,7 @@ buildLLVMFunctionType(OpAsmParser &parser, SMLoc loc, ArrayRef<Type> inputs,
20362047
ParseResult LLVMFuncOp::parse(OpAsmParser &parser, OperationState &result) {
20372048
// Default to external linkage if no keyword is provided.
20382049
result.addAttribute(
2039-
::getLinkageAttrName(),
2050+
getLinkageAttrName(result.name),
20402051
LinkageAttr::get(parser.getContext(),
20412052
parseOptionalLLVMKeyword<Linkage>(
20422053
parser, result, LLVM::Linkage::External)));

mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,10 +432,11 @@ GlobalOp Importer::processGlobal(llvm::GlobalVariable *gv) {
432432
alignment = align.value();
433433
}
434434

435-
GlobalOp op =
436-
b.create<GlobalOp>(UnknownLoc::get(context), type, gv->isConstant(),
437-
convertLinkageFromLLVM(gv->getLinkage()),
438-
gv->getName(), valueAttr, alignment);
435+
GlobalOp op = b.create<GlobalOp>(
436+
UnknownLoc::get(context), type, gv->isConstant(),
437+
convertLinkageFromLLVM(gv->getLinkage()), gv->getName(), valueAttr,
438+
alignment, /*addr_space=*/gv->getAddressSpace(),
439+
/*dso_local=*/gv->isDSOLocal(), /*thread_local=*/gv->isThreadLocal());
439440

440441
if (gv->hasInitializer() && !valueAttr) {
441442
Region &r = op.getInitializerRegion();

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,10 @@ LogicalResult ModuleTranslation::convertGlobals() {
661661

662662
auto *var = new llvm::GlobalVariable(
663663
*llvmModule, type, op.getConstant(), linkage, cst, op.getSymName(),
664-
/*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal, addrSpace);
664+
/*InsertBefore=*/nullptr,
665+
op.getThreadLocal_() ? llvm::GlobalValue::GeneralDynamicTLSModel
666+
: llvm::GlobalValue::NotThreadLocal,
667+
addrSpace);
665668

666669
if (op.getUnnamedAddr().hasValue())
667670
var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));

mlir/test/Dialect/LLVMIR/global.mlir

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ llvm.mlir.global extern_weak @extern_weak() : i64
5757
llvm.mlir.global linkonce_odr @linkonce_odr() : i64
5858
// CHECK: llvm.mlir.global weak_odr
5959
llvm.mlir.global weak_odr @weak_odr() : i64
60+
// CHECK: llvm.mlir.global external @has_thr_local(42 : i64) {thr_local} : i64
61+
llvm.mlir.global external @has_thr_local(42 : i64) {thr_local} : i64
62+
// CHECK: llvm.mlir.global external @has_dso_local(42 : i64) {dso_local} : i64
63+
llvm.mlir.global external @has_dso_local(42 : i64) {dso_local} : i64
6064

6165
// CHECK-LABEL: references
6266
func @references() {

mlir/test/Target/LLVMIR/import.ll

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,49 @@
1313
; CHECK: llvm.mlir.global external @g5() : vector<8xi32>
1414
@g5 = external global <8 x i32>
1515

16-
; CHECK: llvm.mlir.global private @alig32(42 : i64) {alignment = 32 : i64} : i64
16+
; CHECK: llvm.mlir.global private @alig32(42 : i64) {alignment = 32 : i64, dso_local} : i64
1717
@alig32 = private global i64 42, align 32
1818

19-
; CHECK: llvm.mlir.global private @alig64(42 : i64) {alignment = 64 : i64} : i64
19+
; CHECK: llvm.mlir.global private @alig64(42 : i64) {alignment = 64 : i64, dso_local} : i64
2020
@alig64 = private global i64 42, align 64
2121

2222
@g4 = external global i32, align 8
23-
; CHECK: llvm.mlir.global internal constant @int_gep() : !llvm.ptr<i32> {
23+
; CHECK: llvm.mlir.global internal constant @int_gep() {dso_local} : !llvm.ptr<i32> {
2424
; CHECK-DAG: %[[addr:[0-9]+]] = llvm.mlir.addressof @g4 : !llvm.ptr<i32>
2525
; CHECK-DAG: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32
2626
; CHECK-NEXT: %[[gepinit:[0-9]+]] = llvm.getelementptr %[[addr]][%[[c2]]] : (!llvm.ptr<i32>, i32) -> !llvm.ptr<i32>
2727
; CHECK-NEXT: llvm.return %[[gepinit]] : !llvm.ptr<i32>
2828
; CHECK-NEXT: }
2929
@int_gep = internal constant i32* getelementptr (i32, i32* @g4, i32 2)
3030

31+
;
32+
; dso_local attribute
33+
;
34+
35+
; CHECK: llvm.mlir.global external @dso_local_var() {dso_local} : !llvm.struct<"struct.s", (struct<"struct.t", ()>, i64)>
36+
@dso_local_var = external dso_local global %struct.s
37+
38+
;
39+
; thread_local attribute
40+
;
41+
42+
; CHECK: llvm.mlir.global external thread_local @thread_local_var() : !llvm.struct<"struct.s", (struct<"struct.t", ()>, i64)>
43+
@thread_local_var = external thread_local global %struct.s
44+
45+
;
46+
; addr_space attribute
47+
;
48+
49+
; CHECK: llvm.mlir.global external @addr_space_var(0 : i32) {addr_space = 6 : i32} : i32
50+
@addr_space_var = addrspace(6) global i32 0
51+
3152
;
3253
; Linkage attribute.
3354
;
3455

35-
; CHECK: llvm.mlir.global private @private(42 : i32) : i32
56+
; CHECK: llvm.mlir.global private @private(42 : i32) {dso_local} : i32
3657
@private = private global i32 42
37-
; CHECK: llvm.mlir.global internal @internal(42 : i32) : i32
58+
; CHECK: llvm.mlir.global internal @internal(42 : i32) {dso_local} : i32
3859
@internal = internal global i32 42
3960
; CHECK: llvm.mlir.global available_externally @available_externally(42 : i32) : i32
4061
@available_externally = available_externally global i32 42
@@ -60,33 +81,33 @@
6081
;
6182

6283

63-
; CHECK: llvm.mlir.global private constant @no_unnamed_addr(42 : i64) : i64
84+
; CHECK: llvm.mlir.global private constant @no_unnamed_addr(42 : i64) {dso_local} : i64
6485
@no_unnamed_addr = private constant i64 42
65-
; CHECK: llvm.mlir.global private local_unnamed_addr constant @local_unnamed_addr(42 : i64) : i64
86+
; CHECK: llvm.mlir.global private local_unnamed_addr constant @local_unnamed_addr(42 : i64) {dso_local} : i64
6687
@local_unnamed_addr = private local_unnamed_addr constant i64 42
67-
; CHECK: llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) : i64
88+
; CHECK: llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) {dso_local} : i64
6889
@unnamed_addr = private unnamed_addr constant i64 42
6990

7091
;
7192
; Section attribute
7293
;
7394

74-
; CHECK: llvm.mlir.global internal constant @sectionvar("teststring") {section = ".mysection"}
95+
; CHECK: llvm.mlir.global internal constant @sectionvar("teststring") {dso_local, section = ".mysection"}
7596
@sectionvar = internal constant [10 x i8] c"teststring", section ".mysection"
7697

7798
;
7899
; Sequential constants.
79100
;
80101

81-
; CHECK: llvm.mlir.global internal constant @vector_constant(dense<[1, 2]> : vector<2xi32>) : vector<2xi32>
102+
; CHECK: llvm.mlir.global internal constant @vector_constant(dense<[1, 2]> : vector<2xi32>) {dso_local} : vector<2xi32>
82103
@vector_constant = internal constant <2 x i32> <i32 1, i32 2>
83-
; CHECK: llvm.mlir.global internal constant @array_constant(dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf32>) : !llvm.array<2 x f32>
104+
; CHECK: llvm.mlir.global internal constant @array_constant(dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf32>) {dso_local} : !llvm.array<2 x f32>
84105
@array_constant = internal constant [2 x float] [float 1., float 2.]
85-
; CHECK: llvm.mlir.global internal constant @nested_array_constant(dense<[{{\[}}1, 2], [3, 4]]> : tensor<2x2xi32>) : !llvm.array<2 x array<2 x i32>>
106+
; 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>>
86107
@nested_array_constant = internal constant [2 x [2 x i32]] [[2 x i32] [i32 1, i32 2], [2 x i32] [i32 3, i32 4]]
87-
; 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>>>
108+
; 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>>>
88109
@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]]]
89-
; 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>>>
110+
; 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>>>
90111
@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>]]
91112

92113
;

mlir/test/Target/LLVMIR/llvmir.mlir

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) : i64
128128
llvm.mlir.global @has_dso_local(42 : i64) {dso_local} : i64
129129
// CHECK: @has_dso_local = dso_local global i64 42
130130

131+
//
132+
// thr_local attribute.
133+
//
134+
135+
llvm.mlir.global thread_local @has_thr_local(42 : i64) : i64
136+
// CHECK: @has_thr_local = thread_local global i64 42
137+
131138
//
132139
// Section attribute.
133140
//

0 commit comments

Comments
 (0)