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