[flang] Emit fir.global in the global address space (#146653)
Instead of emitting globals in the program/default address space, emit them in the global address space. This also requires changes how address of code-gen is handled, we need to cast to the default address space to prevent code-gen issues.
This commit is contained in:
@@ -900,6 +900,10 @@ uint64_t getAllocaAddressSpace(const mlir::DataLayout *dataLayout);
|
|||||||
llvm::SmallVector<mlir::Value> deduceOptimalExtents(mlir::ValueRange extents1,
|
llvm::SmallVector<mlir::Value> deduceOptimalExtents(mlir::ValueRange extents1,
|
||||||
mlir::ValueRange extents2);
|
mlir::ValueRange extents2);
|
||||||
|
|
||||||
|
uint64_t getGlobalAddressSpace(mlir::DataLayout *dataLayout);
|
||||||
|
|
||||||
|
uint64_t getProgramAddressSpace(mlir::DataLayout *dataLayout);
|
||||||
|
|
||||||
/// Given array extents generate code that sets them all to zeroes,
|
/// Given array extents generate code that sets them all to zeroes,
|
||||||
/// if the array is empty, e.g.:
|
/// if the array is empty, e.g.:
|
||||||
/// %false = arith.constant false
|
/// %false = arith.constant false
|
||||||
|
|||||||
@@ -189,6 +189,9 @@ protected:
|
|||||||
unsigned
|
unsigned
|
||||||
getProgramAddressSpace(mlir::ConversionPatternRewriter &rewriter) const;
|
getProgramAddressSpace(mlir::ConversionPatternRewriter &rewriter) const;
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
getGlobalAddressSpace(mlir::ConversionPatternRewriter &rewriter) const;
|
||||||
|
|
||||||
const fir::FIRToLLVMPassOptions &options;
|
const fir::FIRToLLVMPassOptions &options;
|
||||||
|
|
||||||
using ConvertToLLVMPattern::matchAndRewrite;
|
using ConvertToLLVMPattern::matchAndRewrite;
|
||||||
|
|||||||
@@ -1867,6 +1867,20 @@ fir::factory::deduceOptimalExtents(mlir::ValueRange extents1,
|
|||||||
return extents;
|
return extents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t fir::factory::getGlobalAddressSpace(mlir::DataLayout *dataLayout) {
|
||||||
|
if (dataLayout)
|
||||||
|
if (mlir::Attribute addrSpace = dataLayout->getGlobalMemorySpace())
|
||||||
|
return mlir::cast<mlir::IntegerAttr>(addrSpace).getUInt();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fir::factory::getProgramAddressSpace(mlir::DataLayout *dataLayout) {
|
||||||
|
if (dataLayout)
|
||||||
|
if (mlir::Attribute addrSpace = dataLayout->getProgramMemorySpace())
|
||||||
|
return mlir::cast<mlir::IntegerAttr>(addrSpace).getUInt();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
llvm::SmallVector<mlir::Value> fir::factory::updateRuntimeExtentsForEmptyArrays(
|
llvm::SmallVector<mlir::Value> fir::factory::updateRuntimeExtentsForEmptyArrays(
|
||||||
fir::FirOpBuilder &builder, mlir::Location loc, mlir::ValueRange extents) {
|
fir::FirOpBuilder &builder, mlir::Location loc, mlir::ValueRange extents) {
|
||||||
if (extents.size() <= 1)
|
if (extents.size() <= 1)
|
||||||
|
|||||||
@@ -137,6 +137,38 @@ addLLVMOpBundleAttrs(mlir::ConversionPatternRewriter &rewriter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
mlir::Value replaceWithAddrOfOrASCast(mlir::ConversionPatternRewriter &rewriter,
|
||||||
|
mlir::Location loc,
|
||||||
|
std::uint64_t globalAS,
|
||||||
|
std::uint64_t programAS,
|
||||||
|
llvm::StringRef symName, mlir::Type type,
|
||||||
|
mlir::Operation *replaceOp = nullptr) {
|
||||||
|
if (mlir::isa<mlir::LLVM::LLVMPointerType>(type)) {
|
||||||
|
if (globalAS != programAS) {
|
||||||
|
auto llvmAddrOp = rewriter.create<mlir::LLVM::AddressOfOp>(
|
||||||
|
loc, getLlvmPtrType(rewriter.getContext(), globalAS), symName);
|
||||||
|
if (replaceOp)
|
||||||
|
return rewriter.replaceOpWithNewOp<mlir::LLVM::AddrSpaceCastOp>(
|
||||||
|
replaceOp, ::getLlvmPtrType(rewriter.getContext(), programAS),
|
||||||
|
llvmAddrOp);
|
||||||
|
return rewriter.create<mlir::LLVM::AddrSpaceCastOp>(
|
||||||
|
loc, getLlvmPtrType(rewriter.getContext(), programAS), llvmAddrOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceOp)
|
||||||
|
return rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
|
||||||
|
replaceOp, getLlvmPtrType(rewriter.getContext(), globalAS), symName);
|
||||||
|
return rewriter.create<mlir::LLVM::AddressOfOp>(
|
||||||
|
loc, getLlvmPtrType(rewriter.getContext(), globalAS), symName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceOp)
|
||||||
|
return rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(replaceOp, type,
|
||||||
|
symName);
|
||||||
|
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, type, symName);
|
||||||
|
}
|
||||||
|
|
||||||
/// Lower `fir.address_of` operation to `llvm.address_of` operation.
|
/// Lower `fir.address_of` operation to `llvm.address_of` operation.
|
||||||
struct AddrOfOpConversion : public fir::FIROpConversion<fir::AddrOfOp> {
|
struct AddrOfOpConversion : public fir::FIROpConversion<fir::AddrOfOp> {
|
||||||
using FIROpConversion::FIROpConversion;
|
using FIROpConversion::FIROpConversion;
|
||||||
@@ -144,9 +176,15 @@ struct AddrOfOpConversion : public fir::FIROpConversion<fir::AddrOfOp> {
|
|||||||
llvm::LogicalResult
|
llvm::LogicalResult
|
||||||
matchAndRewrite(fir::AddrOfOp addr, OpAdaptor adaptor,
|
matchAndRewrite(fir::AddrOfOp addr, OpAdaptor adaptor,
|
||||||
mlir::ConversionPatternRewriter &rewriter) const override {
|
mlir::ConversionPatternRewriter &rewriter) const override {
|
||||||
auto ty = convertType(addr.getType());
|
auto global = addr->getParentOfType<mlir::ModuleOp>()
|
||||||
rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
|
.lookupSymbol<mlir::LLVM::GlobalOp>(addr.getSymbol());
|
||||||
addr, ty, addr.getSymbol().getRootReference().getValue());
|
replaceWithAddrOfOrASCast(
|
||||||
|
rewriter, addr->getLoc(),
|
||||||
|
global ? global.getAddrSpace() : getGlobalAddressSpace(rewriter),
|
||||||
|
getProgramAddressSpace(rewriter),
|
||||||
|
global ? global.getSymName()
|
||||||
|
: addr.getSymbol().getRootReference().getValue(),
|
||||||
|
convertType(addr.getType()), addr);
|
||||||
return mlir::success();
|
return mlir::success();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1306,13 +1344,18 @@ getTypeDescriptor(ModOpTy mod, mlir::ConversionPatternRewriter &rewriter,
|
|||||||
? fir::NameUniquer::getTypeDescriptorAssemblyName(recType.getName())
|
? fir::NameUniquer::getTypeDescriptorAssemblyName(recType.getName())
|
||||||
: fir::NameUniquer::getTypeDescriptorName(recType.getName());
|
: fir::NameUniquer::getTypeDescriptorName(recType.getName());
|
||||||
mlir::Type llvmPtrTy = ::getLlvmPtrType(mod.getContext());
|
mlir::Type llvmPtrTy = ::getLlvmPtrType(mod.getContext());
|
||||||
|
mlir::DataLayout dataLayout(mod);
|
||||||
if (auto global = mod.template lookupSymbol<fir::GlobalOp>(name))
|
if (auto global = mod.template lookupSymbol<fir::GlobalOp>(name))
|
||||||
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
|
return replaceWithAddrOfOrASCast(
|
||||||
global.getSymName());
|
rewriter, loc, fir::factory::getGlobalAddressSpace(&dataLayout),
|
||||||
|
fir::factory::getProgramAddressSpace(&dataLayout), global.getSymName(),
|
||||||
|
llvmPtrTy);
|
||||||
// The global may have already been translated to LLVM.
|
// The global may have already been translated to LLVM.
|
||||||
if (auto global = mod.template lookupSymbol<mlir::LLVM::GlobalOp>(name))
|
if (auto global = mod.template lookupSymbol<mlir::LLVM::GlobalOp>(name))
|
||||||
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
|
return replaceWithAddrOfOrASCast(
|
||||||
global.getSymName());
|
rewriter, loc, global.getAddrSpace(),
|
||||||
|
fir::factory::getProgramAddressSpace(&dataLayout), global.getSymName(),
|
||||||
|
llvmPtrTy);
|
||||||
// Type info derived types do not have type descriptors since they are the
|
// Type info derived types do not have type descriptors since they are the
|
||||||
// types defining type descriptors.
|
// types defining type descriptors.
|
||||||
if (options.ignoreMissingTypeDescriptors ||
|
if (options.ignoreMissingTypeDescriptors ||
|
||||||
@@ -3130,8 +3173,8 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
|
|||||||
mlir::SymbolRefAttr comdat;
|
mlir::SymbolRefAttr comdat;
|
||||||
llvm::ArrayRef<mlir::NamedAttribute> attrs;
|
llvm::ArrayRef<mlir::NamedAttribute> attrs;
|
||||||
auto g = rewriter.create<mlir::LLVM::GlobalOp>(
|
auto g = rewriter.create<mlir::LLVM::GlobalOp>(
|
||||||
loc, tyAttr, isConst, linkage, global.getSymName(), initAttr, 0, 0,
|
loc, tyAttr, isConst, linkage, global.getSymName(), initAttr, 0,
|
||||||
false, false, comdat, attrs, dbgExprs);
|
getGlobalAddressSpace(rewriter), false, false, comdat, attrs, dbgExprs);
|
||||||
|
|
||||||
if (global.getAlignment() && *global.getAlignment() > 0)
|
if (global.getAlignment() && *global.getAlignment() > 0)
|
||||||
g.setAlignment(*global.getAlignment());
|
g.setAlignment(*global.getAlignment());
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "flang/Optimizer/CodeGen/FIROpPatterns.h"
|
#include "flang/Optimizer/CodeGen/FIROpPatterns.h"
|
||||||
|
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||||
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
|
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
|
||||||
@@ -365,4 +366,13 @@ unsigned ConvertFIRToLLVMPattern::getProgramAddressSpace(
|
|||||||
return defaultAddressSpace;
|
return defaultAddressSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned ConvertFIRToLLVMPattern::getGlobalAddressSpace(
|
||||||
|
mlir::ConversionPatternRewriter &rewriter) const {
|
||||||
|
mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp();
|
||||||
|
assert(parentOp != nullptr &&
|
||||||
|
"expected insertion block to have parent operation");
|
||||||
|
auto dataLayout = mlir::DataLayout::closest(parentOp);
|
||||||
|
return fir::factory::getGlobalAddressSpace(&dataLayout);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fir
|
} // namespace fir
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
!REQUIRES: amdgpu-registered-target
|
||||||
|
|
||||||
|
!RUN: %flang_fc1 -emit-llvm -triple amdgcn-amd-amdhsa -target-cpu gfx908 %s -o - | FileCheck %s
|
||||||
|
|
||||||
|
subroutine maintest
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
type r1_t
|
||||||
|
end type r1_t
|
||||||
|
|
||||||
|
type(r1_t), pointer :: A
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
! CHECK: @[[TYPE_DESC:.*XdtXr1_t]] = linkonce_odr addrspace(1) constant %_QM__fortran_type_infoTderivedtype
|
||||||
|
|
||||||
|
! CHECK: define void @maintest_() {{.*}} {
|
||||||
|
! CHECK: store { {{.*}} } { {{.*}}, ptr addrspacecast (ptr addrspace(1) @[[TYPE_DESC]] to ptr), {{.*}} }, {{.*}}
|
||||||
|
! CHECK: }
|
||||||
Reference in New Issue
Block a user