Skip to content

Commit 0337931

Browse files
committed
Add support for thread-local globals
1 parent 4bb81b3 commit 0337931

File tree

3 files changed

+61
-8
lines changed

3 files changed

+61
-8
lines changed

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

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,26 @@ def Linkage : LLVM_EnumAttr<
538538
let cppNamespace = "::mlir::LLVM";
539539
}
540540

541+
def ThreadLocalModeNotThreadLocal
542+
: LLVM_EnumAttrCase<"NotThreadLocal", "not_thread_local", "NotThreadLocal", 0>;
543+
def ThreadLocalModeGeneralDynamic
544+
: LLVM_EnumAttrCase<"GeneralDynamic", "general_dynamic", "GeneralDynamicTLSModel", 1>;
545+
def ThreadLocalModeLocalDynamic
546+
: LLVM_EnumAttrCase<"LocalDynamic", "local_dynamic", "LocalDynamicTLSModel", 2>;
547+
def ThreadLocalModeInitialExec
548+
: LLVM_EnumAttrCase<"InitialExec", "initial_exec", "InitialExecTLSModel", 3>;
549+
def ThreadLocalModeLocalExec
550+
: LLVM_EnumAttrCase<"LocalExec", "local_exec", "LocalExecTLSModel", 4>;
551+
552+
def ThreadLocalMode : LLVM_EnumAttr<
553+
"ThreadLocalMode",
554+
"::llvm::GlobalValue::ThreadLocalMode",
555+
"LLVM thread local mode",
556+
[ThreadLocalModeNotThreadLocal,
557+
ThreadLocalModeGeneralDynamic, ThreadLocalModeLocalDynamic,
558+
ThreadLocalModeInitialExec, ThreadLocalModeLocalExec]> {
559+
let cppNamespace = "::mlir::LLVM";
560+
}
541561

542562
def LLVM_AddressOfOp
543563
: LLVM_OneResultOp<"mlir.addressof">,
@@ -572,6 +592,7 @@ def LLVM_GlobalOp
572592
SingleBlockImplicitTerminator<"ReturnOp">, Symbol]>,
573593
Arguments<(ins TypeAttr:$type, UnitAttr:$constant, StrAttr:$sym_name,
574594
Linkage:$linkage,
595+
ThreadLocalMode:$tls_mode,
575596
OptionalAttr<AnyAttr>:$value,
576597
DefaultValuedAttr<NonNegativeI32Attr, "0">:$addr_space)> {
577598
let summary = "LLVM dialect global.";
@@ -593,9 +614,25 @@ def LLVM_GlobalOp
593614

594615
let builders = [
595616
OpBuilder<"Builder *builder, OperationState &result, LLVMType type, "
596-
"bool isConstant, Linkage linkage, StringRef name, "
617+
"bool isConstant, Linkage linkage, ThreadLocalMode tlsMode,"
618+
"StringRef name,"
619+
"Attribute value, unsigned addrSpace = 0, "
620+
"ArrayRef<NamedAttribute> attrs = {}">,
621+
OpBuilder<"Builder *builder, OperationState &result, LLVMType type, "
622+
"bool isConstant, Linkage linkage,"
623+
"StringRef name,"
597624
"Attribute value, unsigned addrSpace = 0, "
598-
"ArrayRef<NamedAttribute> attrs = {}">
625+
"ArrayRef<NamedAttribute> attrs = {}",
626+
[{ build(builder,
627+
result,
628+
type,
629+
isConstant,
630+
linkage,
631+
ThreadLocalMode::NotThreadLocal,
632+
name,
633+
value,
634+
addrSpace,
635+
attrs); }]>,
599636
];
600637

601638
let extraClassDeclaration = [{

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -912,9 +912,14 @@ static LogicalResult verify(AddressOfOp op) {
912912
/// the name of the attribute in ODS.
913913
static StringRef getLinkageAttrName() { return "linkage"; }
914914

915+
/// Returns the name used for the TLS attribute. This *must* correspond to
916+
/// the name of the attribute in ODS.
917+
static StringRef getThreadLocalModeAttrName() { return "tls_mode"; }
918+
919+
915920
void GlobalOp::build(Builder *builder, OperationState &result, LLVMType type,
916-
bool isConstant, Linkage linkage, StringRef name,
917-
Attribute value, unsigned addrSpace,
921+
bool isConstant, Linkage linkage, ThreadLocalMode tlsMode,
922+
StringRef name, Attribute value, unsigned addrSpace,
918923
ArrayRef<NamedAttribute> attrs) {
919924
result.addAttribute(SymbolTable::getSymbolAttrName(),
920925
builder->getStringAttr(name));
@@ -925,6 +930,8 @@ void GlobalOp::build(Builder *builder, OperationState &result, LLVMType type,
925930
result.addAttribute("value", value);
926931
result.addAttribute(getLinkageAttrName(), builder->getI64IntegerAttr(
927932
static_cast<int64_t>(linkage)));
933+
result.addAttribute(getThreadLocalModeAttrName(), builder->getI64IntegerAttr(
934+
static_cast<int64_t>(tlsMode)));
928935
if (addrSpace != 0)
929936
result.addAttribute("addr_space", builder->getI32IntegerAttr(addrSpace));
930937
result.attributes.append(attrs.begin(), attrs.end());
@@ -933,6 +940,9 @@ void GlobalOp::build(Builder *builder, OperationState &result, LLVMType type,
933940

934941
static void printGlobalOp(OpAsmPrinter &p, GlobalOp op) {
935942
p << op.getOperationName() << ' ' << stringifyLinkage(op.linkage()) << ' ';
943+
auto tlsMode = op.tls_mode();
944+
if (tlsMode != ThreadLocalMode::NotThreadLocal)
945+
p << stringifyThreadLocalMode(tlsMode) << ' ';
936946
if (op.constant())
937947
p << "constant ";
938948
p.printSymbolName(op.sym_name());
@@ -942,7 +952,7 @@ static void printGlobalOp(OpAsmPrinter &p, GlobalOp op) {
942952
p << ')';
943953
p.printOptionalAttrDict(op.getAttrs(),
944954
{SymbolTable::getSymbolAttrName(), "type", "constant",
945-
"value", getLinkageAttrName()});
955+
"value", getLinkageAttrName(), getThreadLocalModeAttrName()});
946956

947957
// Print the trailing type unless it's a string global.
948958
if (op.getValueOrNull().dyn_cast_or_null<StringAttr>())
@@ -976,14 +986,15 @@ template <typename Ty> struct EnumTraits {};
976986
}
977987

978988
REGISTER_ENUM_TYPE(Linkage);
989+
REGISTER_ENUM_TYPE(ThreadLocalMode);
979990
} // end namespace
980991

981992
template <typename EnumTy>
982993
static ParseResult parseOptionalLLVMKeyword(OpAsmParser &parser,
983994
OperationState &result,
984995
StringRef name) {
985996
SmallVector<StringRef, 10> names;
986-
for (unsigned i = 0, e = getMaxEnumValForLinkage(); i <= e; ++i)
997+
for (unsigned i = 0, e = EnumTraits<EnumTy>::getMaxEnumVal(); i <= e; ++i)
987998
names.push_back(EnumTraits<EnumTy>::stringify(static_cast<EnumTy>(i)));
988999

9891000
int index = parseOptionalKeywordAlternative(parser, names);
@@ -993,7 +1004,7 @@ static ParseResult parseOptionalLLVMKeyword(OpAsmParser &parser,
9931004
return success();
9941005
}
9951006

996-
// operation ::= `llvm.mlir.global` linkage `constant`? `@` identifier
1007+
// operation ::= `llvm.mlir.global` linkage tls-mode? `constant`? `@` identifier
9971008
// `(` attribute? `)` attribute-list? (`:` type)? region?
9981009
//
9991010
// The type can be omitted for string attributes, in which case it will be
@@ -1003,6 +1014,8 @@ static ParseResult parseGlobalOp(OpAsmParser &parser, OperationState &result) {
10031014
getLinkageAttrName())))
10041015
return parser.emitError(parser.getCurrentLocation(), "expected linkage");
10051016

1017+
parseOptionalLLVMKeyword<ThreadLocalMode>(parser, result, getThreadLocalModeAttrName());
1018+
10061019
if (succeeded(parser.parseOptionalKeyword("constant")))
10071020
result.addAttribute("constant", parser.getBuilder().getUnitAttr());
10081021

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "mlir/Support/LLVM.h"
2222

2323
#include "llvm/ADT/SetVector.h"
24+
#include "llvm/IR/Attributes.h"
25+
#include "llvm/IR/Instructions.h"
2426
#include "llvm/IR/BasicBlock.h"
2527
#include "llvm/IR/Constants.h"
2628
#include "llvm/IR/DerivedTypes.h"
@@ -449,14 +451,15 @@ void ModuleTranslation::convertGlobals() {
449451
}
450452

451453
auto linkage = convertLinkageToLLVM(op.linkage());
454+
auto tlsMode = convertThreadLocalModeToLLVM(op.tls_mode());
452455
bool anyExternalLinkage =
453456
(linkage == llvm::GlobalVariable::ExternalLinkage ||
454457
linkage == llvm::GlobalVariable::ExternalWeakLinkage);
455458
auto addrSpace = op.addr_space().getLimitedValue();
456459
auto *var = new llvm::GlobalVariable(
457460
*llvmModule, type, op.constant(), linkage,
458461
anyExternalLinkage ? nullptr : cst, op.sym_name(),
459-
/*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal, addrSpace);
462+
/*InsertBefore=*/nullptr, tlsMode, addrSpace);
460463

461464
globalsMapping.try_emplace(op, var);
462465
}

0 commit comments

Comments
 (0)