Index: flang/include/flang/Optimizer/Dialect/FIROpsSupport.h =================================================================== --- flang/include/flang/Optimizer/Dialect/FIROpsSupport.h +++ flang/include/flang/Optimizer/Dialect/FIROpsSupport.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef OPTIMIZER_DIALECT_FIROPSSUPPORT_H -#define OPTIMIZER_DIALECT_FIROPSSUPPORT_H +#ifndef FORTRAN_OPTIMIZER_DIALECT_FIROPSSUPPORT_H +#define FORTRAN_OPTIMIZER_DIALECT_FIROPSSUPPORT_H #include "flang/Optimizer/Dialect/FIROps.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" @@ -59,6 +59,21 @@ llvm::StringRef name, mlir::Type type, llvm::ArrayRef attrs = {}); +/// Attribute to mark Fortran entities with the CONTIGUOUS attribute. +constexpr llvm::StringRef getContiguousAttrName() { return "fir.contiguous"; } +/// Attribute to mark Fortran entities with the OPTIONAL attribute. +constexpr llvm::StringRef getOptionalAttrName() { return "fir.optional"; } + +/// Tell if \p value is: +/// - a function argument that has attribute \p attributeName +/// - or, the result of fir.alloca/fir.allocamem op that has attribute \p +/// attributeName +/// - or, the result of a fir.address_of of a fir.global that has attribute \p +/// attributeName +/// - or, a fir.box loaded from a fir.ref that matches one of the +/// previous cases. +bool valueHasFirAttribute(mlir::Value value, llvm::StringRef attributeName); + } // namespace fir -#endif // OPTIMIZER_DIALECT_FIROPSSUPPORT_H +#endif // FORTRAN_OPTIMIZER_DIALECT_FIROPSSUPPORT_H Index: flang/lib/Optimizer/Dialect/FIRDialect.cpp =================================================================== --- flang/lib/Optimizer/Dialect/FIRDialect.cpp +++ flang/lib/Optimizer/Dialect/FIRDialect.cpp @@ -22,7 +22,7 @@ addTypes(); addAttributes(); Index: flang/lib/Optimizer/Dialect/FIROps.cpp =================================================================== --- flang/lib/Optimizer/Dialect/FIROps.cpp +++ flang/lib/Optimizer/Dialect/FIROps.cpp @@ -5,6 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// #include "flang/Optimizer/Dialect/FIROps.h" #include "flang/Optimizer/Dialect/FIRAttr.h" @@ -1560,7 +1564,50 @@ if (auto g = module.lookupSymbol(name)) return g; mlir::OpBuilder modBuilder(module.getBodyRegion()); - return modBuilder.create(loc, name, type, attrs); + auto result = modBuilder.create(loc, name, type, attrs); + result.setVisibility(mlir::SymbolTable::Visibility::Private); + return result; +} + +bool fir::valueHasFirAttribute(mlir::Value value, + llvm::StringRef attributeName) { + // If this is a fir.box that was loaded, the fir attributes will be on the + // related fir.ref creation. + if (value.getType().isa()) + if (auto definingOp = value.getDefiningOp()) + if (auto loadOp = mlir::dyn_cast(definingOp)) + value = loadOp.memref(); + // If this is a function argument, look in the argument attributes. + if (auto blockArg = value.dyn_cast()) { + if (blockArg.getOwner() && blockArg.getOwner()->isEntryBlock()) + if (auto funcOp = + mlir::dyn_cast(blockArg.getOwner()->getParentOp())) + if (funcOp.getArgAttr(blockArg.getArgNumber(), attributeName)) + return true; + return false; + } + + if (auto definingOp = value.getDefiningOp()) { + // If this is an allocated value, look at the allocation attributes. + if (mlir::isa(definingOp) || + mlir::isa(definingOp)) + return definingOp->hasAttr(attributeName); + // If this is an imported global, look at AddOfOp and GlobalOp attributes. + // Both operations are looked at because use/host associated variable (the + // AddrOfOp) can have ASYNCHRONOUS/VOLATILE attributes even if the ultimate + // entity (the globalOp) does not have them. + if (auto addressOfOp = mlir::dyn_cast(definingOp)) { + if (addressOfOp->hasAttr(attributeName)) + return true; + if (auto module = definingOp->getParentOfType()) + if (auto globlaOp = + module.lookupSymbol(addressOfOp.symbol())) + return globlaOp->hasAttr(attributeName); + } + } + // TODO: Construct associated entities attributes. Decide where the fir + // attributes must be placed/looked for in this case. + return false; } // Tablegen operators