//===-- CodeGenOpenMP.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 // //===----------------------------------------------------------------------===// // // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ // //===----------------------------------------------------------------------===// #include "flang/Optimizer/CodeGen/CodeGenOpenMP.h" #include "flang/Optimizer/Builder/FIRBuilder.h" #include "flang/Optimizer/Builder/LowLevelIntrinsics.h" #include "flang/Optimizer/CodeGen/CodeGen.h" #include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/FIROps.h" #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/Dialect/Support/FIRContext.h" #include "flang/Optimizer/Support/FatalError.h" #include "flang/Optimizer/Support/InternalNames.h" #include "mlir/Conversion/LLVMCommon/ConversionTarget.h" #include "mlir/Conversion/LLVMCommon/Pattern.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Transforms/DialectConversion.h" using namespace fir; #define DEBUG_TYPE "flang-codegen-openmp" // fir::LLVMTypeConverter for converting to LLVM IR dialect types. #include "flang/Optimizer/CodeGen/TypeConverter.h" namespace { /// A pattern that converts the region arguments in a single-region OpenMP /// operation to the LLVM dialect. The body of the region is not modified and is /// expected to either be processed by the conversion infrastructure or already /// contain ops compatible with LLVM dialect types. template class OpenMPFIROpConversion : public mlir::ConvertOpToLLVMPattern { public: explicit OpenMPFIROpConversion(const fir::LLVMTypeConverter &lowering) : mlir::ConvertOpToLLVMPattern(lowering) {} const fir::LLVMTypeConverter &lowerTy() const { return *static_cast( this->getTypeConverter()); } }; // FIR Op specific conversion for MapInfoOp that overwrites the default OpenMP // Dialect lowering, this allows FIR specific lowering of types, required for // descriptors of allocatables currently. struct MapInfoOpConversion : public OpenMPFIROpConversion { using OpenMPFIROpConversion::OpenMPFIROpConversion; llvm::LogicalResult matchAndRewrite(mlir::omp::MapInfoOp curOp, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const override { const mlir::TypeConverter *converter = getTypeConverter(); llvm::SmallVector resTypes; if (failed(converter->convertTypes(curOp->getResultTypes(), resTypes))) return mlir::failure(); llvm::SmallVector newAttrs; mlir::omp::MapInfoOp newOp; for (mlir::NamedAttribute attr : curOp->getAttrs()) { if (auto typeAttr = mlir::dyn_cast(attr.getValue())) { mlir::Type newAttr; if (fir::isTypeWithDescriptor(typeAttr.getValue())) { newAttr = lowerTy().convertBoxTypeAsStruct( mlir::cast(typeAttr.getValue())); } else { newAttr = converter->convertType(typeAttr.getValue()); } newAttrs.emplace_back(attr.getName(), mlir::TypeAttr::get(newAttr)); } else { newAttrs.push_back(attr); } } rewriter.replaceOpWithNewOp( curOp, resTypes, adaptor.getOperands(), newAttrs); return mlir::success(); } }; } // namespace void fir::populateOpenMPFIRToLLVMConversionPatterns( const LLVMTypeConverter &converter, mlir::RewritePatternSet &patterns) { patterns.add(converter); }