[flang] optionally add lifetime markers to alloca created in stack-arrays (#140901)

Flang at Ofast usually produces executables that consume more stack that
other Fortran compilers.
This is in part because the alloca created from temporary heap
allocation by the StackArray pass are created at the function scope
level without lifetimes, and LLVM does not/is not able to merge alloca
that do not have overlapping lifetimes.

This patch adds an option to generate LLVM lifetime in the StackArray
pass at the previous heap allocation/free using the LLVM dialect
operation for it.
This commit is contained in:
jeanPerier
2025-05-22 09:26:14 +02:00
committed by GitHub
parent 72a8893689
commit 1f5b6ae89f
7 changed files with 234 additions and 25 deletions

View File

@@ -1868,7 +1868,8 @@ void fir::factory::setInternalLinkage(mlir::func::FuncOp func) {
func->setAttr("llvm.linkage", linkage);
}
uint64_t fir::factory::getAllocaAddressSpace(mlir::DataLayout *dataLayout) {
uint64_t
fir::factory::getAllocaAddressSpace(const mlir::DataLayout *dataLayout) {
if (dataLayout)
if (mlir::Attribute addrSpace = dataLayout->getAllocaMemorySpace())
return mlir::cast<mlir::IntegerAttr>(addrSpace).getUInt();
@@ -1940,3 +1941,20 @@ void fir::factory::genDimInfoFromBox(
strides->push_back(dimInfo.getByteStride());
}
}
mlir::Value fir::factory::genLifetimeStart(mlir::OpBuilder &builder,
mlir::Location loc,
fir::AllocaOp alloc, int64_t size,
const mlir::DataLayout *dl) {
mlir::Type ptrTy = mlir::LLVM::LLVMPointerType::get(
alloc.getContext(), getAllocaAddressSpace(dl));
mlir::Value cast =
builder.create<fir::ConvertOp>(loc, ptrTy, alloc.getResult());
builder.create<mlir::LLVM::LifetimeStartOp>(loc, size, cast);
return cast;
}
void fir::factory::genLifetimeEnd(mlir::OpBuilder &builder, mlir::Location loc,
mlir::Value cast, int64_t size) {
builder.create<mlir::LLVM::LifetimeEndOp>(loc, size, cast);
}