xref: /llvm-project/flang/include/flang/Frontend/FrontendActions.h (revision c870632ef6162fbdccaad8cd09420728220ad344)
1 //===- FrontendActions.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_FRONTEND_FRONTENDACTIONS_H
14 #define FORTRAN_FRONTEND_FRONTENDACTIONS_H
15 
16 #include "flang/Frontend/CodeGenOptions.h"
17 #include "flang/Frontend/FrontendAction.h"
18 #include "flang/Parser/parsing.h"
19 #include "flang/Semantics/semantics.h"
20 
21 #include "mlir/IR/BuiltinOps.h"
22 #include "mlir/IR/OwningOpRef.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/IR/Module.h"
25 #include <memory>
26 
27 namespace Fortran::frontend {
28 
29 // TODO: This is a copy from f18.cpp. It doesn't really belong here and should
30 // be moved to a more suitable place in future.
31 struct MeasurementVisitor {
32   template <typename A>
33   bool Pre(const A &) {
34     return true;
35   }
36   template <typename A>
37   void Post(const A &) {
38     ++objects;
39     bytes += sizeof(A);
40   }
41   size_t objects{0}, bytes{0};
42 };
43 
44 //===----------------------------------------------------------------------===//
45 // Custom Consumer Actions
46 //===----------------------------------------------------------------------===//
47 
48 class InputOutputTestAction : public FrontendAction {
49   void executeAction() override;
50 };
51 
52 class InitOnlyAction : public FrontendAction {
53   void executeAction() override;
54 };
55 
56 //===----------------------------------------------------------------------===//
57 // Prescan Actions
58 //===----------------------------------------------------------------------===//
59 class PrescanAction : public FrontendAction {
60   void executeAction() override = 0;
61   bool beginSourceFileAction() override;
62 };
63 
64 class PrintPreprocessedAction : public PrescanAction {
65   void executeAction() override;
66 };
67 
68 class DebugDumpProvenanceAction : public PrescanAction {
69   void executeAction() override;
70 };
71 
72 class DebugDumpParsingLogAction : public PrescanAction {
73   void executeAction() override;
74 };
75 
76 class DebugMeasureParseTreeAction : public PrescanAction {
77   void executeAction() override;
78 };
79 
80 //===----------------------------------------------------------------------===//
81 // PrescanAndParse Actions
82 //===----------------------------------------------------------------------===//
83 class PrescanAndParseAction : public FrontendAction {
84   void executeAction() override = 0;
85   bool beginSourceFileAction() override;
86 };
87 
88 class DebugUnparseNoSemaAction : public PrescanAndParseAction {
89   void executeAction() override;
90 };
91 
92 class DebugDumpParseTreeNoSemaAction : public PrescanAndParseAction {
93   void executeAction() override;
94 };
95 
96 //===----------------------------------------------------------------------===//
97 // PrescanAndSema Actions
98 //
99 // These actions will parse the input, run the semantic checks and execute
100 // their actions provided that no parsing or semantic errors were found.
101 //===----------------------------------------------------------------------===//
102 class PrescanAndSemaAction : public FrontendAction {
103 
104   void executeAction() override = 0;
105   bool beginSourceFileAction() override;
106 };
107 
108 class DebugUnparseWithSymbolsAction : public PrescanAndSemaAction {
109   void executeAction() override;
110 };
111 
112 class DebugUnparseWithModulesAction : public PrescanAndSemaAction {
113   void executeAction() override;
114 };
115 
116 class DebugUnparseAction : public PrescanAndSemaAction {
117   void executeAction() override;
118 };
119 
120 class DebugDumpSymbolsAction : public PrescanAndSemaAction {
121   void executeAction() override;
122 };
123 
124 class DebugDumpParseTreeAction : public PrescanAndSemaAction {
125   void executeAction() override;
126 };
127 
128 class DebugDumpPFTAction : public PrescanAndSemaAction {
129   void executeAction() override;
130 };
131 
132 class DebugPreFIRTreeAction : public PrescanAndSemaAction {
133   void executeAction() override;
134 };
135 
136 class GetDefinitionAction : public PrescanAndSemaAction {
137   void executeAction() override;
138 };
139 
140 class GetSymbolsSourcesAction : public PrescanAndSemaAction {
141   void executeAction() override;
142 };
143 
144 class ParseSyntaxOnlyAction : public PrescanAndSemaAction {
145   void executeAction() override;
146 };
147 
148 class PluginParseTreeAction : public PrescanAndSemaAction {
149   void executeAction() override = 0;
150 
151 public:
152   Fortran::parser::Parsing &getParsing();
153   /// Creates an output file. This is just a wrapper for calling
154   /// CreateDefaultOutputFile from CompilerInstance. Use it to make sure that
155   /// your plugin respects driver's `-o` flag.
156   /// \param extension  The extension to use for the output file (ignored when
157   ///                   the user decides to print to stdout via `-o -`)
158   /// \return           Null on error, ostream for the output file otherwise
159   std::unique_ptr<llvm::raw_pwrite_stream>
160   createOutputFile(llvm::StringRef extension);
161 };
162 
163 //===----------------------------------------------------------------------===//
164 // PrescanAndSemaDebug Actions
165 //
166 // These actions will parse the input, run the semantic checks and execute
167 // their actions _regardless of_ whether any semantic errors have been found.
168 // This can be useful when adding new languge feature and when you wish to
169 // investigate compiler output (e.g. the parse tree) despite any semantic
170 // errors.
171 //
172 // NOTE: Use with care and for development only!
173 //===----------------------------------------------------------------------===//
174 class PrescanAndSemaDebugAction : public FrontendAction {
175 
176   void executeAction() override = 0;
177   bool beginSourceFileAction() override;
178 };
179 
180 class DebugDumpAllAction : public PrescanAndSemaDebugAction {
181   void executeAction() override;
182 };
183 
184 //===----------------------------------------------------------------------===//
185 // CodeGen Actions
186 //===----------------------------------------------------------------------===//
187 /// Represents the type of "backend" action to perform by the corresponding
188 /// CodeGenAction. Note that from Flang's perspective, both LLVM and MLIR are
189 /// "backends" that are used for generating LLVM IR/BC, assembly files or
190 /// machine code. This enum captures "what" exactly one of these backends is to
191 /// do. The names are similar to what is used in Clang - this allows us to
192 /// maintain some level of consistency/similarity between the drivers.
193 enum class BackendActionTy {
194   Backend_EmitAssembly, ///< Emit native assembly files
195   Backend_EmitObj,      ///< Emit native object files
196   Backend_EmitBC,       ///< Emit LLVM bitcode files
197   Backend_EmitLL,       ///< Emit human-readable LLVM assembly
198   Backend_EmitFIR,      ///< Emit FIR files, possibly lowering via HLFIR
199   Backend_EmitHLFIR,    ///< Emit HLFIR files before any passes run
200 };
201 
202 /// Abstract base class for actions that generate code (MLIR, LLVM IR, assembly
203 /// and machine code). Every action that inherits from this class will at
204 /// least run the prescanning, parsing, semantic checks and lower the parse
205 /// tree to an MLIR module.
206 class CodeGenAction : public FrontendAction {
207 
208   void executeAction() override;
209   /// Runs prescan, parsing, sema and lowers to MLIR.
210   bool beginSourceFileAction() override;
211   /// Runs the optimization (aka middle-end) pipeline on the LLVM module
212   /// associated with this action.
213   void runOptimizationPipeline(llvm::raw_pwrite_stream &os);
214 
215 protected:
216   CodeGenAction(BackendActionTy act) : action{act} {};
217   /// @name MLIR
218   /// {
219   std::unique_ptr<mlir::MLIRContext> mlirCtx;
220   mlir::OwningOpRef<mlir::ModuleOp> mlirModule;
221   /// }
222 
223   /// @name LLVM IR
224   std::unique_ptr<llvm::LLVMContext> llvmCtx;
225   std::unique_ptr<llvm::Module> llvmModule;
226 
227   /// Embeds offload objects specified with -fembed-offload-object
228   void embedOffloadObjects();
229 
230   /// Links in BC libraries spefified with -mlink-builtin-bitcode
231   void linkBuiltinBCLibs();
232 
233   /// Runs pass pipeline to lower HLFIR into FIR
234   void lowerHLFIRToFIR();
235 
236   /// Generates an LLVM IR module from CodeGenAction::mlirModule and saves it
237   /// in CodeGenAction::llvmModule.
238   void generateLLVMIR();
239 
240   BackendActionTy action;
241 
242   /// }
243 public:
244   ~CodeGenAction() override;
245 };
246 
247 class EmitFIRAction : public CodeGenAction {
248 public:
249   EmitFIRAction() : CodeGenAction(BackendActionTy::Backend_EmitFIR) {}
250 };
251 
252 class EmitHLFIRAction : public CodeGenAction {
253 public:
254   EmitHLFIRAction() : CodeGenAction(BackendActionTy::Backend_EmitHLFIR) {}
255 };
256 
257 class EmitLLVMAction : public CodeGenAction {
258 public:
259   EmitLLVMAction() : CodeGenAction(BackendActionTy::Backend_EmitLL) {}
260 };
261 
262 class EmitLLVMBitcodeAction : public CodeGenAction {
263 public:
264   EmitLLVMBitcodeAction() : CodeGenAction(BackendActionTy::Backend_EmitBC) {}
265 };
266 
267 class EmitObjAction : public CodeGenAction {
268 public:
269   EmitObjAction() : CodeGenAction(BackendActionTy::Backend_EmitObj) {}
270 };
271 
272 class EmitAssemblyAction : public CodeGenAction {
273 public:
274   EmitAssemblyAction() : CodeGenAction(BackendActionTy::Backend_EmitAssembly) {}
275 };
276 
277 } // namespace Fortran::frontend
278 
279 #endif // FORTRAN_FRONTEND_FRONTENDACTIONS_H
280