| //===- FrontendActions.h -----------------------------------------*- C++-*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef FORTRAN_FRONTEND_FRONTENDACTIONS_H |
| #define FORTRAN_FRONTEND_FRONTENDACTIONS_H |
| |
| #include "flang/Frontend/CodeGenOptions.h" |
| #include "flang/Frontend/FrontendAction.h" |
| #include "flang/Parser/parsing.h" |
| #include "flang/Semantics/semantics.h" |
| |
| #include "mlir/IR/BuiltinOps.h" |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/IR/Module.h" |
| #include <memory> |
| |
| namespace Fortran::frontend { |
| |
| // TODO: This is a copy from f18.cpp. It doesn't really belong here and should |
| // be moved to a more suitable place in future. |
| struct MeasurementVisitor { |
| template <typename A> |
| bool Pre(const A &) { |
| return true; |
| } |
| template <typename A> |
| void Post(const A &) { |
| ++objects; |
| bytes += sizeof(A); |
| } |
| size_t objects{0}, bytes{0}; |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| // Custom Consumer Actions |
| //===----------------------------------------------------------------------===// |
| |
| class InputOutputTestAction : public FrontendAction { |
| void executeAction() override; |
| }; |
| |
| class InitOnlyAction : public FrontendAction { |
| void executeAction() override; |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| // Prescan Actions |
| //===----------------------------------------------------------------------===// |
| class PrescanAction : public FrontendAction { |
| void executeAction() override = 0; |
| bool beginSourceFileAction() override; |
| }; |
| |
| class PrintPreprocessedAction : public PrescanAction { |
| void executeAction() override; |
| }; |
| |
| class DebugDumpProvenanceAction : public PrescanAction { |
| void executeAction() override; |
| }; |
| |
| class DebugDumpParsingLogAction : public PrescanAction { |
| void executeAction() override; |
| }; |
| |
| class DebugMeasureParseTreeAction : public PrescanAction { |
| void executeAction() override; |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| // PrescanAndParse Actions |
| //===----------------------------------------------------------------------===// |
| class PrescanAndParseAction : public FrontendAction { |
| void executeAction() override = 0; |
| bool beginSourceFileAction() override; |
| }; |
| |
| class DebugUnparseNoSemaAction : public PrescanAndParseAction { |
| void executeAction() override; |
| }; |
| |
| class DebugDumpParseTreeNoSemaAction : public PrescanAndParseAction { |
| void executeAction() override; |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| // PrescanAndSema Actions |
| // |
| // These actions will parse the input, run the semantic checks and execute |
| // their actions provided that no parsing or semantic errors were found. |
| //===----------------------------------------------------------------------===// |
| class PrescanAndSemaAction : public FrontendAction { |
| |
| void executeAction() override = 0; |
| bool beginSourceFileAction() override; |
| }; |
| |
| class DebugUnparseWithSymbolsAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class DebugUnparseAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class DebugDumpSymbolsAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class DebugDumpParseTreeAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class DebugDumpPFTAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class DebugPreFIRTreeAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class GetDefinitionAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class GetSymbolsSourcesAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class ParseSyntaxOnlyAction : public PrescanAndSemaAction { |
| void executeAction() override; |
| }; |
| |
| class PluginParseTreeAction : public PrescanAndSemaAction { |
| void executeAction() override = 0; |
| |
| public: |
| Fortran::parser::Parsing &getParsing(); |
| /// Creates an output file. This is just a wrapper for calling |
| /// CreateDefaultOutputFile from CompilerInstance. Use it to make sure that |
| /// your plugin respects driver's `-o` flag. |
| /// \param extension The extension to use for the output file (ignored when |
| /// the user decides to print to stdout via `-o -`) |
| /// \return Null on error, ostream for the output file otherwise |
| std::unique_ptr<llvm::raw_pwrite_stream> |
| createOutputFile(llvm::StringRef extension); |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| // PrescanAndSemaDebug Actions |
| // |
| // These actions will parse the input, run the semantic checks and execute |
| // their actions _regardless of_ whether any semantic errors have been found. |
| // This can be useful when adding new languge feature and when you wish to |
| // investigate compiler output (e.g. the parse tree) despite any semantic |
| // errors. |
| // |
| // NOTE: Use with care and for development only! |
| //===----------------------------------------------------------------------===// |
| class PrescanAndSemaDebugAction : public FrontendAction { |
| |
| void executeAction() override = 0; |
| bool beginSourceFileAction() override; |
| }; |
| |
| class DebugDumpAllAction : public PrescanAndSemaDebugAction { |
| void executeAction() override; |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| // CodeGen Actions |
| //===----------------------------------------------------------------------===// |
| /// Represents the type of "backend" action to perform by the corresponding |
| /// CodeGenAction. Note that from Flang's perspective, both LLVM and MLIR are |
| /// "backends" that are used for generating LLVM IR/BC, assembly files or |
| /// machine code. This enum captures "what" exactly one of these backends is to |
| /// do. The names are similar to what is used in Clang - this allows us to |
| /// maintain some level of consistency/similarity between the drivers. |
| enum class BackendActionTy { |
| Backend_EmitAssembly, ///< Emit native assembly files |
| Backend_EmitObj, ///< Emit native object files |
| Backend_EmitBC, ///< Emit LLVM bitcode files |
| Backend_EmitLL, ///< Emit human-readable LLVM assembly |
| Backend_EmitFIR, ///< Emit FIR files, possibly lowering via HLFIR |
| Backend_EmitHLFIR, ///< Emit HLFIR files before any passes run |
| }; |
| |
| /// Abstract base class for actions that generate code (MLIR, LLVM IR, assembly |
| /// and machine code). Every action that inherits from this class will at |
| /// least run the prescanning, parsing, semantic checks and lower the parse |
| /// tree to an MLIR module. |
| class CodeGenAction : public FrontendAction { |
| |
| void executeAction() override; |
| /// Runs prescan, parsing, sema and lowers to MLIR. |
| bool beginSourceFileAction() override; |
| /// Runs the optimization (aka middle-end) pipeline on the LLVM module |
| /// associated with this action. |
| void runOptimizationPipeline(llvm::raw_pwrite_stream &os); |
| |
| protected: |
| CodeGenAction(BackendActionTy act) : action{act} {}; |
| /// @name MLIR |
| /// { |
| std::unique_ptr<mlir::ModuleOp> mlirModule; |
| std::unique_ptr<mlir::MLIRContext> mlirCtx; |
| /// } |
| |
| /// @name LLVM IR |
| std::unique_ptr<llvm::LLVMContext> llvmCtx; |
| std::unique_ptr<llvm::Module> llvmModule; |
| |
| /// Embeds offload objects given with specified with -fembed-offload-object |
| void embedOffloadObjects(); |
| |
| /// Runs pass pipeline to lower HLFIR into FIR |
| void lowerHLFIRToFIR(); |
| |
| /// Generates an LLVM IR module from CodeGenAction::mlirModule and saves it |
| /// in CodeGenAction::llvmModule. |
| void generateLLVMIR(); |
| |
| BackendActionTy action; |
| |
| /// } |
| public: |
| ~CodeGenAction() override; |
| }; |
| |
| class EmitFIRAction : public CodeGenAction { |
| public: |
| EmitFIRAction() : CodeGenAction(BackendActionTy::Backend_EmitFIR) {} |
| }; |
| |
| class EmitHLFIRAction : public CodeGenAction { |
| public: |
| EmitHLFIRAction() : CodeGenAction(BackendActionTy::Backend_EmitHLFIR) {} |
| }; |
| |
| class EmitLLVMAction : public CodeGenAction { |
| public: |
| EmitLLVMAction() : CodeGenAction(BackendActionTy::Backend_EmitLL) {} |
| }; |
| |
| class EmitLLVMBitcodeAction : public CodeGenAction { |
| public: |
| EmitLLVMBitcodeAction() : CodeGenAction(BackendActionTy::Backend_EmitBC) {} |
| }; |
| |
| class EmitObjAction : public CodeGenAction { |
| public: |
| EmitObjAction() : CodeGenAction(BackendActionTy::Backend_EmitObj) {} |
| }; |
| |
| class EmitAssemblyAction : public CodeGenAction { |
| public: |
| EmitAssemblyAction() : CodeGenAction(BackendActionTy::Backend_EmitAssembly) {} |
| }; |
| |
| } // namespace Fortran::frontend |
| |
| #endif // FORTRAN_FRONTEND_FRONTENDACTIONS_H |