117 lines · cpp
1//===-- FIRDialect.cpp ----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/10//11//===----------------------------------------------------------------------===//12 13#include "flang/Optimizer/Dialect/FIRDialect.h"14#include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.h"15#include "flang/Optimizer/Dialect/FIRAttr.h"16#include "flang/Optimizer/Dialect/FIROps.h"17#include "flang/Optimizer/Dialect/FIRType.h"18#include "mlir/Dialect/LLVMIR/LLVMDialect.h"19#include "mlir/Target/LLVMIR/ModuleTranslation.h"20#include "mlir/Transforms/InliningUtils.h"21 22#include "flang/Optimizer/Dialect/FIRDialect.cpp.inc"23 24using namespace fir;25 26namespace {27/// This class defines the interface for handling inlining of FIR calls.28struct FIRInlinerInterface : public mlir::DialectInlinerInterface {29 using DialectInlinerInterface::DialectInlinerInterface;30 31 bool isLegalToInline(mlir::Operation *call, mlir::Operation *callable,32 bool wouldBeCloned) const final {33 return fir::canLegallyInline(call, callable, wouldBeCloned);34 }35 36 /// This hook checks to see if the operation `op` is legal to inline into the37 /// given region `reg`.38 bool isLegalToInline(mlir::Operation *op, mlir::Region *reg,39 bool wouldBeCloned, mlir::IRMapping &map) const final {40 return fir::canLegallyInline(op, reg, wouldBeCloned, map);41 }42 43 /// This hook is called when a terminator operation has been inlined.44 /// We handle the return (a Fortran FUNCTION) by replacing the values45 /// previously returned by the call operation with the operands of the46 /// return.47 void handleTerminator(mlir::Operation *op,48 mlir::ValueRange valuesToRepl) const final {49 auto returnOp = llvm::cast<mlir::func::ReturnOp>(op);50 assert(returnOp.getNumOperands() == valuesToRepl.size());51 for (const auto &it : llvm::enumerate(returnOp.getOperands()))52 valuesToRepl[it.index()].replaceAllUsesWith(it.value());53 }54 55 mlir::Operation *materializeCallConversion(mlir::OpBuilder &builder,56 mlir::Value input,57 mlir::Type resultType,58 mlir::Location loc) const final {59 return fir::ConvertOp::create(builder, loc, resultType, input);60 }61};62} // namespace63 64void fir::FIROpsDialect::initialize() {65 registerTypes();66 registerAttributes();67 addOperations<68#define GET_OP_LIST69#include "flang/Optimizer/Dialect/FIROps.cpp.inc"70 >();71 registerOpExternalInterfaces();72}73 74// Register the FIRInlinerInterface to FIROpsDialect75void fir::addFIRInlinerExtension(mlir::DialectRegistry ®istry) {76 registry.addExtension(77 +[](mlir::MLIRContext *ctx, fir::FIROpsDialect *dialect) {78 dialect->addInterface<FIRInlinerInterface>();79 });80}81 82// We do not provide LLVMTranslationDialectInterface implementation83// for FIR dialect, since at the point of translation to LLVM IR84// there should not be any FIR operations (the CodeGen converts85// them to LLVMIR dialect operations).86// Here we register the default implementation of87// LLVMTranslationDialectInterface that will drop all FIR dialect88// attributes - this helps to avoid warnings about unhandled attributes.89// We can provide our own implementation of the interface,90// when more sophisticated translation is required.91void fir::addFIRToLLVMIRExtension(mlir::DialectRegistry ®istry) {92 registry.addExtension(93 +[](mlir::MLIRContext *ctx, fir::FIROpsDialect *dialect) {94 dialect->addInterface<mlir::LLVMTranslationDialectInterface>();95 });96}97 98mlir::Type fir::FIROpsDialect::parseType(mlir::DialectAsmParser &parser) const {99 return parseFirType(const_cast<FIROpsDialect *>(this), parser);100}101 102void fir::FIROpsDialect::printType(mlir::Type ty,103 mlir::DialectAsmPrinter &p) const {104 return printFirType(const_cast<FIROpsDialect *>(this), ty, p);105}106 107mlir::Attribute108fir::FIROpsDialect::parseAttribute(mlir::DialectAsmParser &parser,109 mlir::Type type) const {110 return parseFirAttribute(const_cast<FIROpsDialect *>(this), parser, type);111}112 113void fir::FIROpsDialect::printAttribute(mlir::Attribute attr,114 mlir::DialectAsmPrinter &p) const {115 printFirAttribute(const_cast<FIROpsDialect *>(this), attr, p);116}117