forked from OSchip/llvm-project
[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
This commit is contained in:
parent
36de2d639e
commit
f0ba32d666
|
@ -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)>
|
||||
];
|
||||
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
|
@ -28,13 +28,34 @@
|
|||
; CHECK-NEXT: }
|
||||
@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>]]
|
||||
|
||||
;
|
||||
|
|
|
@ -128,6 +128,13 @@ llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) : i64
|
|||
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.
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue