157f536a4SjeanPerier //===-- FIRDialect.cpp ----------------------------------------------------===//
257f536a4SjeanPerier //
357f536a4SjeanPerier // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457f536a4SjeanPerier // See https://llvm.org/LICENSE.txt for license information.
557f536a4SjeanPerier // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
657f536a4SjeanPerier //
757f536a4SjeanPerier //===----------------------------------------------------------------------===//
8399c3d5bSEric Schweitz //
9399c3d5bSEric Schweitz // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10399c3d5bSEric Schweitz //
11399c3d5bSEric Schweitz //===----------------------------------------------------------------------===//
1257f536a4SjeanPerier
1357f536a4SjeanPerier #include "flang/Optimizer/Dialect/FIRDialect.h"
1457f536a4SjeanPerier #include "flang/Optimizer/Dialect/FIRAttr.h"
1557f536a4SjeanPerier #include "flang/Optimizer/Dialect/FIROps.h"
1657f536a4SjeanPerier #include "flang/Optimizer/Dialect/FIRType.h"
176da728adSValentin Clement #include "mlir/Transforms/InliningUtils.h"
1857f536a4SjeanPerier
1957f536a4SjeanPerier using namespace fir;
2057f536a4SjeanPerier
216da728adSValentin Clement namespace {
226da728adSValentin Clement /// This class defines the interface for handling inlining of FIR calls.
236da728adSValentin Clement struct FIRInlinerInterface : public mlir::DialectInlinerInterface {
246da728adSValentin Clement using DialectInlinerInterface::DialectInlinerInterface;
256da728adSValentin Clement
isLegalToInline__anon9d7d931b0111::FIRInlinerInterface266da728adSValentin Clement bool isLegalToInline(mlir::Operation *call, mlir::Operation *callable,
276da728adSValentin Clement bool wouldBeCloned) const final {
286da728adSValentin Clement return fir::canLegallyInline(call, callable, wouldBeCloned);
296da728adSValentin Clement }
306da728adSValentin Clement
316da728adSValentin Clement /// This hook checks to see if the operation `op` is legal to inline into the
326da728adSValentin Clement /// given region `reg`.
isLegalToInline__anon9d7d931b0111::FIRInlinerInterface336da728adSValentin Clement bool isLegalToInline(mlir::Operation *op, mlir::Region *reg,
346da728adSValentin Clement bool wouldBeCloned,
356da728adSValentin Clement mlir::BlockAndValueMapping &map) const final {
366da728adSValentin Clement return fir::canLegallyInline(op, reg, wouldBeCloned, map);
376da728adSValentin Clement }
386da728adSValentin Clement
396da728adSValentin Clement /// This hook is called when a terminator operation has been inlined.
406da728adSValentin Clement /// We handle the return (a Fortran FUNCTION) by replacing the values
416da728adSValentin Clement /// previously returned by the call operation with the operands of the
426da728adSValentin Clement /// return.
handleTerminator__anon9d7d931b0111::FIRInlinerInterface436da728adSValentin Clement void handleTerminator(mlir::Operation *op,
446da728adSValentin Clement llvm::ArrayRef<mlir::Value> valuesToRepl) const final {
45*092601d4SAndrzej Warzynski auto returnOp = llvm::cast<mlir::func::ReturnOp>(op);
466da728adSValentin Clement assert(returnOp.getNumOperands() == valuesToRepl.size());
476da728adSValentin Clement for (const auto &it : llvm::enumerate(returnOp.getOperands()))
486da728adSValentin Clement valuesToRepl[it.index()].replaceAllUsesWith(it.value());
496da728adSValentin Clement }
506da728adSValentin Clement
materializeCallConversion__anon9d7d931b0111::FIRInlinerInterface516da728adSValentin Clement mlir::Operation *materializeCallConversion(mlir::OpBuilder &builder,
526da728adSValentin Clement mlir::Value input,
536da728adSValentin Clement mlir::Type resultType,
546da728adSValentin Clement mlir::Location loc) const final {
556da728adSValentin Clement return builder.create<fir::ConvertOp>(loc, resultType, input);
566da728adSValentin Clement }
576da728adSValentin Clement };
586da728adSValentin Clement } // namespace
596da728adSValentin Clement
FIROpsDialect(mlir::MLIRContext * ctx)6057f536a4SjeanPerier fir::FIROpsDialect::FIROpsDialect(mlir::MLIRContext *ctx)
6182fd1392SRiver Riddle : mlir::Dialect("fir", ctx, mlir::TypeID::get<FIROpsDialect>()) {
6231bb8efdSRiver Riddle registerTypes();
6331bb8efdSRiver Riddle registerAttributes();
6457f536a4SjeanPerier addOperations<
6557f536a4SjeanPerier #define GET_OP_LIST
6657f536a4SjeanPerier #include "flang/Optimizer/Dialect/FIROps.cpp.inc"
6757f536a4SjeanPerier >();
686da728adSValentin Clement addInterfaces<FIRInlinerInterface>();
6957f536a4SjeanPerier }
7057f536a4SjeanPerier
7157f536a4SjeanPerier // anchor the class vtable to this compilation unit
~FIROpsDialect()7257f536a4SjeanPerier fir::FIROpsDialect::~FIROpsDialect() {
7357f536a4SjeanPerier // do nothing
7457f536a4SjeanPerier }
7557f536a4SjeanPerier
parseType(mlir::DialectAsmParser & parser) const7657f536a4SjeanPerier mlir::Type fir::FIROpsDialect::parseType(mlir::DialectAsmParser &parser) const {
7757f536a4SjeanPerier return parseFirType(const_cast<FIROpsDialect *>(this), parser);
7857f536a4SjeanPerier }
7957f536a4SjeanPerier
printType(mlir::Type ty,mlir::DialectAsmPrinter & p) const8057f536a4SjeanPerier void fir::FIROpsDialect::printType(mlir::Type ty,
8157f536a4SjeanPerier mlir::DialectAsmPrinter &p) const {
8257f536a4SjeanPerier return printFirType(const_cast<FIROpsDialect *>(this), ty, p);
8357f536a4SjeanPerier }
8457f536a4SjeanPerier
8557f536a4SjeanPerier mlir::Attribute
parseAttribute(mlir::DialectAsmParser & parser,mlir::Type type) const8657f536a4SjeanPerier fir::FIROpsDialect::parseAttribute(mlir::DialectAsmParser &parser,
8757f536a4SjeanPerier mlir::Type type) const {
8857f536a4SjeanPerier return parseFirAttribute(const_cast<FIROpsDialect *>(this), parser, type);
8957f536a4SjeanPerier }
9057f536a4SjeanPerier
printAttribute(mlir::Attribute attr,mlir::DialectAsmPrinter & p) const9157f536a4SjeanPerier void fir::FIROpsDialect::printAttribute(mlir::Attribute attr,
9257f536a4SjeanPerier mlir::DialectAsmPrinter &p) const {
9357f536a4SjeanPerier printFirAttribute(const_cast<FIROpsDialect *>(this), attr, p);
9457f536a4SjeanPerier }
95