From ac76fa480fce3302743c75798240298ea4dac374 Mon Sep 17 00:00:00 2001 From: Slava Zakharin Date: Wed, 5 Oct 2022 11:17:09 -0700 Subject: [PATCH] [flang] Represent TARGET for globals with 'target' attribute. TARGET dummy arguments have fir.target attribute attached to them, but globals do not have any sign of TARGET. This patch adds target attribute for globals, which can be queried via ::fir::GlobalOp::getTarget(). Differential Revision: https://reviews.llvm.org/D135313 --- .../flang/Optimizer/Builder/FIRBuilder.h | 12 +++++---- .../include/flang/Optimizer/Dialect/FIROps.td | 9 +++++-- flang/lib/Lower/ConvertVariable.cpp | 5 ++-- flang/lib/Lower/IO.cpp | 6 ++--- flang/lib/Optimizer/Builder/FIRBuilder.cpp | 20 ++++++++------ flang/lib/Optimizer/Dialect/FIROps.cpp | 27 +++++++++++++------ flang/test/Lower/derived-type-descriptor.f90 | 16 +++++------ .../test/Lower/module-single-point-of-def.f90 | 4 +-- flang/test/Lower/target_definition.f90 | 11 ++++++++ flang/test/Lower/target_use.f90 | 9 +++++++ 10 files changed, 81 insertions(+), 38 deletions(-) create mode 100644 flang/test/Lower/target_definition.f90 create mode 100644 flang/test/Lower/target_use.f90 diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h index 653b6ebe6f99..fe1350d2dbcf 100644 --- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h +++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h @@ -176,10 +176,11 @@ public: fir::GlobalOp createGlobal(mlir::Location loc, mlir::Type type, llvm::StringRef name, mlir::StringAttr linkage = {}, - mlir::Attribute value = {}, bool isConst = false); + mlir::Attribute value = {}, bool isConst = false, + bool isTarget = false); fir::GlobalOp createGlobal(mlir::Location loc, mlir::Type type, - llvm::StringRef name, bool isConst, + llvm::StringRef name, bool isConst, bool isTarget, std::function bodyBuilder, mlir::StringAttr linkage = {}); @@ -188,7 +189,8 @@ public: llvm::StringRef name, mlir::StringAttr linkage = {}, mlir::Attribute value = {}) { - return createGlobal(loc, type, name, linkage, value, /*isConst=*/true); + return createGlobal(loc, type, name, linkage, value, /*isConst=*/true, + /*isTarget=*/false); } fir::GlobalOp @@ -196,8 +198,8 @@ public: llvm::StringRef name, std::function bodyBuilder, mlir::StringAttr linkage = {}) { - return createGlobal(loc, type, name, /*isConst=*/true, bodyBuilder, - linkage); + return createGlobal(loc, type, name, /*isConst=*/true, /*isTarget=*/false, + bodyBuilder, linkage); } /// Convert a StringRef string into a fir::StringLitOp. diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index 5b61011998c6..60d34fdf2072 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -2654,6 +2654,7 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> { TypeAttr:$type, OptionalAttr:$initVal, OptionalAttr:$constant, + OptionalAttr:$target, OptionalAttr:$linkName ); @@ -2666,19 +2667,20 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> { OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type, CArg<"llvm::ArrayRef", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "bool":$isConstant, - "mlir::Type":$type, + "bool":$isTarget, "mlir::Type":$type, CArg<"llvm::ArrayRef", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type, CArg<"mlir::StringAttr", "{}">:$linkage, CArg<"llvm::ArrayRef", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "bool":$isConstant, + "bool":$isTarget, "mlir::Type":$type, CArg<"mlir::StringAttr", "{}">:$linkage, CArg<"llvm::ArrayRef", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type, "mlir::Attribute":$initVal, CArg<"mlir::StringAttr", "{}">:$linkage, CArg<"llvm::ArrayRef", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "bool":$isConstant, - "mlir::Type":$type, "mlir::Attribute":$initVal, + "bool":$isTarget, "mlir::Type":$type, "mlir::Attribute":$initVal, CArg<"mlir::StringAttr", "{}">:$linkage, CArg<"llvm::ArrayRef", "{}">:$attrs)>, ]; @@ -2691,6 +2693,9 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> { static constexpr llvm::StringRef getLinkageAttrNameStr() { return "linkName"; } + static constexpr llvm::StringRef getTargetAttrNameStr() { + return "target"; + } /// The semantic type of the global mlir::Type resultType(); diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 9a1211a9c30e..3114eeae4c09 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -134,7 +134,8 @@ static fir::GlobalOp declareGlobal(Fortran::lower::AbstractConverter &converter, mlir::emitError(loc, "processing global declaration: symbol '") << toStringRef(sym.name()) << "' has unexpected details\n"; return builder.createGlobal(loc, converter.genType(var), globalName, linkage, - mlir::Attribute{}, isConstant(ultimate)); + mlir::Attribute{}, isConstant(ultimate), + var.isTarget()); } /// Temporary helper to catch todos in initial data target lowering. @@ -442,7 +443,7 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter, } if (!global) global = builder.createGlobal(loc, symTy, globalName, linkage, - mlir::Attribute{}, isConst); + mlir::Attribute{}, isConst, var.isTarget()); if (Fortran::semantics::IsAllocatableOrPointer(sym)) { const auto *details = sym.detailsIf(); diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp index e207b50f7957..4b08b06e013d 100644 --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -401,9 +401,9 @@ getNamelistGroup(Fortran::lower::AbstractConverter &converter, if (groupIsLocal) { groupFunc(builder); } else { - fir::GlobalOp group = - builder.createGlobal(loc, groupTy, groupMangleName, - /*isConst=*/true, groupFunc, linkOnce); + fir::GlobalOp group = builder.createGlobal( + loc, groupTy, groupMangleName, + /*isConst=*/true, /*isTarget=*/false, groupFunc, linkOnce); groupAddr = builder.create(loc, group.resultType(), group.getSymbol()); } diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index 446e3b78a443..de0d6b295d85 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -234,30 +234,34 @@ fir::FirOpBuilder::createTemporary(mlir::Location loc, mlir::Type type, /// Create a global variable in the (read-only) data section. A global variable /// must have a unique name to identify and reference it. -fir::GlobalOp -fir::FirOpBuilder::createGlobal(mlir::Location loc, mlir::Type type, - llvm::StringRef name, mlir::StringAttr linkage, - mlir::Attribute value, bool isConst) { +fir::GlobalOp fir::FirOpBuilder::createGlobal(mlir::Location loc, + mlir::Type type, + llvm::StringRef name, + mlir::StringAttr linkage, + mlir::Attribute value, + bool isConst, bool isTarget) { auto module = getModule(); auto insertPt = saveInsertionPoint(); if (auto glob = module.lookupSymbol(name)) return glob; setInsertionPoint(module.getBody(), module.getBody()->end()); - auto glob = create(loc, name, isConst, type, value, linkage); + auto glob = + create(loc, name, isConst, isTarget, type, value, linkage); restoreInsertionPoint(insertPt); return glob; } fir::GlobalOp fir::FirOpBuilder::createGlobal( mlir::Location loc, mlir::Type type, llvm::StringRef name, bool isConst, - std::function bodyBuilder, mlir::StringAttr linkage) { + bool isTarget, std::function bodyBuilder, + mlir::StringAttr linkage) { auto module = getModule(); auto insertPt = saveInsertionPoint(); if (auto glob = module.lookupSymbol(name)) return glob; setInsertionPoint(module.getBody(), module.getBody()->end()); - auto glob = create(loc, name, isConst, type, mlir::Attribute{}, - linkage); + auto glob = create(loc, name, isConst, isTarget, type, + mlir::Attribute{}, linkage); auto ®ion = glob.getRegion(); region.push_back(new mlir::Block); auto &block = glob.getRegion().back(); diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index 577fe4dda5f3..9666677bcd86 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -1251,6 +1251,9 @@ mlir::ParseResult fir::GlobalOp::parse(mlir::OpAsmParser &parser, result.addAttribute("constant", builder.getUnitAttr()); } + if (succeeded(parser.parseOptionalKeyword("target"))) + result.addAttribute(getTargetAttrNameStr(), builder.getUnitAttr()); + mlir::Type globalType; if (parser.parseColonType(globalType)) return mlir::failure(); @@ -1279,6 +1282,8 @@ void fir::GlobalOp::print(mlir::OpAsmPrinter &p) { p << '(' << val << ')'; if (getOperation()->getAttr(fir::GlobalOp::getConstantAttrNameStr())) p << " constant"; + if (getOperation()->getAttr(getTargetAttrName())) + p << " target"; p << " : "; p.printType(getType()); if (hasInitializationBody()) { @@ -1295,7 +1300,7 @@ void fir::GlobalOp::appendInitialValue(mlir::Operation *op) { void fir::GlobalOp::build(mlir::OpBuilder &builder, mlir::OperationState &result, llvm::StringRef name, - bool isConstant, mlir::Type type, + bool isConstant, bool isTarget, mlir::Type type, mlir::Attribute initialVal, mlir::StringAttr linkage, llvm::ArrayRef attrs) { result.addRegion(); @@ -1307,6 +1312,8 @@ void fir::GlobalOp::build(mlir::OpBuilder &builder, if (isConstant) result.addAttribute(getConstantAttrName(result.name), builder.getUnitAttr()); + if (isTarget) + result.addAttribute(getTargetAttrName(result.name), builder.getUnitAttr()); if (initialVal) result.addAttribute(getInitValAttrName(result.name), initialVal); if (linkage) @@ -1319,36 +1326,40 @@ void fir::GlobalOp::build(mlir::OpBuilder &builder, mlir::Type type, mlir::Attribute initialVal, mlir::StringAttr linkage, llvm::ArrayRef attrs) { - build(builder, result, name, /*isConstant=*/false, type, {}, linkage, attrs); + build(builder, result, name, /*isConstant=*/false, /*isTarget=*/false, type, + {}, linkage, attrs); } void fir::GlobalOp::build(mlir::OpBuilder &builder, mlir::OperationState &result, llvm::StringRef name, - bool isConstant, mlir::Type type, + bool isConstant, bool isTarget, mlir::Type type, mlir::StringAttr linkage, llvm::ArrayRef attrs) { - build(builder, result, name, isConstant, type, {}, linkage, attrs); + build(builder, result, name, isConstant, isTarget, type, {}, linkage, attrs); } void fir::GlobalOp::build(mlir::OpBuilder &builder, mlir::OperationState &result, llvm::StringRef name, mlir::Type type, mlir::StringAttr linkage, llvm::ArrayRef attrs) { - build(builder, result, name, /*isConstant=*/false, type, {}, linkage, attrs); + build(builder, result, name, /*isConstant=*/false, /*isTarget=*/false, type, + {}, linkage, attrs); } void fir::GlobalOp::build(mlir::OpBuilder &builder, mlir::OperationState &result, llvm::StringRef name, - bool isConstant, mlir::Type type, + bool isConstant, bool isTarget, mlir::Type type, llvm::ArrayRef attrs) { - build(builder, result, name, isConstant, type, mlir::StringAttr{}, attrs); + build(builder, result, name, isConstant, isTarget, type, mlir::StringAttr{}, + attrs); } void fir::GlobalOp::build(mlir::OpBuilder &builder, mlir::OperationState &result, llvm::StringRef name, mlir::Type type, llvm::ArrayRef attrs) { - build(builder, result, name, /*isConstant=*/false, type, attrs); + build(builder, result, name, /*isConstant=*/false, /*isTarget=*/false, type, + attrs); } mlir::ParseResult fir::GlobalOp::verifyValidLinkage(llvm::StringRef linkage) { diff --git a/flang/test/Lower/derived-type-descriptor.f90 b/flang/test/Lower/derived-type-descriptor.f90 index 35443d008a4c..22f7bf188440 100644 --- a/flang/test/Lower/derived-type-descriptor.f90 +++ b/flang/test/Lower/derived-type-descriptor.f90 @@ -11,22 +11,22 @@ subroutine foo() type(sometype), allocatable, save :: x(:) end subroutine -! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.n.num constant : !fir.char<1,3> { +! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.n.num constant target : !fir.char<1,3> { ! CHECK: %[[res:.*]] = fir.string_lit "num"(3) : !fir.char<1,3> ! CHECK: fir.has_value %[[res]] : !fir.char<1,3> -! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.di.sometype.num constant : i32 -! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.n.values constant : !fir.char<1,6> { +! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.di.sometype.num constant target : i32 +! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.n.values constant target : !fir.char<1,6> { ! CHECK: %[[res:.*]] = fir.string_lit "values"(6) : !fir.char<1,6> ! CHECK: fir.has_value %[[res]] : !fir.char<1,6> -! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.n.sometype constant : !fir.char<1,8> { +! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.n.sometype constant target : !fir.char<1,8> { ! CHECK: %[[res:.*]] = fir.string_lit "sometype"(8) : !fir.char<1,8> ! CHECK: fir.has_value %[[res]] : !fir.char<1,8> -! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.di.sometype.values constant : !fir.type<_QFfooT.dp.sometype.values{values:!fir.box>>}> { +! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.di.sometype.values constant target : !fir.type<_QFfooT.dp.sometype.values{values:!fir.box>>}> { ! CHECK: fir.address_of(@_QFfooEinit_values) ! CHECK: } -! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.dt.sometype constant {{.*}} { +! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.dt.sometype constant target {{.*}} { !CHECK: fir.address_of(@_QFfooE.n.sometype) !CHECK: fir.address_of(@_QFfooE.c.sometype) ! CHECK:} @@ -46,10 +46,10 @@ subroutine char_comp_init() type(t) :: a end subroutine -! CHECK-LABEL: fir.global linkonce_odr @_QFchar_comp_initE.di.t.name constant : !fir.char<1,8> { +! CHECK-LABEL: fir.global linkonce_odr @_QFchar_comp_initE.di.t.name constant target : !fir.char<1,8> { ! CHECK: %[[res:.*]] = fir.string_lit "Empty "(8) : !fir.char<1,8> ! CHECK: fir.has_value %[[res]] : !fir.char<1,8> -! CHECK-LABEL: fir.global linkonce_odr @_QFchar_comp_initE.c.t constant : {{.*}} { +! CHECK-LABEL: fir.global linkonce_odr @_QFchar_comp_initE.c.t constant target : {{.*}} { ! CHECK: fir.address_of(@_QFchar_comp_initE.di.t.name) : !fir.ref> ! CHECK: } diff --git a/flang/test/Lower/module-single-point-of-def.f90 b/flang/test/Lower/module-single-point-of-def.f90 index 06dba7438e9b..dd899078db9d 100644 --- a/flang/test/Lower/module-single-point-of-def.f90 +++ b/flang/test/Lower/module-single-point-of-def.f90 @@ -23,7 +23,7 @@ module define_a end type end module -! CHECK-A-DEF: fir.global linkonce_odr @_QMdefine_aE.dt.atype constant : !fir.type<{{.*}}> { +! CHECK-A-DEF: fir.global linkonce_odr @_QMdefine_aE.dt.atype constant target : !fir.type<{{.*}}> { ! CHECK-A-DEF: fir.has_value ! CHECK-A-DEF: } @@ -45,7 +45,7 @@ end module ! CHECK-B-DEF: fir.has_value %{{.*}} : i32 ! CHECK-B-DEF: } -! CHECK-B-DEF: fir.global linkonce_odr @_QMdefine_bE.dt.btype constant : !fir.type<{{.*}}> { +! CHECK-B-DEF: fir.global linkonce_odr @_QMdefine_bE.dt.btype constant target : !fir.type<{{.*}}> { ! CHECK-B-DEF: fir.has_value ! CHECK-B-DEF: } diff --git a/flang/test/Lower/target_definition.f90 b/flang/test/Lower/target_definition.f90 new file mode 100644 index 000000000000..2bde8b31c4a1 --- /dev/null +++ b/flang/test/Lower/target_definition.f90 @@ -0,0 +1,11 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! Test TARGET attributes on a definition of a global symbol. +! CHECK: fir.global @_QMtarget_modEx target : f32 { +! CHECK: %[[init:.*]] = fir.undefined f32 +! CHECK: fir.has_value %[[init]] : f32 +! CHECK: } + +module target_mod + real, target :: x +end module target_mod diff --git a/flang/test/Lower/target_use.f90 b/flang/test/Lower/target_use.f90 new file mode 100644 index 000000000000..9602cc296a1e --- /dev/null +++ b/flang/test/Lower/target_use.f90 @@ -0,0 +1,9 @@ +! RUN: bbc -emit-fir %S/target_definition.f90 +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! Test TARGET attributes on a declaration of a global symbol. +! CHECK: fir.global @_QMtarget_modEx target : f32 +real function test() + use target_mod + test = x +end function test