[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
This commit is contained in:
parent
f4e8f44811
commit
ac76fa480f
|
@ -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<void(FirOpBuilder &)> 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<void(FirOpBuilder &)> 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.
|
||||
|
|
|
@ -2654,6 +2654,7 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> {
|
|||
TypeAttr:$type,
|
||||
OptionalAttr<AnyAttr>:$initVal,
|
||||
OptionalAttr<UnitAttr>:$constant,
|
||||
OptionalAttr<UnitAttr>:$target,
|
||||
OptionalAttr<StrAttr>:$linkName
|
||||
);
|
||||
|
||||
|
@ -2666,19 +2667,20 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> {
|
|||
OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type,
|
||||
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attrs)>,
|
||||
OpBuilder<(ins "llvm::StringRef":$name, "bool":$isConstant,
|
||||
"mlir::Type":$type,
|
||||
"bool":$isTarget, "mlir::Type":$type,
|
||||
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attrs)>,
|
||||
OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type,
|
||||
CArg<"mlir::StringAttr", "{}">:$linkage,
|
||||
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attrs)>,
|
||||
OpBuilder<(ins "llvm::StringRef":$name, "bool":$isConstant,
|
||||
"bool":$isTarget,
|
||||
"mlir::Type":$type, CArg<"mlir::StringAttr", "{}">:$linkage,
|
||||
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attrs)>,
|
||||
OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type,
|
||||
"mlir::Attribute":$initVal, CArg<"mlir::StringAttr", "{}">:$linkage,
|
||||
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$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<mlir::NamedAttribute>", "{}">:$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();
|
||||
|
|
|
@ -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<Fortran::semantics::ObjectEntityDetails>();
|
||||
|
|
|
@ -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<fir::AddrOfOp>(loc, group.resultType(),
|
||||
group.getSymbol());
|
||||
}
|
||||
|
|
|
@ -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<fir::GlobalOp>(name))
|
||||
return glob;
|
||||
setInsertionPoint(module.getBody(), module.getBody()->end());
|
||||
auto glob = create<fir::GlobalOp>(loc, name, isConst, type, value, linkage);
|
||||
auto glob =
|
||||
create<fir::GlobalOp>(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<void(FirOpBuilder &)> bodyBuilder, mlir::StringAttr linkage) {
|
||||
bool isTarget, std::function<void(FirOpBuilder &)> bodyBuilder,
|
||||
mlir::StringAttr linkage) {
|
||||
auto module = getModule();
|
||||
auto insertPt = saveInsertionPoint();
|
||||
if (auto glob = module.lookupSymbol<fir::GlobalOp>(name))
|
||||
return glob;
|
||||
setInsertionPoint(module.getBody(), module.getBody()->end());
|
||||
auto glob = create<fir::GlobalOp>(loc, name, isConst, type, mlir::Attribute{},
|
||||
linkage);
|
||||
auto glob = create<fir::GlobalOp>(loc, name, isConst, isTarget, type,
|
||||
mlir::Attribute{}, linkage);
|
||||
auto ®ion = glob.getRegion();
|
||||
region.push_back(new mlir::Block);
|
||||
auto &block = glob.getRegion().back();
|
||||
|
|
|
@ -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<mlir::NamedAttribute> 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<mlir::NamedAttribute> 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<mlir::NamedAttribute> 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<mlir::NamedAttribute> 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<mlir::NamedAttribute> 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<mlir::NamedAttribute> 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) {
|
||||
|
|
|
@ -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<!fir.ptr<!fir.array<?x?xf32>>>}> {
|
||||
! CHECK-LABEL: fir.global linkonce_odr @_QFfooE.di.sometype.values constant target : !fir.type<_QFfooT.dp.sometype.values{values:!fir.box<!fir.ptr<!fir.array<?x?xf32>>>}> {
|
||||
! 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<!fir.char<1,8>>
|
||||
! CHECK: }
|
||||
|
|
|
@ -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: }
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue