As there is now certain areas where we now have the possibility of having either a ModuleOp or GPUModuleOp and both of these modules can have DataLayout's and we may require utilising the DataLayout utilities in these areas I've taken the liberty of trying to extend them for use with both. Those with more knowledge of how they wish the GPUModuleOp's to interact with their parent ModuleOp's DataLayout may have further alterations they wish to make in the future, but for the moment, it'll simply utilise the basic data layout construction which I believe combines parent and child datalayouts from the ModuleOp and GPUModuleOp. If there is no GPUModuleOp DataLayout it should default to the parent ModuleOp. It's worth noting there is some weirdness if you have two module operations defining builtin dialect DataLayout Entries, it appears the combinatorial functionality for DataLayouts doesn't support the merging of these. This behaviour is useful for areas like: https://github.com/llvm/llvm-project/pull/119585/files#diff-19fc4bcb38829d085e25d601d344bbd85bf7ef749ca359e348f4a7c750eae89dR1412 where we have a crossroads between the two different module operations.
98 lines
3.7 KiB
C++
98 lines
3.7 KiB
C++
//===-- Optimizer/Support/DataLayout.cpp ----------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "flang/Optimizer/Support/DataLayout.h"
|
|
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
|
|
#include "flang/Optimizer/Support/FatalError.h"
|
|
#include "mlir/Dialect/DLTI/DLTI.h"
|
|
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
|
|
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
|
#include "mlir/IR/BuiltinOps.h"
|
|
#include "mlir/Interfaces/DataLayoutInterfaces.h"
|
|
#include "mlir/Support/LLVM.h"
|
|
#include "mlir/Target/LLVMIR/Import.h"
|
|
#include "llvm/IR/DataLayout.h"
|
|
#include "llvm/MC/TargetRegistry.h"
|
|
#include "llvm/Support/TargetSelect.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
namespace {
|
|
template <typename ModOpTy>
|
|
static void setDataLayout(ModOpTy mlirModule, const llvm::DataLayout &dl) {
|
|
mlir::MLIRContext *context = mlirModule.getContext();
|
|
mlirModule->setAttr(
|
|
mlir::LLVM::LLVMDialect::getDataLayoutAttrName(),
|
|
mlir::StringAttr::get(context, dl.getStringRepresentation()));
|
|
mlir::DataLayoutSpecInterface dlSpec = mlir::translateDataLayout(dl, context);
|
|
mlirModule->setAttr(mlir::DLTIDialect::kDataLayoutAttrName, dlSpec);
|
|
}
|
|
|
|
template <typename ModOpTy>
|
|
static void setDataLayoutFromAttributes(ModOpTy mlirModule,
|
|
bool allowDefaultLayout) {
|
|
if (mlirModule.getDataLayoutSpec())
|
|
return; // Already set.
|
|
if (auto dataLayoutString =
|
|
mlirModule->template getAttrOfType<mlir::StringAttr>(
|
|
mlir::LLVM::LLVMDialect::getDataLayoutAttrName())) {
|
|
llvm::DataLayout llvmDataLayout(dataLayoutString);
|
|
fir::support::setMLIRDataLayout(mlirModule, llvmDataLayout);
|
|
return;
|
|
}
|
|
if (!allowDefaultLayout)
|
|
return;
|
|
llvm::DataLayout llvmDataLayout("");
|
|
fir::support::setMLIRDataLayout(mlirModule, llvmDataLayout);
|
|
}
|
|
|
|
template <typename ModOpTy>
|
|
static std::optional<mlir::DataLayout>
|
|
getOrSetDataLayout(ModOpTy mlirModule, bool allowDefaultLayout) {
|
|
if (!mlirModule.getDataLayoutSpec())
|
|
fir::support::setMLIRDataLayoutFromAttributes(mlirModule,
|
|
allowDefaultLayout);
|
|
if (!mlirModule.getDataLayoutSpec() &&
|
|
!mlir::isa<mlir::gpu::GPUModuleOp>(mlirModule))
|
|
return std::nullopt;
|
|
return mlir::DataLayout(mlirModule);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void fir::support::setMLIRDataLayout(mlir::ModuleOp mlirModule,
|
|
const llvm::DataLayout &dl) {
|
|
setDataLayout(mlirModule, dl);
|
|
}
|
|
|
|
void fir::support::setMLIRDataLayout(mlir::gpu::GPUModuleOp mlirModule,
|
|
const llvm::DataLayout &dl) {
|
|
setDataLayout(mlirModule, dl);
|
|
}
|
|
|
|
void fir::support::setMLIRDataLayoutFromAttributes(mlir::ModuleOp mlirModule,
|
|
bool allowDefaultLayout) {
|
|
setDataLayoutFromAttributes(mlirModule, allowDefaultLayout);
|
|
}
|
|
|
|
void fir::support::setMLIRDataLayoutFromAttributes(
|
|
mlir::gpu::GPUModuleOp mlirModule, bool allowDefaultLayout) {
|
|
setDataLayoutFromAttributes(mlirModule, allowDefaultLayout);
|
|
}
|
|
|
|
std::optional<mlir::DataLayout>
|
|
fir::support::getOrSetMLIRDataLayout(mlir::ModuleOp mlirModule,
|
|
bool allowDefaultLayout) {
|
|
return getOrSetDataLayout(mlirModule, allowDefaultLayout);
|
|
}
|
|
|
|
std::optional<mlir::DataLayout>
|
|
fir::support::getOrSetMLIRDataLayout(mlir::gpu::GPUModuleOp mlirModule,
|
|
bool allowDefaultLayout) {
|
|
return getOrSetDataLayout(mlirModule, allowDefaultLayout);
|
|
}
|