Skip to content

Commit bb177ed

Browse files
committed
[flang][driver] Re-organise the code-gen actions (nfc)
All frontend actions that generate code (MLIR, LLVM IR/BC, Assembly/Object Code) are re-factored as essentially one action, `CodeGenAction`, with minor specialisations. To facilate all this, `CodeGenAction` is extended to hold `TargetMachine` and backend action type (MLIR vs LLVM IR vs LLVM BC vs Assembly vs Object Code). `CodeGenAction` is no longer a pure abstract class and the corresponding `ExecuteAction` is implemented so that it covers all use cases. All this allows a much better code re-use. Key functionality is extracted into some helpful hooks: * `SetUpTargetMachine` * `GetOutputStream` * `EmitObjectCodeHelper` * `EmitBCHelper` I hope that this clarifies the overall structure. I suspect that we may need to revisit this again as the functionality grows in complexity. Differential Revision: https://reviews.llvm.org/D124665
1 parent c894e85 commit bb177ed

File tree

3 files changed

+156
-143
lines changed

3 files changed

+156
-143
lines changed

flang/include/flang/Frontend/FrontendActions.h

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "mlir/IR/BuiltinOps.h"
1717
#include "llvm/ADT/StringRef.h"
1818
#include "llvm/IR/Module.h"
19+
#include "llvm/Target/TargetMachine.h"
1920
#include <memory>
2021

2122
namespace Fortran::frontend {
@@ -170,17 +171,33 @@ class DebugDumpAllAction : public PrescanAndSemaDebugAction {
170171
//===----------------------------------------------------------------------===//
171172
// CodeGen Actions
172173
//===----------------------------------------------------------------------===//
174+
/// Represents the type of "backend" action to perform by the corresponding
175+
/// CodeGenAction. Note that from Flang's perspective, both LLVM and MLIR are
176+
/// "backends" that are used for generating LLVM IR/BC, assembly files or
177+
/// machine code. This enum captures "what" exactly one of these backends is to
178+
/// do. The names are similar to what is used in Clang - this allows us to
179+
/// maintain some level of consistency/similarity between the drivers.
180+
enum class BackendActionTy {
181+
Backend_EmitAssembly, ///< Emit native assembly files
182+
Backend_EmitObj, ///< Emit native object files
183+
Backend_EmitBC, ///< Emit LLVM bitcode files
184+
Backend_EmitLL, ///< Emit human-readable LLVM assembly
185+
Backend_EmitMLIR ///< Emit MLIR files
186+
};
187+
173188
/// Abstract base class for actions that generate code (MLIR, LLVM IR, assembly
174189
/// and machine code). Every action that inherits from this class will at
175190
/// least run the prescanning, parsing, semantic checks and lower the parse
176191
/// tree to an MLIR module.
177192
class CodeGenAction : public FrontendAction {
178193

179-
void ExecuteAction() override = 0;
194+
void ExecuteAction() override;
180195
/// Runs prescan, parsing, sema and lowers to MLIR.
181196
bool BeginSourceFileAction() override;
197+
void SetUpTargetMachine();
182198

183199
protected:
200+
CodeGenAction(BackendActionTy act) : action{act} {};
184201
/// @name MLIR
185202
/// {
186203
std::unique_ptr<mlir::ModuleOp> mlirModule;
@@ -194,34 +211,38 @@ class CodeGenAction : public FrontendAction {
194211
/// Generates an LLVM IR module from CodeGenAction::mlirModule and saves it
195212
/// in CodeGenAction::llvmModule.
196213
void GenerateLLVMIR();
214+
215+
BackendActionTy action;
216+
217+
std::unique_ptr<llvm::TargetMachine> TM;
197218
/// }
219+
public:
220+
~CodeGenAction() override;
198221
};
199222

200223
class EmitMLIRAction : public CodeGenAction {
201-
void ExecuteAction() override;
224+
public:
225+
EmitMLIRAction() : CodeGenAction(BackendActionTy::Backend_EmitMLIR) {}
202226
};
203227

204228
class EmitLLVMAction : public CodeGenAction {
205-
void ExecuteAction() override;
229+
public:
230+
EmitLLVMAction() : CodeGenAction(BackendActionTy::Backend_EmitLL) {}
206231
};
207232

208233
class EmitLLVMBitcodeAction : public CodeGenAction {
209-
void ExecuteAction() override;
234+
public:
235+
EmitLLVMBitcodeAction() : CodeGenAction(BackendActionTy::Backend_EmitBC) {}
210236
};
211237

212-
class BackendAction : public CodeGenAction {
238+
class EmitObjAction : public CodeGenAction {
213239
public:
214-
enum class BackendActionTy {
215-
Backend_EmitAssembly, ///< Emit native assembly files
216-
Backend_EmitObj ///< Emit native object files
217-
};
218-
219-
BackendAction(BackendActionTy act) : action{act} {};
220-
221-
private:
222-
void ExecuteAction() override;
240+
EmitObjAction() : CodeGenAction(BackendActionTy::Backend_EmitObj) {}
241+
};
223242

224-
BackendActionTy action;
243+
class EmitAssemblyAction : public CodeGenAction {
244+
public:
245+
EmitAssemblyAction() : CodeGenAction(BackendActionTy::Backend_EmitAssembly) {}
225246
};
226247

227248
} // namespace Fortran::frontend

0 commit comments

Comments
 (0)