Skip to content

Commit b177422

Browse files
authored
[flang] Emit fir.global in the global address space (llvm#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.
1 parent 3b4e793 commit b177422

File tree

6 files changed

+101
-9
lines changed

6 files changed

+101
-9
lines changed

flang/include/flang/Optimizer/Builder/FIRBuilder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,10 @@ uint64_t getAllocaAddressSpace(const mlir::DataLayout *dataLayout);
900900
llvm::SmallVector<mlir::Value> deduceOptimalExtents(mlir::ValueRange extents1,
901901
mlir::ValueRange extents2);
902902

903+
uint64_t getGlobalAddressSpace(mlir::DataLayout *dataLayout);
904+
905+
uint64_t getProgramAddressSpace(mlir::DataLayout *dataLayout);
906+
903907
/// Given array extents generate code that sets them all to zeroes,
904908
/// if the array is empty, e.g.:
905909
/// %false = arith.constant false

flang/include/flang/Optimizer/CodeGen/FIROpPatterns.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ class ConvertFIRToLLVMPattern : public mlir::ConvertToLLVMPattern {
189189
unsigned
190190
getProgramAddressSpace(mlir::ConversionPatternRewriter &rewriter) const;
191191

192+
unsigned
193+
getGlobalAddressSpace(mlir::ConversionPatternRewriter &rewriter) const;
194+
192195
const fir::FIRToLLVMPassOptions &options;
193196

194197
using ConvertToLLVMPattern::matchAndRewrite;

flang/lib/Optimizer/Builder/FIRBuilder.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,20 @@ fir::factory::deduceOptimalExtents(mlir::ValueRange extents1,
18671867
return extents;
18681868
}
18691869

1870+
uint64_t fir::factory::getGlobalAddressSpace(mlir::DataLayout *dataLayout) {
1871+
if (dataLayout)
1872+
if (mlir::Attribute addrSpace = dataLayout->getGlobalMemorySpace())
1873+
return mlir::cast<mlir::IntegerAttr>(addrSpace).getUInt();
1874+
return 0;
1875+
}
1876+
1877+
uint64_t fir::factory::getProgramAddressSpace(mlir::DataLayout *dataLayout) {
1878+
if (dataLayout)
1879+
if (mlir::Attribute addrSpace = dataLayout->getProgramMemorySpace())
1880+
return mlir::cast<mlir::IntegerAttr>(addrSpace).getUInt();
1881+
return 0;
1882+
}
1883+
18701884
llvm::SmallVector<mlir::Value> fir::factory::updateRuntimeExtentsForEmptyArrays(
18711885
fir::FirOpBuilder &builder, mlir::Location loc, mlir::ValueRange extents) {
18721886
if (extents.size() <= 1)

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,54 @@ addLLVMOpBundleAttrs(mlir::ConversionPatternRewriter &rewriter,
137137
}
138138

139139
namespace {
140+
141+
mlir::Value replaceWithAddrOfOrASCast(mlir::ConversionPatternRewriter &rewriter,
142+
mlir::Location loc,
143+
std::uint64_t globalAS,
144+
std::uint64_t programAS,
145+
llvm::StringRef symName, mlir::Type type,
146+
mlir::Operation *replaceOp = nullptr) {
147+
if (mlir::isa<mlir::LLVM::LLVMPointerType>(type)) {
148+
if (globalAS != programAS) {
149+
auto llvmAddrOp = rewriter.create<mlir::LLVM::AddressOfOp>(
150+
loc, getLlvmPtrType(rewriter.getContext(), globalAS), symName);
151+
if (replaceOp)
152+
return rewriter.replaceOpWithNewOp<mlir::LLVM::AddrSpaceCastOp>(
153+
replaceOp, ::getLlvmPtrType(rewriter.getContext(), programAS),
154+
llvmAddrOp);
155+
return rewriter.create<mlir::LLVM::AddrSpaceCastOp>(
156+
loc, getLlvmPtrType(rewriter.getContext(), programAS), llvmAddrOp);
157+
}
158+
159+
if (replaceOp)
160+
return rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
161+
replaceOp, getLlvmPtrType(rewriter.getContext(), globalAS), symName);
162+
return rewriter.create<mlir::LLVM::AddressOfOp>(
163+
loc, getLlvmPtrType(rewriter.getContext(), globalAS), symName);
164+
}
165+
166+
if (replaceOp)
167+
return rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(replaceOp, type,
168+
symName);
169+
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, type, symName);
170+
}
171+
140172
/// Lower `fir.address_of` operation to `llvm.address_of` operation.
141173
struct AddrOfOpConversion : public fir::FIROpConversion<fir::AddrOfOp> {
142174
using FIROpConversion::FIROpConversion;
143175

144176
llvm::LogicalResult
145177
matchAndRewrite(fir::AddrOfOp addr, OpAdaptor adaptor,
146178
mlir::ConversionPatternRewriter &rewriter) const override {
147-
auto ty = convertType(addr.getType());
148-
rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
149-
addr, ty, addr.getSymbol().getRootReference().getValue());
179+
auto global = addr->getParentOfType<mlir::ModuleOp>()
180+
.lookupSymbol<mlir::LLVM::GlobalOp>(addr.getSymbol());
181+
replaceWithAddrOfOrASCast(
182+
rewriter, addr->getLoc(),
183+
global ? global.getAddrSpace() : getGlobalAddressSpace(rewriter),
184+
getProgramAddressSpace(rewriter),
185+
global ? global.getSymName()
186+
: addr.getSymbol().getRootReference().getValue(),
187+
convertType(addr.getType()), addr);
150188
return mlir::success();
151189
}
152190
};
@@ -1306,13 +1344,18 @@ getTypeDescriptor(ModOpTy mod, mlir::ConversionPatternRewriter &rewriter,
13061344
? fir::NameUniquer::getTypeDescriptorAssemblyName(recType.getName())
13071345
: fir::NameUniquer::getTypeDescriptorName(recType.getName());
13081346
mlir::Type llvmPtrTy = ::getLlvmPtrType(mod.getContext());
1347+
mlir::DataLayout dataLayout(mod);
13091348
if (auto global = mod.template lookupSymbol<fir::GlobalOp>(name))
1310-
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
1311-
global.getSymName());
1349+
return replaceWithAddrOfOrASCast(
1350+
rewriter, loc, fir::factory::getGlobalAddressSpace(&dataLayout),
1351+
fir::factory::getProgramAddressSpace(&dataLayout), global.getSymName(),
1352+
llvmPtrTy);
13121353
// The global may have already been translated to LLVM.
13131354
if (auto global = mod.template lookupSymbol<mlir::LLVM::GlobalOp>(name))
1314-
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
1315-
global.getSymName());
1355+
return replaceWithAddrOfOrASCast(
1356+
rewriter, loc, global.getAddrSpace(),
1357+
fir::factory::getProgramAddressSpace(&dataLayout), global.getSymName(),
1358+
llvmPtrTy);
13161359
// Type info derived types do not have type descriptors since they are the
13171360
// types defining type descriptors.
13181361
if (options.ignoreMissingTypeDescriptors ||
@@ -3130,8 +3173,8 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
31303173
mlir::SymbolRefAttr comdat;
31313174
llvm::ArrayRef<mlir::NamedAttribute> attrs;
31323175
auto g = rewriter.create<mlir::LLVM::GlobalOp>(
3133-
loc, tyAttr, isConst, linkage, global.getSymName(), initAttr, 0, 0,
3134-
false, false, comdat, attrs, dbgExprs);
3176+
loc, tyAttr, isConst, linkage, global.getSymName(), initAttr, 0,
3177+
getGlobalAddressSpace(rewriter), false, false, comdat, attrs, dbgExprs);
31353178

31363179
if (global.getAlignment() && *global.getAlignment() > 0)
31373180
g.setAlignment(*global.getAlignment());

flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "flang/Optimizer/CodeGen/FIROpPatterns.h"
14+
#include "flang/Optimizer/Builder/FIRBuilder.h"
1415
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
1516
#include "llvm/Support/Debug.h"
1617

@@ -365,4 +366,13 @@ unsigned ConvertFIRToLLVMPattern::getProgramAddressSpace(
365366
return defaultAddressSpace;
366367
}
367368

369+
unsigned ConvertFIRToLLVMPattern::getGlobalAddressSpace(
370+
mlir::ConversionPatternRewriter &rewriter) const {
371+
mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp();
372+
assert(parentOp != nullptr &&
373+
"expected insertion block to have parent operation");
374+
auto dataLayout = mlir::DataLayout::closest(parentOp);
375+
return fir::factory::getGlobalAddressSpace(&dataLayout);
376+
}
377+
368378
} // namespace fir
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
!REQUIRES: amdgpu-registered-target
2+
3+
!RUN: %flang_fc1 -emit-llvm -triple amdgcn-amd-amdhsa -target-cpu gfx908 %s -o - | FileCheck %s
4+
5+
subroutine maintest
6+
implicit none
7+
8+
type r1_t
9+
end type r1_t
10+
11+
type(r1_t), pointer :: A
12+
end subroutine
13+
14+
! CHECK: @[[TYPE_DESC:.*XdtXr1_t]] = linkonce_odr addrspace(1) constant %_QM__fortran_type_infoTderivedtype
15+
16+
! CHECK: define void @maintest_() {{.*}} {
17+
! CHECK: store { {{.*}} } { {{.*}}, ptr addrspacecast (ptr addrspace(1) @[[TYPE_DESC]] to ptr), {{.*}} }, {{.*}}
18+
! CHECK: }

0 commit comments

Comments
 (0)