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