skatrak created this revision.
skatrak added reviewers: gregrodgers, dpalermo, domada, jsjodin, agozillon, 
kiranchandramohan, awarzynski.
Herald added subscribers: sunshaoce, bzcheeseman, rriddle, guansong, yaxunl.
Herald added a reviewer: sscalpone.
Herald added projects: Flang, All.
skatrak requested review of this revision.
Herald added subscribers: cfe-commits, sstefan1, stephenneuendorffer, 
jdoerfert, MaskRay.
Herald added a reviewer: jdoerfert.
Herald added a project: clang.

This patch adds support for producing MLIR files when using -save-temps on
flang. One MLIR file will be produced before lowering and optimization passes,
containing the operations produced by the PFT-to-MLIR lowering bridge, and
another at the end of the process, just before LLVM IR generation.

This is accomplished by forwarding the -save-temps flag from the driver to the
frontend, and modifying it to output MLIR files accordingly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146075

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Flang.cpp
  flang/include/flang/Frontend/CodeGenOptions.h
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendActions.cpp
  flang/test/Driver/driver-help.f90

Index: flang/test/Driver/driver-help.f90
===================================================================
--- flang/test/Driver/driver-help.f90
+++ flang/test/Driver/driver-help.f90
@@ -170,6 +170,8 @@
 ! HELP-FC1-NEXT: -pic-level <value>      Value for __PIC__
 ! HELP-FC1-NEXT: -plugin <name>         Use the named plugin action instead of the default action (use "help" to list available options)
 ! HELP-FC1-NEXT: -P                     Disable linemarker output in -E mode
+! HELP-FC1-NEXT: -save-temps=<value>    Save intermediate compilation results.
+! HELP-FC1-NEXT: -save-temps            Save intermediate compilation results
 ! HELP-FC1-NEXT: -std=<value>           Language standard to compile for
 ! HELP-FC1-NEXT: -S                     Only run preprocess and compilation steps
 ! HELP-FC1-NEXT: -target-cpu <value>    Target a specific cpu type
Index: flang/lib/Frontend/FrontendActions.cpp
===================================================================
--- flang/lib/Frontend/FrontendActions.cpp
+++ flang/lib/Frontend/FrontendActions.cpp
@@ -13,6 +13,7 @@
 #include "flang/Frontend/FrontendActions.h"
 #include "flang/Common/default-kinds.h"
 #include "flang/Frontend/CompilerInstance.h"
+#include "flang/Frontend/CompilerInvocation.h"
 #include "flang/Frontend/FrontendOptions.h"
 #include "flang/Frontend/PreprocessorOptions.h"
 #include "flang/Lower/Bridge.h"
@@ -52,10 +53,14 @@
 #include "llvm/Passes/PassPlugin.h"
 #include "llvm/Passes/StandardInstrumentations.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
+#include <llvm/Support/Path.h>
 #include <memory>
+#include <system_error>
 
 using namespace Fortran::frontend;
 
@@ -64,6 +69,52 @@
   llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
 #include "llvm/Support/Extension.def"
 
+namespace {
+
+/// Save the given \c mlirModule to a temporary .mlir file, in a location
+/// decided by the -save-temps flag. No files are produced if the flag is not
+/// specified.
+bool saveMLIRTempFile(const CompilerInvocation &ci, mlir::ModuleOp mlirModule,
+                      llvm::StringRef inputFile, llvm::StringRef outputTag) {
+  if (!ci.getCodeGenOpts().SaveTempsDir.has_value()) {
+    return true;
+  }
+
+  const std::string &compilerOutFile = ci.getFrontendOpts().outputFile;
+  const std::string &dir = ci.getCodeGenOpts().SaveTempsDir.value();
+  std::string outDir =
+      llvm::StringSwitch<std::string>(dir)
+          .Case("cwd", "")
+          .Case("obj", llvm::sys::path::parent_path(compilerOutFile).str())
+          .Default(dir);
+
+  if (llvm::sys::fs::is_directory(outDir)) {
+    outDir.append("/");
+  }
+
+  // Build file name from the compiler output file name, triple, cpu and OpenMP
+  // information
+  llvm::StringRef input = llvm::sys::path::filename(inputFile);
+  std::string outFile = input.substr(0, input.find_last_of('.'))
+                            .str()
+                            .append("-")
+                            .append(outputTag.str())
+                            .append(".mlir");
+
+  std::error_code ec;
+  llvm::ToolOutputFile out(outDir + outFile, ec, llvm::sys::fs::OF_Text);
+  if (ec) {
+    return false;
+  }
+  mlirModule->print(out.os());
+  out.os().close();
+  out.keep();
+
+  return true;
+}
+
+} // namespace
+
 //===----------------------------------------------------------------------===//
 // Custom BeginSourceFileAction
 //===----------------------------------------------------------------------===//
@@ -206,6 +257,15 @@
     return false;
   }
 
+  // FIR.mlir: This is 1st -save-temps file created for mlir
+  if (!saveMLIRTempFile(ci.getInvocation(), *mlirModule, getCurrentFile(),
+                        "FIR")) {
+    unsigned diagID = ci.getDiagnostics().getCustomDiagID(
+        clang::DiagnosticsEngine::Error, "Saving MLIR temp file failed");
+    ci.getDiagnostics().Report(diagID);
+    return false;
+  }
+
   return true;
 }
 
@@ -563,6 +623,15 @@
     ci.getDiagnostics().Report(diagID);
   }
 
+  // LLVMIR.mlir: This is 2nd -save-temps file created for mlir
+  if (!saveMLIRTempFile(ci.getInvocation(), *mlirModule, getCurrentFile(),
+                        "LLVMIR")) {
+    unsigned diagID = ci.getDiagnostics().getCustomDiagID(
+        clang::DiagnosticsEngine::Error, "Saving MLIR temp file failed");
+    ci.getDiagnostics().Report(diagID);
+    return;
+  }
+
   // Translate to LLVM IR
   std::optional<llvm::StringRef> moduleName = mlirModule->getName();
   llvmModule = mlir::translateModuleToLLVMIR(
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- flang/lib/Frontend/CompilerInvocation.cpp
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -150,6 +150,9 @@
       opts.PrepareForThinLTO = true;
   }
 
+  if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ))
+    opts.SaveTempsDir = a->getValue();
+
   // -mrelocation-model option.
   if (const llvm::opt::Arg *a =
           args.getLastArg(clang::driver::options::OPT_mrelocation_model)) {
Index: flang/include/flang/Frontend/CodeGenOptions.h
===================================================================
--- flang/include/flang/Frontend/CodeGenOptions.h
+++ flang/include/flang/Frontend/CodeGenOptions.h
@@ -21,6 +21,7 @@
 #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -53,6 +54,9 @@
   /// are offloading binaries containing device images and metadata.
   std::vector<std::string> OffloadObjects;
 
+  /// The directory where temp files are stored if specified by -save-temps
+  std::optional<std::string> SaveTempsDir;
+
   // Define accessors/mutators for code generation options of enumeration type.
 #define CODEGENOPT(Name, Bits, Default)
 #define ENUM_CODEGENOPT(Name, Type, Bits, Default)                             \
Index: clang/lib/Driver/ToolChains/Flang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Flang.cpp
+++ clang/lib/Driver/ToolChains/Flang.cpp
@@ -370,6 +370,9 @@
 
   assert(Input.isFilename() && "Invalid input.");
 
+  if (Args.getLastArg(options::OPT_save_temps_EQ))
+    Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ);
+
   addDashXForInput(Args, Input, CmdArgs);
 
   CmdArgs.push_back(Input.getFilename());
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4266,9 +4266,9 @@
   Alias<frtlib_add_rpath>;
 def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>,
         Group<Link_Group>;
-def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[CC1Option, FlangOption, NoXarchOption]>,
+def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[CC1Option, FlangOption, FC1Option, NoXarchOption]>,
   HelpText<"Save intermediate compilation results.">;
-def save_temps : Flag<["-", "--"], "save-temps">, Flags<[FlangOption, NoXarchOption]>,
+def save_temps : Flag<["-", "--"], "save-temps">, Flags<[FlangOption, FC1Option, NoXarchOption]>,
   Alias<save_temps_EQ>, AliasArgs<["cwd"]>,
   HelpText<"Save intermediate compilation results">;
 def save_stats_EQ : Joined<["-", "--"], "save-stats=">, Flags<[NoXarchOption]>,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to