xref: /llvm-project/flang/include/flang/Optimizer/Support/InitFIR.h (revision 01a0d212a64919205734706d929db37e503c35ce)
1 //===-- Optimizer/Support/InitFIR.h -----------------------------*- C++ -*-===//
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 #ifndef FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
14 #define FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
15 
16 #include "flang/Optimizer/Dialect/CUF/CUFDialect.h"
17 #include "flang/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.h"
18 #include "flang/Optimizer/Dialect/FIRDialect.h"
19 #include "flang/Optimizer/HLFIR/HLFIRDialect.h"
20 #include "flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h"
21 #include "mlir/Conversion/Passes.h"
22 #include "mlir/Dialect/Affine/Passes.h"
23 #include "mlir/Dialect/Complex/IR/Complex.h"
24 #include "mlir/Dialect/Func/Extensions/InlinerExtension.h"
25 #include "mlir/Dialect/OpenACC/Transforms/Passes.h"
26 #include "mlir/InitAllDialects.h"
27 #include "mlir/Pass/Pass.h"
28 #include "mlir/Pass/PassRegistry.h"
29 #include "mlir/Transforms/LocationSnapshot.h"
30 #include "mlir/Transforms/Passes.h"
31 
32 namespace fir::support {
33 
34 #define FLANG_NONCODEGEN_DIALECT_LIST                                          \
35   mlir::affine::AffineDialect, FIROpsDialect, hlfir::hlfirDialect,             \
36       mlir::acc::OpenACCDialect, mlir::omp::OpenMPDialect,                     \
37       mlir::scf::SCFDialect, mlir::arith::ArithDialect,                        \
38       mlir::cf::ControlFlowDialect, mlir::func::FuncDialect,                   \
39       mlir::vector::VectorDialect, mlir::math::MathDialect,                    \
40       mlir::complex::ComplexDialect, mlir::DLTIDialect, cuf::CUFDialect
41 
42 #define FLANG_CODEGEN_DIALECT_LIST FIRCodeGenDialect, mlir::LLVM::LLVMDialect
43 
44 // The definitive list of dialects used by flang.
45 #define FLANG_DIALECT_LIST                                                     \
46   FLANG_NONCODEGEN_DIALECT_LIST, FLANG_CODEGEN_DIALECT_LIST
47 
48 inline void registerNonCodegenDialects(mlir::DialectRegistry &registry) {
49   registry.insert<FLANG_NONCODEGEN_DIALECT_LIST>();
50   mlir::func::registerInlinerExtension(registry);
51   mlir::LLVM::registerInlinerInterface(registry);
52 }
53 
54 /// Register all the dialects used by flang.
55 inline void registerDialects(mlir::DialectRegistry &registry) {
56   registerNonCodegenDialects(registry);
57   registry.insert<FLANG_CODEGEN_DIALECT_LIST>();
58 }
59 
60 // Register FIR Extensions
61 inline void addFIRExtensions(mlir::DialectRegistry &registry,
62                              bool addFIRInlinerInterface = true) {
63   if (addFIRInlinerInterface)
64     addFIRInlinerExtension(registry);
65   addFIRToLLVMIRExtension(registry);
66   cuf::registerCUFDialectTranslation(registry);
67   fir::acc::registerOpenACCExtensions(registry);
68 }
69 
70 inline void loadNonCodegenDialects(mlir::MLIRContext &context) {
71   mlir::DialectRegistry registry;
72   registerNonCodegenDialects(registry);
73   context.appendDialectRegistry(registry);
74 
75   context.loadDialect<FLANG_NONCODEGEN_DIALECT_LIST>();
76 }
77 
78 /// Forced load of all the dialects used by flang.  Lowering is not an MLIR
79 /// pass, but a producer of FIR and MLIR. It is therefore a requirement that the
80 /// dialects be preloaded to be able to build the IR.
81 inline void loadDialects(mlir::MLIRContext &context) {
82   mlir::DialectRegistry registry;
83   registerDialects(registry);
84   context.appendDialectRegistry(registry);
85 
86   context.loadDialect<FLANG_DIALECT_LIST>();
87 }
88 
89 /// Register the standard passes we use. This comes from registerAllPasses(),
90 /// but is a smaller set since we aren't using many of the passes found there.
91 inline void registerMLIRPassesForFortranTools() {
92   mlir::acc::registerOpenACCPasses();
93   mlir::registerCanonicalizerPass();
94   mlir::registerCSEPass();
95   mlir::affine::registerAffineLoopFusionPass();
96   mlir::registerLoopInvariantCodeMotionPass();
97   mlir::affine::registerLoopCoalescingPass();
98   mlir::registerStripDebugInfoPass();
99   mlir::registerPrintOpStatsPass();
100   mlir::registerInlinerPass();
101   mlir::registerSCCPPass();
102   mlir::affine::registerAffineScalarReplacementPass();
103   mlir::registerSymbolDCEPass();
104   mlir::registerLocationSnapshotPass();
105   mlir::affine::registerAffinePipelineDataTransferPass();
106 
107   mlir::affine::registerAffineVectorizePass();
108   mlir::affine::registerAffineLoopUnrollPass();
109   mlir::affine::registerAffineLoopUnrollAndJamPass();
110   mlir::affine::registerSimplifyAffineStructuresPass();
111   mlir::affine::registerAffineLoopInvariantCodeMotionPass();
112   mlir::affine::registerAffineLoopTilingPass();
113   mlir::affine::registerAffineDataCopyGenerationPass();
114 
115   mlir::registerConvertAffineToStandardPass();
116 }
117 
118 /// Register the interfaces needed to lower to LLVM IR.
119 void registerLLVMTranslation(mlir::MLIRContext &context);
120 
121 } // namespace fir::support
122 
123 #endif // FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
124