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-exception
6//
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/FIRAttr.h"
15#include "flang/Optimizer/Dialect/FIROps.h"
16#include "flang/Optimizer/Dialect/FIRType.h"
17#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
18#include "mlir/Target/LLVMIR/ModuleTranslation.h"
19#include "mlir/Transforms/InliningUtils.h"
20
21#include "flang/Optimizer/Dialect/FIRDialect.cpp.inc"
22
23using namespace fir;
24
25namespace {
26/// This class defines the interface for handling inlining of FIR calls.
27struct FIRInlinerInterface : public mlir::DialectInlinerInterface {
28 using DialectInlinerInterface::DialectInlinerInterface;
29
30 bool isLegalToInline(mlir::Operation *call, mlir::Operation *callable,
31 bool wouldBeCloned) const final {
32 return fir::canLegallyInline(call, callable, wouldBeCloned);
33 }
34
35 /// This hook checks to see if the operation `op` is legal to inline into the
36 /// given region `reg`.
37 bool isLegalToInline(mlir::Operation *op, mlir::Region *reg,
38 bool wouldBeCloned, mlir::IRMapping &map) const final {
39 return fir::canLegallyInline(op, reg, wouldBeCloned, map);
40 }
41
42 /// This hook is called when a terminator operation has been inlined.
43 /// We handle the return (a Fortran FUNCTION) by replacing the values
44 /// previously returned by the call operation with the operands of the
45 /// return.
46 void handleTerminator(mlir::Operation *op,
47 mlir::ValueRange valuesToRepl) const final {
48 auto returnOp = llvm::cast<mlir::func::ReturnOp>(op);
49 assert(returnOp.getNumOperands() == valuesToRepl.size());
50 for (const auto &it : llvm::enumerate(returnOp.getOperands()))
51 valuesToRepl[it.index()].replaceAllUsesWith(it.value());
52 }
53
54 mlir::Operation *materializeCallConversion(mlir::OpBuilder &builder,
55 mlir::Value input,
56 mlir::Type resultType,
57 mlir::Location loc) const final {
58 return builder.create<fir::ConvertOp>(loc, resultType, input);
59 }
60};
61} // namespace
62
63void fir::FIROpsDialect::initialize() {
64 registerTypes();
65 registerAttributes();
66 addOperations<
67#define GET_OP_LIST
68#include "flang/Optimizer/Dialect/FIROps.cpp.inc"
69 >();
70 registerOpExternalInterfaces();
71}
72
73// Register the FIRInlinerInterface to FIROpsDialect
74void fir::addFIRInlinerExtension(mlir::DialectRegistry &registry) {
75 registry.addExtension(
76 +[](mlir::MLIRContext *ctx, fir::FIROpsDialect *dialect) {
77 dialect->addInterface<FIRInlinerInterface>();
78 });
79}
80
81// We do not provide LLVMTranslationDialectInterface implementation
82// for FIR dialect, since at the point of translation to LLVM IR
83// there should not be any FIR operations (the CodeGen converts
84// them to LLVMIR dialect operations).
85// Here we register the default implementation of
86// LLVMTranslationDialectInterface that will drop all FIR dialect
87// attributes - this helps to avoid warnings about unhandled attributes.
88// We can provide our own implementation of the interface,
89// when more sophisticated translation is required.
90void fir::addFIRToLLVMIRExtension(mlir::DialectRegistry &registry) {
91 registry.addExtension(
92 +[](mlir::MLIRContext *ctx, fir::FIROpsDialect *dialect) {
93 dialect->addInterface<mlir::LLVMTranslationDialectInterface>();
94 });
95}
96
97mlir::Type fir::FIROpsDialect::parseType(mlir::DialectAsmParser &parser) const {
98 return parseFirType(const_cast<FIROpsDialect *>(this), parser);
99}
100
101void fir::FIROpsDialect::printType(mlir::Type ty,
102 mlir::DialectAsmPrinter &p) const {
103 return printFirType(const_cast<FIROpsDialect *>(this), ty, p);
104}
105
106mlir::Attribute
107fir::FIROpsDialect::parseAttribute(mlir::DialectAsmParser &parser,
108 mlir::Type type) const {
109 return parseFirAttribute(const_cast<FIROpsDialect *>(this), parser, type);
110}
111
112void fir::FIROpsDialect::printAttribute(mlir::Attribute attr,
113 mlir::DialectAsmPrinter &p) const {
114 printFirAttribute(const_cast<FIROpsDialect *>(this), attr, p);
115}
116

source code of flang/lib/Optimizer/Dialect/FIRDialect.cpp