OSDN Git Service

[flang][driver] Add support for `-c` and `-emit-obj`
authorAndrzej Warzynski <andrzej.warzynski@arm.com>
Thu, 7 Jan 2021 09:08:54 +0000 (09:08 +0000)
committerAndrzej Warzynski <andrzej.warzynski@arm.com>
Thu, 7 Jan 2021 10:52:38 +0000 (10:52 +0000)
This patch adds a frontend action for emitting object files. While Flang
does not support code-generation, this action remains a placeholder.
This patch simply provides glue-code to connect the compiler driver
with the appropriate frontend action.

The new action is triggered with the `-c` compiler driver flag, i.e.
`flang-new -c`. This is then translated to `flang-new -fc1 -emit-obj`,
so `-emit-obj` has to be marked as supported as well.

As code-generation is not available yet, `flang-new -c` results in a
driver error:
```
error: code-generation is not available yet
```
Hopefully this will help communicating the level of available
functionality within Flang.

The definition of `emit-obj` is updated so that it can be shared between
Clang and Flang. As the original definition was enclosed within a
Clang-specific TableGen `let` statement, it is extracted into a new `let`
statement. That felt like the cleanest option.

I also commented out `-triple` in Flang::ConstructJob and updated some
comments there. This is similar to https://reviews.llvm.org/D93027. I
wanted to make sure that it's clear that we can't support `-triple`
until we have code-generation. However, once code-generation is
available we _will need_ `-triple`.

As this patch adds `-emit-obj`, the emit-obj.f90 becomes irrelevant and
is deleted. Instead, phases.f90 is added to demonstrate that users can
control compilation phases (indeed, `-c` is a phase control flag).

Reviewed By: SouraVX, clementval

Differential Revision: https://reviews.llvm.org/D93301

12 files changed:
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Flang.cpp
flang/include/flang/Frontend/FrontendActions.h
flang/include/flang/Frontend/FrontendOptions.h
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Frontend/FrontendActions.cpp
flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
flang/test/Flang-Driver/code-gen.f90 [new file with mode: 0644]
flang/test/Flang-Driver/driver-help-hidden.f90
flang/test/Flang-Driver/driver-help.f90
flang/test/Flang-Driver/emit-obj.f90 [deleted file]
flang/test/Flang-Driver/phases.f90 [new file with mode: 0644]

index 6b5ae35..ffa7fbd 100644 (file)
@@ -857,7 +857,7 @@ def current__version : JoinedOrSeparate<["-"], "current_version">;
 def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
   HelpText<"Add directory to the C++ SYSTEM include search path">, Flags<[CC1Option]>,
   MetaVarName<"<directory>">;
-def c : Flag<["-"], "c">, Flags<[NoXarchOption]>, Group<Action_Group>,
+def c : Flag<["-"], "c">, Flags<[NoXarchOption, FlangOption]>, Group<Action_Group>,
   HelpText<"Only run preprocess, compile, and assemble steps">;
 def fconvergent_functions : Flag<["-"], "fconvergent-functions">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Assume functions may be convergent">;
@@ -4854,8 +4854,6 @@ def emit_llvm_only : Flag<["-"], "emit-llvm-only">,
   HelpText<"Build ASTs and convert to LLVM, discarding output">;
 def emit_codegen_only : Flag<["-"], "emit-codegen-only">,
   HelpText<"Generate machine code, but discard output">;
-def emit_obj : Flag<["-"], "emit-obj">,
-  HelpText<"Emit native object files">;
 def rewrite_test : Flag<["-"], "rewrite-test">,
   HelpText<"Rewriter playground">;
 def rewrite_macros : Flag<["-"], "rewrite-macros">,
@@ -5230,6 +5228,18 @@ def fsycl_is_device : Flag<["-"], "fsycl-is-device">,
 } // let Flags = [CC1Option, NoDriverOption]
 
 //===----------------------------------------------------------------------===//
+// Frontend Options - cc1 + fc1
+//===----------------------------------------------------------------------===//
+let Flags = [CC1Option, FC1Option, NoDriverOption] in {
+let Group = Action_Group in {
+
+def emit_obj : Flag<["-"], "emit-obj">,
+  HelpText<"Emit native object files">;
+
+} // let Group = Action_Group
+} // let Flags = [CC1Option, FC1Option, NoDriverOption]
+
+//===----------------------------------------------------------------------===//
 // cc1as-only Options
 //===----------------------------------------------------------------------===//
 
index 69f0841..bf300d7 100644 (file)
@@ -28,17 +28,22 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
                          const InputInfo &Output, const InputInfoList &Inputs,
                          const ArgList &Args, const char *LinkingOutput) const {
   const auto &TC = getToolChain();
-  const llvm::Triple &Triple = TC.getEffectiveTriple();
-  const std::string &TripleStr = Triple.getTriple();
+  // TODO: Once code-generation is available, this will need to be commented
+  // out.
+  // const llvm::Triple &Triple = TC.getEffectiveTriple();
+  // const std::string &TripleStr = Triple.getTriple();
 
   ArgStringList CmdArgs;
 
+  // Invoke ourselves in -fc1 mode.
   CmdArgs.push_back("-fc1");
 
-  // TODO: Eventually all actions will require a triple (e.g. `-triple
-  // aarch64-unknown-linux-gnu`). However, `-triple` is currently not supported
-  // by `flang-new -fc1`, so we only add it selectively to actions that we
-  // don't support/execute just yet.
+  // TODO: Once code-generation is available, this will need to be commented
+  // out.
+  // Add the "effective" target triple.
+  // CmdArgs.push_back("-triple");
+  // CmdArgs.push_back(Args.MakeArgString(TripleStr));
+
   if (isa<PreprocessJobAction>(JA)) {
     if (C.getArgs().hasArg(options::OPT_test_io))
       CmdArgs.push_back("-test-io");
@@ -61,8 +66,6 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
       assert(false && "Unexpected output type!");
     }
   } else if (isa<AssembleJobAction>(JA)) {
-    CmdArgs.push_back("-triple");
-    CmdArgs.push_back(Args.MakeArgString(TripleStr));
     CmdArgs.push_back("-emit-obj");
   } else {
     assert(false && "Unexpected action class for Flang tool.");
index 3eea94b..9f125e3 100644 (file)
@@ -29,6 +29,10 @@ class ParseSyntaxOnlyAction : public FrontendAction {
   void ExecuteAction() override;
 };
 
+class EmitObjAction : public FrontendAction {
+  void ExecuteAction() override;
+};
+
 } // namespace Fortran::frontend
 
 #endif // LLVM_FLANG_FRONTEND_FRONTENDACTIONS_H
index d167f09..7add145 100644 (file)
@@ -28,6 +28,9 @@ enum ActionKind {
   /// -fsyntax-only
   ParseSyntaxOnly,
 
+  /// Emit a .o file.
+  EmitObj,
+
   /// TODO: RunPreprocessor, EmitLLVM, EmitLLVMOnly,
   /// EmitCodeGenOnly, EmitAssembly, (...)
 };
index df7fe44..57f097f 100644 (file)
@@ -99,9 +99,11 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts,
     case clang::driver::options::OPT_fsyntax_only:
       opts.programAction_ = ParseSyntaxOnly;
       break;
+    case clang::driver::options::OPT_emit_obj:
+      opts.programAction_ = EmitObj;
+      break;
 
       // TODO:
-      // case clang::driver::options::OPT_emit_obj:
       // case calng::driver::options::OPT_emit_llvm:
       // case clang::driver::options::OPT_emit_llvm_only:
       // case clang::driver::options::OPT_emit_codegen_only:
index acb9988..a157935 100644 (file)
@@ -111,3 +111,10 @@ void ParseSyntaxOnlyAction::ExecuteAction() {
     ci.diagnostics().Report(DiagID) << GetCurrentFileOrBufferName();
   }
 }
+
+void EmitObjAction::ExecuteAction() {
+  CompilerInstance &ci = this->instance();
+  unsigned DiagID = ci.diagnostics().getCustomDiagID(
+      clang::DiagnosticsEngine::Error, "code-generation is not available yet");
+  ci.diagnostics().Report(DiagID);
+}
index 0315fd5..50c9fca 100644 (file)
@@ -34,6 +34,8 @@ static std::unique_ptr<FrontendAction> CreateFrontendBaseAction(
     break;
   case ParseSyntaxOnly:
     return std::make_unique<ParseSyntaxOnlyAction>();
+  case EmitObj:
+    return std::make_unique<EmitObjAction>();
     break;
   default:
     break;
diff --git a/flang/test/Flang-Driver/code-gen.f90 b/flang/test/Flang-Driver/code-gen.f90
new file mode 100644 (file)
index 0000000..53a1a52
--- /dev/null
@@ -0,0 +1,15 @@
+! RUN: not %flang-new %s 2>&1 | FileCheck %s --check-prefix=ERROR
+! RUN: not %flang-new -c %s 2>&1 | FileCheck %s --check-prefix=ERROR
+! RUN: not %flang-new -emit-obj %s 2>&1 | FileCheck %s --check-prefix=ERROR
+! RUN: not %flang-new -fc1 -emit-obj %s 2>&1 | FileCheck %s --check-prefix=ERROR
+
+! REQUIRES: new-flang-driver
+
+! Although code-generation is not yet available, we do have frontend actions
+! that correspond to `-c` and `-emit-obj`. For now these actions are just a
+! placeholder and running them leads to a driver error. This test makes sure
+! that these actions are indeed run (rather than `-c` or `-emit-obj` being
+! rejected earlier).
+! TODO: Replace this file with a proper test once code-generation is available.
+
+! ERROR: code-generation is not available yet
index 2b0e316..c9913ff 100644 (file)
@@ -19,6 +19,7 @@
 ! CHECK-EMPTY:
 ! CHECK-NEXT:OPTIONS:
 ! CHECK-NEXT: -###      Print (but do not run) the commands to run for this compilation
+! CHECK-NEXT: -c        Only run preprocess, compile, and assemble steps
 ! CHECK-NEXT: -D <macro>=<value>     Define <macro> to <value> (or 1 if <value> omitted)
 ! CHECK-NEXT: -E        Only run the preprocessor
 ! CHECK-NEXT: -fcolor-diagnostics    Enable colors in diagnostics
index 6931925..e2fab5c 100644 (file)
@@ -19,6 +19,7 @@
 ! HELP-EMPTY:
 ! HELP-NEXT:OPTIONS:
 ! HELP-NEXT: -###                   Print (but do not run) the commands to run for this compilation
+! HELP-NEXT: -c                     Only run preprocess, compile, and assemble steps
 ! HELP-NEXT: -D <macro>=<value>     Define <macro> to <value> (or 1 if <value> omitted)
 ! HELP-NEXT: -E                     Only run the preprocessor
 ! HELP-NEXT: -fcolor-diagnostics    Enable colors in diagnostics
@@ -35,6 +36,7 @@
 ! HELP-FC1-EMPTY:
 ! HELP-FC1-NEXT:OPTIONS:
 ! HELP-FC1-NEXT: -D <macro>=<value>     Define <macro> to <value> (or 1 if <value> omitted)
+! HELP-FC1-NEXT: -emit-obj Emit native object files
 ! HELP-FC1-NEXT: -E                     Only run the preprocessor
 ! HELP-FC1-NEXT: -help                  Display available options
 ! HELP-FC1-NEXT: -o <file>              Write output to <file>
diff --git a/flang/test/Flang-Driver/emit-obj.f90 b/flang/test/Flang-Driver/emit-obj.f90
deleted file mode 100644 (file)
index 09c1f84..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-! RUN: not %flang-new  %s 2>&1 | FileCheck %s --check-prefix=ERROR
-! RUN: not %flang-new  -emit-obj %s 2>&1 | FileCheck %s --check-prefix=ERROR
-! RUN: not %flang-new  -fc1 -emit-obj %s 2>&1 | FileCheck %s --check-prefix=ERROR-FC1
-
-! REQUIRES: new-flang-driver
-
-! By default (e.g. when no options like `-E` are passed) flang-new
-! creates a job that corresponds to `-emit-obj`. This option/action is
-! not yet supported. Verify that this is correctly reported as error.
-
-! ERROR: error: unknown argument: '-triple'
-! ERROR: error: unknown argument: '-emit-obj'
-
-! ERROR-FC1: error: unknown argument: '-emit-obj'
diff --git a/flang/test/Flang-Driver/phases.f90 b/flang/test/Flang-Driver/phases.f90
new file mode 100644 (file)
index 0000000..62c54c7
--- /dev/null
@@ -0,0 +1,20 @@
+! RUN: %flang-new -E -ccc-print-phases %s 2>&1 | FileCheck %s --check-prefix=PP
+! RUN: %flang-new -fsyntax-only -ccc-print-phases %s 2>&1 | FileCheck %s --check-prefix=COMPILE
+! RUN: %flang-new -c -ccc-print-phases %s 2>&1 | FileCheck %s --check-prefix=EMIT_OBJ
+
+! REQUIRES: new-flang-driver
+
+! This test verifies the phase control in Flang compiler driver.
+
+! PP: +- 0: input, "{{.*}}phases.f90", f95-cpp-input
+! PP-NEXT: 1: preprocessor, {0}, f95
+
+! COMPILE: +- 0: input, "{{.*}}phases.f90", f95-cpp-input
+! COMPILE-NEXT: 1: preprocessor, {0}, f95
+! COMPILE-NEXT: 2: compiler, {1}, none
+
+! EMIT_OBJ: +- 0: input, "{{.*}}phases.f90", f95-cpp-input
+! EMIT_OBJ-NEXT: 1: preprocessor, {0}, f95
+! EMIT_OBJ-NEXT: 2: compiler, {1}, ir
+! EMIT_OBJ-NEXT: +- 3: backend, {2}, assembler
+! EMIT_OBJ-NEXT: 4: assembler, {3}, object