Skip to content

Commit 88e1769

Browse files
committed
[flang][WIP] Add support for -emit-fir
A new parent class for code-gen frontend actions is introduced: `CodeGenAction`. We will be using this class to encapsulate logic shared between all code-generation actions but not required otherwise. For `-emit-fir`, a specialisation of `CodeGenAction` is introduced: `EmitFIRAction`. The key logic for this class is implemented in `EmitFirAction::ExecuteAction`.
1 parent 0792de9 commit 88e1769

File tree

11 files changed

+123
-0
lines changed

11 files changed

+123
-0
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4467,6 +4467,9 @@ def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group
44674467
HelpText<"Specify where to find the compiled intrinsic modules">,
44684468
DocBrief<[{This option specifies the location of pre-compiled intrinsic modules,
44694469
if they are not in the default location expected by the compiler.}]>;
4470+
4471+
def emit_fir : Flag<["-"], "emit-fir">, Group<Action_Group>,
4472+
HelpText<"Build the parse tree, then convert to FIR and dump">;
44704473
}
44714474

44724475
def J : JoinedOrSeparate<["-"], "J">,

clang/lib/Driver/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "ToolChains/PS4CPU.h"
4444
#include "ToolChains/RISCVToolchain.h"
4545
#include "ToolChains/Solaris.h"
46+
4647
#include "ToolChains/TCE.h"
4748
#include "ToolChains/VEToolchain.h"
4849
#include "ToolChains/WebAssembly.h"

flang/include/flang/Frontend/FrontendActions.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,19 @@ class ParseSyntaxOnlyAction : public PrescanAndSemaAction {
127127
void ExecuteAction() override;
128128
};
129129

130+
//===----------------------------------------------------------------------===//
131+
// CodeGen Actions
132+
//===----------------------------------------------------------------------===//
133+
class CodeGenAction : public FrontendAction {
134+
135+
void ExecuteAction() override = 0;
136+
bool BeginSourceFileAction() override;
137+
};
138+
139+
class EmitFirAction : public CodeGenAction {
140+
void ExecuteAction() override;
141+
};
142+
130143
} // namespace Fortran::frontend
131144

132145
#endif // LLVM_FLANG_FRONTEND_FRONTENDACTIONS_H

flang/include/flang/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ enum ActionKind {
3131
/// -fsyntax-only
3232
ParseSyntaxOnly,
3333

34+
/// Emit a .mlir file
35+
EmitFir,
36+
3437
/// Emit a .o file.
3538
EmitObj,
3639

flang/lib/Frontend/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
2+
13
add_flang_library(flangFrontend
24
CompilerInstance.cpp
35
CompilerInvocation.cpp
@@ -19,6 +21,15 @@ add_flang_library(flangFrontend
1921
FortranLower
2022
clangBasic
2123
clangDriver
24+
FIRDialect
25+
FIRAnalysis
26+
FIRSupport
27+
FIRTransforms
28+
FIRBuilder
29+
FIRRuntime
30+
${dialect_libs}
31+
MLIRAffineToStandard
32+
MLIRSCFToStandard
2233

2334
LINK_COMPONENTS
2435
Option

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ static bool ParseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
123123
case clang::driver::options::OPT_fsyntax_only:
124124
opts.programAction = ParseSyntaxOnly;
125125
break;
126+
case clang::driver::options::OPT_emit_fir:
127+
opts.programAction = EmitFir;
128+
break;
126129
case clang::driver::options::OPT_emit_obj:
127130
opts.programAction = EmitObj;
128131
break;

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#include "flang/Frontend/CompilerInstance.h"
1212
#include "flang/Frontend/FrontendOptions.h"
1313
#include "flang/Frontend/PreprocessorOptions.h"
14+
#include "flang/Lower/Bridge.h"
1415
#include "flang/Lower/PFTBuilder.h"
16+
#include "flang/Optimizer/Dialect/FIRType.h"
1517
#include "flang/Parser/dump-parse-tree.h"
1618
#include "flang/Parser/parsing.h"
1719
#include "flang/Parser/provenance.h"
@@ -22,8 +24,16 @@
2224
#include "flang/Semantics/unparse-with-symbols.h"
2325
#include "llvm/ADT/StringRef.h"
2426
#include "llvm/Support/ErrorHandling.h"
27+
#include "llvm/Support/raw_ostream.h"
2528
#include <clang/Basic/Diagnostic.h>
2629
#include <memory>
30+
#include "mlir/IR/Dialect.h"
31+
#include "flang/Optimizer/Support/InitFIR.h"
32+
#include "flang/Optimizer/Support/KindMapping.h"
33+
#include "flang/Lower/Bridge.h"
34+
#include "mlir/Pass/PassManager.h"
35+
#include "mlir/Support/LogicalResult.h"
36+
#include "flang/Lower/Support/Verifier.h"
2737

2838
using namespace Fortran::frontend;
2939

@@ -40,6 +50,10 @@ bool PrescanAndSemaAction::BeginSourceFileAction() {
4050
return RunPrescan() & RunParse() && RunSemanticChecks();
4151
}
4252

53+
bool CodeGenAction::BeginSourceFileAction() {
54+
return RunPrescan() & RunParse() && RunSemanticChecks();
55+
}
56+
4357
//===----------------------------------------------------------------------===//
4458
// Custom ExecuteAction
4559
//===----------------------------------------------------------------------===//
@@ -351,6 +365,65 @@ void GetSymbolsSourcesAction::ExecuteAction() {
351365
ci.semantics().DumpSymbolsSources(llvm::outs());
352366
}
353367

368+
// Translate front-end KINDs for use in the IR and code gen. Extracted from
369+
// bbc.cpp.
370+
// TODO: How to share this with bbc.cpp?
371+
static std::vector<fir::KindTy>
372+
fromDefaultKinds(const Fortran::common::IntrinsicTypeDefaultKinds &defKinds) {
373+
return {static_cast<fir::KindTy>(defKinds.GetDefaultKind(
374+
Fortran::common::TypeCategory::Character)),
375+
static_cast<fir::KindTy>(
376+
defKinds.GetDefaultKind(Fortran::common::TypeCategory::Complex)),
377+
static_cast<fir::KindTy>(defKinds.doublePrecisionKind()),
378+
static_cast<fir::KindTy>(
379+
defKinds.GetDefaultKind(Fortran::common::TypeCategory::Integer)),
380+
static_cast<fir::KindTy>(
381+
defKinds.GetDefaultKind(Fortran::common::TypeCategory::Logical)),
382+
static_cast<fir::KindTy>(
383+
defKinds.GetDefaultKind(Fortran::common::TypeCategory::Real))};
384+
}
385+
386+
void EmitFirAction::ExecuteAction() {
387+
CompilerInstance &ci = this->instance();
388+
389+
// Load the MLIR dialects required by Flang
390+
mlir::DialectRegistry registry;
391+
mlir::MLIRContext ctx(registry);
392+
fir::support::registerNonCodegenDialects(registry);
393+
fir::support::loadNonCodegenDialects(ctx);
394+
395+
// Create a LoweringBridge
396+
auto &defKinds = ci.invocation().semanticsContext().defaultKinds();
397+
fir::KindMapping kindMap(
398+
&ctx, llvm::ArrayRef<fir::KindTy>{fromDefaultKinds(defKinds)});
399+
auto lb = Fortran::lower::LoweringBridge::create(ctx, defKinds,
400+
ci.invocation().semanticsContext().intrinsics(), ci.parsing().allCooked(),
401+
"", kindMap);
402+
403+
// Create PFT and lower it to FIR
404+
auto &parseTree{*ci.parsing().parseTree()};
405+
lb.lower(parseTree, ci.invocation().semanticsContext());
406+
407+
// Run the default passes.
408+
mlir::PassManager pm(&ctx, mlir::OpPassManager::Nesting::Implicit);
409+
pm.enableVerifier(/*verifyPasses=*/true);
410+
pm.addPass(std::make_unique<Fortran::lower::VerifierPass>());
411+
mlir::ModuleOp mlirModule = lb.getModule();
412+
if (mlir::failed(pm.run(mlirModule))) {
413+
// TODO: Replace with a diagnostic
414+
llvm::errs() << "FATAL: verification of lowering to FIR failed";
415+
}
416+
417+
// Print the output
418+
auto os{ci.CreateDefaultOutputFile(
419+
/*Binary=*/true, /*InFile=*/GetCurrentFileOrBufferName(), "mlir")};
420+
if (!os) {
421+
return;
422+
}
423+
424+
mlirModule.print(*os);
425+
}
426+
354427
void EmitObjAction::ExecuteAction() {
355428
CompilerInstance &ci = this->instance();
356429
unsigned DiagID = ci.diagnostics().getCustomDiagID(

flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ static std::unique_ptr<FrontendAction> CreateFrontendBaseAction(
3232
return std::make_unique<PrintPreprocessedAction>();
3333
case ParseSyntaxOnly:
3434
return std::make_unique<ParseSyntaxOnlyAction>();
35+
break;
36+
case EmitFir:
37+
return std::make_unique<EmitFirAction>();
38+
break;
3539
case EmitObj:
3640
return std::make_unique<EmitObjAction>();
3741
case DebugUnparse:

flang/test/Driver/driver-help-hidden.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
! CHECK-NEXT: -cpp Enable predefined and command line preprocessor macros
2323
! CHECK-NEXT: -c Only run preprocess, compile, and assemble steps
2424
! CHECK-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
25+
! CHECK-NEXT: -emit-fir Build the parse tree, then convert to FIR and dump
2526
! CHECK-NEXT: -E Only run the preprocessor
2627
! CHECK-NEXT: -falternative-parameter-statement
2728
! CHECK-NEXT: Enable the old style PARAMETER statement

flang/test/Driver/driver-help.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
! HELP-NEXT: -cpp Enable predefined and command line preprocessor macros
2323
! HELP-NEXT: -c Only run preprocess, compile, and assemble steps
2424
! HELP-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
25+
! HELP-NEXT: -emit-fir Build the parse tree, then convert to FIR and dump
2526
! HELP-NEXT: -E Only run the preprocessor
2627
! HELP-NEXT: -falternative-parameter-statement
2728
! HELP-NEXT: Enable the old style PARAMETER statement
@@ -65,6 +66,7 @@
6566
! HELP-FC1-NEXT:OPTIONS:
6667
! HELP-FC1-NEXT: -cpp Enable predefined and command line preprocessor macros
6768
! HELP-FC1-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
69+
! HELP-FC1-NEXT: -emit-fir Build the parse tree, then convert to FIR and dump
6870
! HELP-FC1-NEXT: -emit-obj Emit native object files
6971
! HELP-FC1-NEXT: -E Only run the preprocessor
7072
! HELP-FC1-NEXT: -falternative-parameter-statement

0 commit comments

Comments
 (0)