gollvm: initial support for -fsave-optimization-record

Add support for the -fsave-optimization-record command line option,
which directs the back end to save a transcript of interesting
optimization decisions (functions inlined, loops vectorized, etc).

Change-Id: Ib0fb85c4c23e57a00f6dbbeb0326acaf5672e66f
Reviewed-on: https://go-review.googlesource.com/c/157241
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/driver/CompileGo.cpp b/driver/CompileGo.cpp
index a9d30a5..9eeca21 100644
--- a/driver/CompileGo.cpp
+++ b/driver/CompileGo.cpp
@@ -106,6 +106,7 @@
   std::vector<std::string> inputFileNames_;
   std::string asmOutFileName_;
   std::unique_ptr<ToolOutputFile> asmout_;
+  std::unique_ptr<ToolOutputFile> optRecordFile_;
   std::unique_ptr<TargetLibraryInfoImpl> tlii_;
   std::string targetCpuAttr_;
   std::string targetFeaturesAttr_;
@@ -371,6 +372,33 @@
     }
   }
 
+  // Capture optimization record.
+  opt::Arg *optrecordarg =
+      args_.getLastArg(gollvm::options::OPT_fsave_optimization_record,
+                       gollvm::options::OPT_fno_save_optimization_record,
+                       gollvm::options::OPT_foptimization_record_file_EQ);
+  if (optrecordarg && !optrecordarg->getOption().matches(
+          gollvm::options::OPT_fno_save_optimization_record)) {
+    opt::Arg *fnamearg =
+        args_.getLastArg(gollvm::options::OPT_foptimization_record_file_EQ);
+    if (fnamearg != nullptr) {
+      StringRef fname = fnamearg->getValue();
+      std::error_code EC;
+      optRecordFile_ = llvm::make_unique<llvm::ToolOutputFile>(
+          fname, EC, llvm::sys::fs::F_None);
+      if (EC) {
+        errs() << "error: unable to open file '"
+               << fname << "' to emit optimization remarks\n";
+        return false;
+      }
+      context_.setDiagnosticsOutputFile(
+          llvm::make_unique<yaml::Output>(optRecordFile_->os()));
+      if (! sampleProfileFile_.empty())
+        context_.setDiagnosticsHotnessRequested(true);
+      optRecordFile_->keep();
+    }
+  }
+
   TargetOptions Options;
 
   // FIXME: turn off integrated assembler for now.
diff --git a/driver/GollvmOptions.td b/driver/GollvmOptions.td
index b74e61f..70a3ba7 100644
--- a/driver/GollvmOptions.td
+++ b/driver/GollvmOptions.td
@@ -315,7 +315,17 @@
 def fno_debug_info_for_profiling : Flag<["-"], "fno-debug-info-for-profiling">, Group<f_Group>,
     Flags<[DriverOption]>,
     HelpText<"Do not emit extra debug info for sample profiler.">;
-    
+
+def fsave_optimization_record : Flag<["-"], "fsave-optimization-record">,
+    Group<f_Group>, Flags<[DriverOption]>,
+    HelpText<"Generate a YAML optimization record file">;
+def fno_save_optimization_record : Flag<["-"], "fno-save-optimization-record">,
+    Group<f_Group>, Flags<[DriverOption]>,
+    HelpText<"Do not generate a YAML optimization record file">;
+def foptimization_record_file_EQ : Joined<["-"], "foptimization-record-file=">,
+    Group<f_Group>, Flags<[DriverOption]>,
+    HelpText<"Specify the file name of any generated YAML optimization record">;
+
 // Target-dependent "-m" options.
 
 def march_EQ : Joined<["-"], "march=">, Group<m_Group>;