xur updated this revision to Diff 46960.
xur added a comment.

Now http://reviews.llvm.org/D16730 has been committed (as r259811)

Here is the patch that adds cc1 option -fprofile-instrument=llvm to enable IR 
level PGO generate and use.

The pgo use part of the patch depends http://reviews.llvm.org/D15540 which 
differentiates the IR level and clang profiles. To detect the profile 
automatically, we need to first the profile. It can either done in driver or in 
Clang codegen (lib/CodeGen/CodeGenModule.cpp). If we do this in Clang codegen, 
we would have to change the Codegen option which does not seem to be a good 
approach. As a result, we do this in the driver in this patch.

Again like in http://reviews.llvm.org/D16730, this patch won't change any 
driver (user level) options. Only cc1 options are touched.

Thanks,

-Rong


http://reviews.llvm.org/D15829

Files:
  include/clang/Driver/CC1Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Driver/CMakeLists.txt
  lib/Driver/Tools.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/pgotestclang.profraw
  test/CodeGen/Inputs/pgotestir.profraw
  test/CodeGen/pgo-instrumentation.c

Index: test/CodeGen/pgo-instrumentation.c
===================================================================
--- test/CodeGen/pgo-instrumentation.c
+++ test/CodeGen/pgo-instrumentation.c
@@ -0,0 +1,28 @@
+// Test if PGO instrumentation and use pass are invoked.
+//
+// Ensure Pass PGOInstrumentationGenPass is invoked.
+// RUN: %clang -O2 -c -Xclang -fprofile-instrument=llvm -fprofile-instr-generate %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN
+// CHECK-PGOGENPASS-INVOKED-INSTR-GEN: PGOInstrumentationGenPass
+//
+// Ensure Pass PGOInstrumentationGenPass is invoked.
+// RUN: %clang -O2 -c -Xclang -fprofile-instrument=llvm -fprofile-generate %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-GEN
+// CHECK-PGOGENPASS-INVOKED-GEN: PGOInstrumentationGenPass
+//
+// Ensure Pass PGOInstrumentationGenPass is not invoked.
+// RUN: %clang -O2 -c -Xclang -fprofile-instrument=clang -fprofile-instr-generate %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN-CLANG
+// CHECK-PGOGENPASS-INVOKED-INSTR-GEN-CLANG-NOT: PGOInstrumentationGenPass
+//
+// Ensure Pass PGOInstrumentationUsePass is invoked.
+// RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotestir.profraw
+// RUN: %clang -O2 -c -Xclang -fprofile-instrument=llvm -fprofile-instr-use=%t.profdata %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE
+// CHECK-PGOUSEPASS-INVOKED-INSTR-USE: PGOInstrumentationUsePass
+//
+// Ensure Pass PGOInstrumentationUsePass is invoked.
+// RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotestir.profraw
+// RUN: %clang -O2 -c -Xclang -fprofile-instrument=llvm -fprofile-use=%t.profdata %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE
+// CHECK-PGOUSEPASS-INVOKED-USE: PGOInstrumentationUsePass
+//
+// Ensure Pass PGOInstrumentationUsePass is not invoked.
+// RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotestclang.profraw
+// RUN: %clang -O2 -c -Xclang -fprofile-instrument=clang -fprofile-use=%t.profdata %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE-CLANG
+// CHECK-PGOUSEPASS-INVOKED-USE-CLANG-NOT: PGOInstrumentationUsePass
Index: test/CodeGen/Inputs/pgotestir.profraw
===================================================================
--- test/CodeGen/Inputs/pgotestir.profraw
+++ test/CodeGen/Inputs/pgotestir.profraw
@@ -0,0 +1 @@
+:ir
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -478,14 +478,18 @@
   Opts.Autolink = !Args.hasArg(OPT_fno_autolink);
   Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
 
-  enum PGOInstrumentor { Unknown, None, Clang };
+  enum PGOInstrumentor { Unknown, None, Clang, LLVM };
   if (Arg *A = Args.getLastArg(OPT_fprofile_instrument_EQ)) {
     StringRef Value = A->getValue();
     PGOInstrumentor Method = llvm::StringSwitch<PGOInstrumentor>(Value)
-                                 .Case("clang", Clang)
                                  .Case("none", None)
+                                 .Case("clang", Clang)
+                                 .Case("llvm", LLVM)
                                  .Default(Unknown);
     switch (Method) {
+    case LLVM:
+      Opts.setProfileInstr(CodeGenOptions::ProfileIRInstr);
+      break;
     case Clang:
       Opts.setProfileInstr(CodeGenOptions::ProfileClangInstr);
       break;
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -32,6 +32,7 @@
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
+#include "llvm/ProfileData/InstrProfReader.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -3196,6 +3197,18 @@
   return VersionTuple();
 }
 
+// Set the profile kind if it's not the default clang kind.
+static void setProfileKindFlag(ArgStringList &CmdArgs,
+                               std::string ProfileName) {
+  auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName);
+  if (ReaderOrErr.getError())
+    return;
+  std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader =
+    std::move(ReaderOrErr.get());
+  if (PGOReader->isIRLevelProfile())
+    CmdArgs.push_back("-fprofile-instrument=llvm");
+}
+
 static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
                                    const InputInfo &Output, const ArgList &Args,
                                    ArgStringList &CmdArgs) {
@@ -3238,8 +3251,10 @@
   }
 
   if (ProfileUseArg) {
-    if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
+    if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ)) {
       ProfileUseArg->render(Args, CmdArgs);
+      setProfileKindFlag(CmdArgs, ProfileUseArg->getValue());
+    }
     else if ((ProfileUseArg->getOption().matches(
                   options::OPT_fprofile_use_EQ) ||
               ProfileUseArg->getOption().matches(
@@ -3250,6 +3265,7 @@
         llvm::sys::path::append(Path, "default.profdata");
       CmdArgs.push_back(
           Args.MakeArgString(Twine("-fprofile-instr-use=") + Path));
+      setProfileKindFlag(CmdArgs, Path.str().str());
     }
   }
 
Index: lib/Driver/CMakeLists.txt
===================================================================
--- lib/Driver/CMakeLists.txt
+++ lib/Driver/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(LLVM_LINK_COMPONENTS
   Option
   Support
+  ProfileData
   )
 
 add_clang_library(clangDriver
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -146,7 +146,8 @@
   if (C.getLangOpts().ObjC1)
     ObjCData = new ObjCEntrypoints();
 
-  if (!CodeGenOpts.InstrProfileInput.empty()) {
+  if (!CodeGenOpts.hasProfileIRInstr() &&
+      !CodeGenOpts.InstrProfileInput.empty()) {
     auto ReaderOrErr =
         llvm::IndexedInstrProfReader::create(CodeGenOpts.InstrProfileInput);
     if (std::error_code EC = ReaderOrErr.getError()) {
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -434,6 +434,13 @@
     Options.NoRedZone = CodeGenOpts.DisableRedZone;
     Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
     MPM->add(createInstrProfilingPass(Options));
+  } else if (CodeGenOpts.hasProfileIRInstr()) {
+    if (!CodeGenOpts.InstrProfileInput.empty())
+      PMBuilder.PGOInstrUse = CodeGenOpts.InstrProfileInput;
+    else if (!CodeGenOpts.InstrProfileOutput.empty())
+      PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput;
+    else
+      PMBuilder.PGOInstrGen = "default.profraw";
   }
 
   if (!CodeGenOpts.SampleProfileFile.empty())
Index: include/clang/Frontend/CodeGenOptions.h
===================================================================
--- include/clang/Frontend/CodeGenOptions.h
+++ include/clang/Frontend/CodeGenOptions.h
@@ -87,8 +87,9 @@
 
   enum ProfileInstrKind {
     ProfileNoInstr,    // No instrumentation.
-    ProfileClangInstr  // Clang instrumentation to generate execution counts
+    ProfileClangInstr, // Clang instrumentation to generate execution counts
                        // to use with PGO.
+    ProfileIRInstr     // IR level PGO instrumentation in LLVM.
   };
 
   /// The code model to use (-mcmodel).
@@ -229,6 +230,11 @@
   bool hasProfileClangInstr() const {
     return getProfileInstr() == ProfileClangInstr;
   }
+
+  /// \brief Check if IR profile instrumenation is on.
+  bool hasProfileIRInstr() const {
+    return getProfileInstr() == ProfileIRInstr;
+  }
 };
 
 }  // end namespace clang
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -269,8 +269,8 @@
     : Flag<["-"], "fsanitize-coverage-8bit-counters">,
       HelpText<"Enable frequency counters in sanitizer coverage">;
 def fprofile_instrument_EQ: Joined<["-"], "fprofile-instrument=">,
-    HelpText<"Enable PGO instrumentation. The accepted values is clang or "
-             "none">;
+    HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, "
+             "or none">;
 def fprofile_instrument_path_EQ: Joined<["-"], "fprofile-instrument-path=">,
     HelpText<"Generate instrumented code to collect execution counts into "
              "<file> (overridden by LLVM_PROFILE_FILE env var)">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to