[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