xref: /llvm-project/flang/lib/Optimizer/CodeGen/CodeGenOpenMP.cpp (revision 206fad0e218e83799e49ca15545d997c6c5e8a03)
195fe47caSagozillon //===-- CodeGenOpenMP.cpp -------------------------------------------------===//
295fe47caSagozillon //
395fe47caSagozillon // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
495fe47caSagozillon // See https://llvm.org/LICENSE.txt for license information.
595fe47caSagozillon // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
695fe47caSagozillon //
795fe47caSagozillon //===----------------------------------------------------------------------===//
895fe47caSagozillon //
995fe47caSagozillon // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
1095fe47caSagozillon //
1195fe47caSagozillon //===----------------------------------------------------------------------===//
1295fe47caSagozillon 
1395fe47caSagozillon #include "flang/Optimizer/CodeGen/CodeGenOpenMP.h"
1495fe47caSagozillon 
1595fe47caSagozillon #include "flang/Optimizer/Builder/FIRBuilder.h"
1695fe47caSagozillon #include "flang/Optimizer/Builder/LowLevelIntrinsics.h"
1795fe47caSagozillon #include "flang/Optimizer/CodeGen/CodeGen.h"
1895fe47caSagozillon #include "flang/Optimizer/Dialect/FIRDialect.h"
1995fe47caSagozillon #include "flang/Optimizer/Dialect/FIROps.h"
2095fe47caSagozillon #include "flang/Optimizer/Dialect/FIRType.h"
2195fe47caSagozillon #include "flang/Optimizer/Dialect/Support/FIRContext.h"
2295fe47caSagozillon #include "flang/Optimizer/Support/FatalError.h"
2395fe47caSagozillon #include "flang/Optimizer/Support/InternalNames.h"
2495fe47caSagozillon #include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
2595fe47caSagozillon #include "mlir/Conversion/LLVMCommon/Pattern.h"
2695fe47caSagozillon #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
2795fe47caSagozillon #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
2895fe47caSagozillon #include "mlir/IR/PatternMatch.h"
2995fe47caSagozillon #include "mlir/Transforms/DialectConversion.h"
3095fe47caSagozillon 
3195fe47caSagozillon using namespace fir;
3295fe47caSagozillon 
3395fe47caSagozillon #define DEBUG_TYPE "flang-codegen-openmp"
3495fe47caSagozillon 
3595fe47caSagozillon // fir::LLVMTypeConverter for converting to LLVM IR dialect types.
3695fe47caSagozillon #include "flang/Optimizer/CodeGen/TypeConverter.h"
3795fe47caSagozillon 
3895fe47caSagozillon namespace {
3995fe47caSagozillon /// A pattern that converts the region arguments in a single-region OpenMP
4095fe47caSagozillon /// operation to the LLVM dialect. The body of the region is not modified and is
4195fe47caSagozillon /// expected to either be processed by the conversion infrastructure or already
4295fe47caSagozillon /// contain ops compatible with LLVM dialect types.
4395fe47caSagozillon template <typename OpType>
4495fe47caSagozillon class OpenMPFIROpConversion : public mlir::ConvertOpToLLVMPattern<OpType> {
4595fe47caSagozillon public:
4695fe47caSagozillon   explicit OpenMPFIROpConversion(const fir::LLVMTypeConverter &lowering)
4795fe47caSagozillon       : mlir::ConvertOpToLLVMPattern<OpType>(lowering) {}
4895fe47caSagozillon 
4995fe47caSagozillon   const fir::LLVMTypeConverter &lowerTy() const {
5095fe47caSagozillon     return *static_cast<const fir::LLVMTypeConverter *>(
5195fe47caSagozillon         this->getTypeConverter());
5295fe47caSagozillon   }
5395fe47caSagozillon };
5495fe47caSagozillon 
5595fe47caSagozillon // FIR Op specific conversion for MapInfoOp that overwrites the default OpenMP
5695fe47caSagozillon // Dialect lowering, this allows FIR specific lowering of types, required for
5795fe47caSagozillon // descriptors of allocatables currently.
5895fe47caSagozillon struct MapInfoOpConversion
5995fe47caSagozillon     : public OpenMPFIROpConversion<mlir::omp::MapInfoOp> {
6095fe47caSagozillon   using OpenMPFIROpConversion::OpenMPFIROpConversion;
6195fe47caSagozillon 
62db791b27SRamkumar Ramachandra   llvm::LogicalResult
6395fe47caSagozillon   matchAndRewrite(mlir::omp::MapInfoOp curOp, OpAdaptor adaptor,
6495fe47caSagozillon                   mlir::ConversionPatternRewriter &rewriter) const override {
6595fe47caSagozillon     const mlir::TypeConverter *converter = getTypeConverter();
6695fe47caSagozillon     llvm::SmallVector<mlir::Type> resTypes;
6795fe47caSagozillon     if (failed(converter->convertTypes(curOp->getResultTypes(), resTypes)))
6895fe47caSagozillon       return mlir::failure();
6995fe47caSagozillon 
7095fe47caSagozillon     llvm::SmallVector<mlir::NamedAttribute> newAttrs;
7195fe47caSagozillon     mlir::omp::MapInfoOp newOp;
7295fe47caSagozillon     for (mlir::NamedAttribute attr : curOp->getAttrs()) {
7395fe47caSagozillon       if (auto typeAttr = mlir::dyn_cast<mlir::TypeAttr>(attr.getValue())) {
7495fe47caSagozillon         mlir::Type newAttr;
7595fe47caSagozillon         if (fir::isTypeWithDescriptor(typeAttr.getValue())) {
7695fe47caSagozillon           newAttr = lowerTy().convertBoxTypeAsStruct(
7795fe47caSagozillon               mlir::cast<fir::BaseBoxType>(typeAttr.getValue()));
7895fe47caSagozillon         } else {
7995fe47caSagozillon           newAttr = converter->convertType(typeAttr.getValue());
8095fe47caSagozillon         }
8195fe47caSagozillon         newAttrs.emplace_back(attr.getName(), mlir::TypeAttr::get(newAttr));
8295fe47caSagozillon       } else {
8395fe47caSagozillon         newAttrs.push_back(attr);
8495fe47caSagozillon       }
8595fe47caSagozillon     }
8695fe47caSagozillon 
8795fe47caSagozillon     rewriter.replaceOpWithNewOp<mlir::omp::MapInfoOp>(
8895fe47caSagozillon         curOp, resTypes, adaptor.getOperands(), newAttrs);
8995fe47caSagozillon 
9095fe47caSagozillon     return mlir::success();
9195fe47caSagozillon   }
9295fe47caSagozillon };
9395fe47caSagozillon } // namespace
9495fe47caSagozillon 
9595fe47caSagozillon void fir::populateOpenMPFIRToLLVMConversionPatterns(
96*206fad0eSMatthias Springer     const LLVMTypeConverter &converter, mlir::RewritePatternSet &patterns) {
9795fe47caSagozillon   patterns.add<MapInfoOpConversion>(converter);
9895fe47caSagozillon }
99