[flang-commits] [flang] cc3c6b6 - [flang][driver] Make `flang-new -fc1` accept MLIR files
Andrzej Warzynski via flang-commits
flang-commits at lists.llvm.org
Fri Jun 10 03:59:19 PDT 2022
Author: Andrzej Warzynski
Date: 2022-06-10T10:58:54Z
New Revision: cc3c6b61095a47687858b21e93d1a2fc3a6e192b
URL: https://github.com/llvm/llvm-project/commit/cc3c6b61095a47687858b21e93d1a2fc3a6e192b
DIFF: https://github.com/llvm/llvm-project/commit/cc3c6b61095a47687858b21e93d1a2fc3a6e192b.diff
LOG: [flang][driver] Make `flang-new -fc1` accept MLIR files
This relatively small change will allow Flang's frontend driver,
`flang-new -fc1`, to consume and parse MLIR files. Semantically (i.e.
from user's perspective) this is identical to reading LLVM IR files.
Two file extensions are associated with MLIR files: .fir and .mlir. Note
that reading MLIR files makes only sense when running one of the
code-generation actions, i.e. when using one of the following action
flags: -S, -emit-obj, -emit-llvm, -emit-llvm-bc.
The majority of tests that required `tco` to run are updated to also run
with `flang-new -fc1`. A few tests are updated to use `fir-opt` instead
of `tco` (that's the preferred choice when testing a particular MLIR
pass). basic-program.fir is not updated as that test is intended to
verify the behaviour of `tco` specifically.
Differential Revision: https://reviews.llvm.org/D126890
Added:
flang/test/Driver/emit-asm-from-mlir.mlir
flang/test/Driver/parse-fir-error.ll
Modified:
flang/include/flang/Frontend/FrontendOptions.h
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Frontend/FrontendActions.cpp
flang/lib/Frontend/FrontendOptions.cpp
flang/test/Fir/addrof.fir
flang/test/Fir/alloc.fir
flang/test/Fir/arrayset.fir
flang/test/Fir/boxchar.fir
flang/test/Fir/embox.fir
flang/test/Fir/global.fir
flang/test/Fir/ignore-missing-type-descriptor.fir
flang/test/Fir/inline.fir
flang/test/Fir/optional.fir
flang/test/Fir/peephole.fir
flang/test/Fir/rebox.fir
flang/test/Fir/select.fir
flang/test/Fir/widechar.fir
flang/test/Lower/common-block.f90
flang/test/Lower/complex-part.f90
flang/test/Lower/forall/character-1.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h
index c8f74e31de432..3be87b6f5218d 100644
--- a/flang/include/flang/Frontend/FrontendOptions.h
+++ b/flang/include/flang/Frontend/FrontendOptions.h
@@ -115,12 +115,17 @@ bool isToBePreprocessed(llvm::StringRef suffix);
enum class Language : uint8_t {
Unknown,
+ /// MLIR: we accept this so that we can run the optimizer on it, and compile
+ /// it to LLVM IR, assembly or object code.
+ MLIR,
+
/// LLVM IR: we accept this so that we can run the optimizer on it,
/// and compile it to assembly or object code.
LLVM_IR,
/// @{ Languages that the frontend can parse and compile.
Fortran,
+ /// @}
};
// Source file layout
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index cc376f3b7d851..8f2167b14f0e6 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -269,10 +269,12 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
.Case("f95-cpp-input", Language::Fortran)
.Default(Language::Unknown);
- // Some special cases cannot be combined with suffixes.
+ // Flang's intermediate representations.
if (dashX.isUnknown())
dashX = llvm::StringSwitch<InputKind>(xValue)
.Case("ir", Language::LLVM_IR)
+ .Case("fir", Language::MLIR)
+ .Case("mlir", Language::MLIR)
.Default(Language::Unknown);
if (dashX.isUnknown())
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 57b6203f94b2e..a842420be887a 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -32,6 +32,7 @@
#include "flang/Semantics/unparse-with-symbols.h"
#include "mlir/IR/Dialect.h"
+#include "mlir/Parser/Parser.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
#include "clang/Basic/Diagnostic.h"
@@ -96,6 +97,34 @@ bool CodeGenAction::beginSourceFileAction() {
return true;
}
+ // Load the MLIR dialects required by Flang
+ mlir::DialectRegistry registry;
+ mlirCtx = std::make_unique<mlir::MLIRContext>(registry);
+ fir::support::registerNonCodegenDialects(registry);
+ fir::support::loadNonCodegenDialects(*mlirCtx);
+ fir::support::loadDialects(*mlirCtx);
+ fir::support::registerLLVMTranslation(*mlirCtx);
+
+ // If the input is an MLIR file, just parse it and return.
+ if (this->getCurrentInput().getKind().getLanguage() == Language::MLIR) {
+ llvm::SourceMgr sourceMgr;
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileOrErr =
+ llvm::MemoryBuffer::getFileOrSTDIN(getCurrentInput().getFile());
+ sourceMgr.AddNewSourceBuffer(std::move(*fileOrErr), llvm::SMLoc());
+ mlir::OwningOpRef<mlir::ModuleOp> module =
+ mlir::parseSourceFile<mlir::ModuleOp>(sourceMgr, mlirCtx.get());
+
+ if (!module || mlir::failed(module->verifyInvariants())) {
+ unsigned diagID = ci.getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "Could not parse FIR");
+ ci.getDiagnostics().Report(diagID);
+ return false;
+ }
+
+ mlirModule = std::make_unique<mlir::ModuleOp>(module.release());
+ return true;
+ }
+
// Otherwise, generate an MLIR module from the input Fortran source
if (getCurrentInput().getKind().getLanguage() != Language::Fortran) {
unsigned diagID = ci.getDiagnostics().getCustomDiagID(
@@ -109,12 +138,6 @@ bool CodeGenAction::beginSourceFileAction() {
if (!res)
return res;
- // Load the MLIR dialects required by Flang
- mlir::DialectRegistry registry;
- mlirCtx = std::make_unique<mlir::MLIRContext>(registry);
- fir::support::registerNonCodegenDialects(registry);
- fir::support::loadNonCodegenDialects(*mlirCtx);
-
// Create a LoweringBridge
const common::IntrinsicTypeDefaultKinds &defKinds =
ci.getInvocation().getSemanticsContext().defaultKinds();
diff --git a/flang/lib/Frontend/FrontendOptions.cpp b/flang/lib/Frontend/FrontendOptions.cpp
index 574e007278327..8353858ff5094 100644
--- a/flang/lib/Frontend/FrontendOptions.cpp
+++ b/flang/lib/Frontend/FrontendOptions.cpp
@@ -42,6 +42,8 @@ InputKind FrontendOptions::getInputKindForExtension(llvm::StringRef extension) {
if (extension == "bc" || extension == "ll")
return Language::LLVM_IR;
+ if (extension == "fir" || extension == "mlir")
+ return Language::MLIR;
return Language::Unknown;
}
diff --git a/flang/test/Driver/emit-asm-from-mlir.mlir b/flang/test/Driver/emit-asm-from-mlir.mlir
new file mode 100644
index 0000000000000..d0dbd7bdc41e2
--- /dev/null
+++ b/flang/test/Driver/emit-asm-from-mlir.mlir
@@ -0,0 +1,19 @@
+; Verify that the driver can consume MLIR/FIR files.
+
+;-------------
+; RUN COMMANDS
+;-------------
+; RUN: %flang_fc1 -S %s -o - | FileCheck %s
+
+;----------------
+; EXPECTED OUTPUT
+;----------------
+; CHECK-LABEL: foo:
+; CHECK: ret
+
+;------
+; INPUT
+;------
+func.func @foo() {
+ return
+}
diff --git a/flang/test/Driver/parse-fir-error.ll b/flang/test/Driver/parse-fir-error.ll
new file mode 100644
index 0000000000000..e2ac4797aa6ba
--- /dev/null
+++ b/flang/test/Driver/parse-fir-error.ll
@@ -0,0 +1,21 @@
+; This file is a valid LLVM IR file, but we force the driver to treat it as
+; FIR (with the `-x` flag). This way we verify that the driver
+; correctly rejects invalid FIR input.
+
+;----------
+; RUN LINES
+;----------
+; Input type is implicit (correctly assumed to be LLVM IR)
+; RUN: %flang_fc1 -S %s -o -
+
+; Input type is explicitly set as FIR
+; Verify that parsing errors are correctly reported by the driver
+; RUN: not %flang_fc1 -S -x fir %s 2>&1 | FileCheck %s --check-prefix=ERROR
+; RUN: not %flang_fc1 -S %s -x mlir 2>&1 | FileCheck %s --check-prefix=ERROR
+
+; ERROR: error: unexpected character
+; ERROR: error: Could not parse FIR
+
+define void @foo() {
+ ret void
+}
diff --git a/flang/test/Fir/addrof.fir b/flang/test/Fir/addrof.fir
index 059a43778e535..bc80a6bfca86d 100644
--- a/flang/test/Fir/addrof.fir
+++ b/flang/test/Fir/addrof.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// CHECK: @var_x = external global i32
fir.global @var_x : !fir.int<4> {}
diff --git a/flang/test/Fir/alloc.fir b/flang/test/Fir/alloc.fir
index dd4efae9968c6..d3dddf70433ce 100644
--- a/flang/test/Fir/alloc.fir
+++ b/flang/test/Fir/alloc.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// UNSUPPORTED: system-windows
diff --git a/flang/test/Fir/arrayset.fir b/flang/test/Fir/arrayset.fir
index 248fc9420889c..a9630c815fc42 100644
--- a/flang/test/Fir/arrayset.fir
+++ b/flang/test/Fir/arrayset.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// CHECK-LABEL: define void @x(ptr %0)
func.func @x(%arr : !fir.ref<!fir.array<10xf32>>) {
diff --git a/flang/test/Fir/boxchar.fir b/flang/test/Fir/boxchar.fir
index ee20424b001fd..06d66202ff894 100644
--- a/flang/test/Fir/boxchar.fir
+++ b/flang/test/Fir/boxchar.fir
@@ -1,4 +1,5 @@
// RUN: tco --target=x86_64-unknown-linux-gnu %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s
// Test of building and passing boxchar.
diff --git a/flang/test/Fir/embox.fir b/flang/test/Fir/embox.fir
index 68e59f7055dfc..aec11dd19ddf7 100644
--- a/flang/test/Fir/embox.fir
+++ b/flang/test/Fir/embox.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -mmlir -disable-external-name-interop -emit-llvm %s -o -| FileCheck %s
// CHECK-LABEL: define void @_QPtest_callee(ptr %0)
diff --git a/flang/test/Fir/global.fir b/flang/test/Fir/global.fir
index a29c1da4974af..598fcb3da60c9 100644
--- a/flang/test/Fir/global.fir
+++ b/flang/test/Fir/global.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// CHECK: @g_i0 = global i32 0
fir.global @g_i0 : i32 {
diff --git a/flang/test/Fir/ignore-missing-type-descriptor.fir b/flang/test/Fir/ignore-missing-type-descriptor.fir
index 50e11bc6955dd..14b210f5a0de7 100644
--- a/flang/test/Fir/ignore-missing-type-descriptor.fir
+++ b/flang/test/Fir/ignore-missing-type-descriptor.fir
@@ -3,6 +3,7 @@
// having to care with providing an ABI compliant derived type descriptor object.
// Missing derived type descriptor pointers are replaced by null pointers.
// RUN: tco --ignore-missing-type-desc -o - %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm -mmlir --ignore-missing-type-desc -o - %s | FileCheck %s
!some_freestyle_type = !fir.type<some_not_mangled_type{j:i32}>
diff --git a/flang/test/Fir/inline.fir b/flang/test/Fir/inline.fir
index 67e37234be68a..48f10c1e85198 100644
--- a/flang/test/Fir/inline.fir
+++ b/flang/test/Fir/inline.fir
@@ -1,4 +1,5 @@
// RUN: tco --target=x86_64-unknown-linux-gnu --inline-all %s -o - | FileCheck %s
+// RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -mmlir --inline-all -emit-llvm %s -o - | FileCheck %s
// CHECK-LABEL: @add
func.func @add(%a : i32, %b : i32) -> i32 {
diff --git a/flang/test/Fir/optional.fir b/flang/test/Fir/optional.fir
index 19653aae06ac2..644a7ef8d2198 100644
--- a/flang/test/Fir/optional.fir
+++ b/flang/test/Fir/optional.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// Test fir.is_present and fir.absent codegen
diff --git a/flang/test/Fir/peephole.fir b/flang/test/Fir/peephole.fir
index a19519a7c8f6f..28fe33c93e7d2 100644
--- a/flang/test/Fir/peephole.fir
+++ b/flang/test/Fir/peephole.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// Test peephole optimizations
diff --git a/flang/test/Fir/rebox.fir b/flang/test/Fir/rebox.fir
index b018ec4f4a48d..5cdf2cd1b4be7 100644
--- a/flang/test/Fir/rebox.fir
+++ b/flang/test/Fir/rebox.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// Test applying slice on fir.box
// subroutine foo(x)
diff --git a/flang/test/Fir/select.fir b/flang/test/Fir/select.fir
index 5b15e205117bf..47cc5e4122076 100644
--- a/flang/test/Fir/select.fir
+++ b/flang/test/Fir/select.fir
@@ -1,6 +1,7 @@
// Test lowering FIR to LLVM IR of fir.select{|_rank|_case}
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// CHECK-LABEL: @f
func.func @f(%a : i32) -> i32 {
diff --git a/flang/test/Fir/widechar.fir b/flang/test/Fir/widechar.fir
index 251b77d5dc680..c0f8d09789790 100644
--- a/flang/test/Fir/widechar.fir
+++ b/flang/test/Fir/widechar.fir
@@ -1,4 +1,5 @@
// RUN: tco %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s
// CHECK-LABEL: @character_literal1
func.func @character_literal1() -> !fir.char<1,13> {
diff --git a/flang/test/Lower/common-block.f90 b/flang/test/Lower/common-block.f90
index 8ea9daf2bf3c6..d569adb79dba4 100644
--- a/flang/test/Lower/common-block.f90
+++ b/flang/test/Lower/common-block.f90
@@ -1,4 +1,5 @@
! RUN: bbc %s -o - | tco | FileCheck %s
+! RUN: %flang -emit-llvm -S -mmlir -disable-external-name-interop %s -o - | FileCheck %s
! CHECK: @_QB = common global [8 x i8] zeroinitializer
! CHECK: @_QBrien = common global [1 x i8] zeroinitializer
diff --git a/flang/test/Lower/complex-part.f90 b/flang/test/Lower/complex-part.f90
index 28051485834de..896f17d91f171 100644
--- a/flang/test/Lower/complex-part.f90
+++ b/flang/test/Lower/complex-part.f90
@@ -1,4 +1,5 @@
! RUN: bbc %s -o - | tco | FileCheck %s
+! RUN: %flang -emit-llvm -S -mmlir -disable-external-name-interop %s -o - | FileCheck %s
COMPLEX c
c%RE = 3.14
diff --git a/flang/test/Lower/forall/character-1.f90 b/flang/test/Lower/forall/character-1.f90
index 3ba2bdd5efca3..92f215b23a889 100644
--- a/flang/test/Lower/forall/character-1.f90
+++ b/flang/test/Lower/forall/character-1.f90
@@ -1,4 +1,5 @@
! RUN: bbc %s -o - | tco | FileCheck %s
+! RUN: %flang -emit-llvm -S -mmlir -disable-external-name-interop %s -o - | FileCheck %s
! Test from Fortran source through to LLVM IR.
! UNSUPPORTED: system-windows
@@ -23,7 +24,7 @@ end program test
! CHECK: %[[elesize:.*]] = getelementptr { {{.*}}, [1 x [3 x i64]] }, ptr %[[arg]], i32 0, i32 1
! CHECK: %[[esval:.*]] = load i64, ptr %[[elesize]]
! CHECK: %[[mul:.*]] = mul i64 1, %[[esval]]
-! CHECK: %[[mul2:.*]] = mul i64 %[[mul]], %[[extval]], !dbg !17
+! CHECK: %[[mul2:.*]] = mul i64 %[[mul]], %[[extval]]
! CHECK: %[[buff:.*]] = call ptr @malloc(i64 %[[mul2]])
! CHECK: %[[to:.*]] = getelementptr i8, ptr %[[buff]], i64 %
! CHECK: call void @llvm.memmove.p0.p0.i64(ptr %[[to]], ptr %{{.*}}, i64 %{{.*}}, i1 false)
More information about the flang-commits
mailing list