Reland "[Remarks] Add -foptimization-record-passes to filter remark emission"

Currently we have -Rpass for filtering the remarks that are displayed as
diagnostics, but when using -fsave-optimization-record, there is no way
to filter the remarks while generating them.

This adds support for filtering remarks by passes using a regex.
Ex: `clang -fsave-optimization-record -foptimization-record-passes=inline`

will only emit the remarks coming from the pass `inline`.

This adds:

* `-fsave-optimization-record` to the driver
* `-opt-record-passes` to cc1
* `-lto-pass-remarks-filter` to the LTOCodeGenerator
* `--opt-remarks-passes` to lld
* `-pass-remarks-filter` to llc, opt, llvm-lto, llvm-lto2
* `-opt-remarks-passes` to gold-plugin

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

Original llvm-svn: 355964

llvm-svn: 355984
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index fbf78b0..dc61ff9 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -205,8 +205,9 @@
   /// Statistics output filename.
   static std::string stats_file;
 
-  // Optimization remarks filename and hotness options
+  // Optimization remarks filename, accepted passes and hotness options
   static std::string OptRemarksFilename;
+  static std::string OptRemarksFilter;
   static bool OptRemarksWithHotness = false;
 
   // Context sensitive PGO options.
@@ -285,6 +286,8 @@
       dwo_dir = opt.substr(strlen("dwo_dir="));
     } else if (opt.startswith("opt-remarks-filename=")) {
       OptRemarksFilename = opt.substr(strlen("opt-remarks-filename="));
+    } else if (opt.startswith("opt-remarks-passes=")) {
+      OptRemarksFilter = opt.substr(strlen("opt-remarks-passes="));
     } else if (opt == "opt-remarks-with-hotness") {
       OptRemarksWithHotness = true;
     } else if (opt.startswith("stats-file=")) {
@@ -908,6 +911,7 @@
 
   // Set up optimization remarks handling.
   Conf.RemarksFilename = options::OptRemarksFilename;
+  Conf.RemarksPasses = options::OptRemarksFilter;
   Conf.RemarksWithHotness = options::OptRemarksWithHotness;
 
   // Use new pass manager if set in driver
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index a566d15..be10384 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -148,6 +148,12 @@
                     cl::desc("YAML output filename for pass remarks"),
                     cl::value_desc("filename"));
 
+static cl::opt<std::string>
+    RemarksPasses("pass-remarks-filter",
+                  cl::desc("Only record optimization remarks from passes whose "
+                           "names match the given regular expression"),
+                  cl::value_desc("regex"));
+
 namespace {
 static ManagedStatic<std::vector<std::string>> RunPassNames;
 
@@ -336,6 +342,12 @@
     }
     Context.setRemarkStreamer(
         llvm::make_unique<RemarkStreamer>(RemarksFilename, YamlFile->os()));
+
+    if (!RemarksPasses.empty())
+      if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
+        WithColor::error(errs(), argv[0]) << E << '\n';
+        return 1;
+      }
   }
 
   if (InputLanguage != "" && InputLanguage != "ir" &&
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 6cceb8e..df51921 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -101,6 +101,12 @@
              "Has effect only if -pass-remarks-output is specified."));
 
 static cl::opt<std::string>
+    OptRemarksPasses("pass-remarks-filter",
+                     cl::desc("Only record optimization remarks from passes "
+                              "whose names match the given regular expression"),
+                     cl::value_desc("regex"));
+
+static cl::opt<std::string>
     SamplePGOFile("lto-sample-profile-file",
                   cl::desc("Specify a SamplePGO profile file"));
 
@@ -220,6 +226,7 @@
 
   // Optimization remarks.
   Conf.RemarksFilename = OptRemarksOutput;
+  Conf.RemarksPasses = OptRemarksPasses;
   Conf.RemarksWithHotness = OptRemarksWithHotness;
 
   Conf.SampleProfile = SamplePGOFile;
diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp
index 06745b0..b4c39e2 100644
--- a/llvm/tools/opt/opt.cpp
+++ b/llvm/tools/opt/opt.cpp
@@ -275,6 +275,12 @@
                     cl::desc("YAML output filename for pass remarks"),
                     cl::value_desc("filename"));
 
+static cl::opt<std::string>
+    RemarksPasses("pass-remarks-filter",
+                  cl::desc("Only record optimization remarks from passes whose "
+                           "names match the given regular expression"),
+                  cl::value_desc("regex"));
+
 cl::opt<PGOKind>
     PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
                 cl::desc("The kind of profile guided optimization"),
@@ -566,6 +572,12 @@
     }
     Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
         RemarksFilename, OptRemarkFile->os()));
+
+    if (!RemarksPasses.empty())
+      if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
+        errs() << E << '\n';
+        return 1;
+      }
   }
 
   // Load the input module...