xur updated this revision to Diff 45929.
xur marked an inline comment as done.
xur added a comment.

Here is the new patch. Changes from previous patch are:
(1) rename codegen option ProfileInstrGenerate to ClangProfInstrGen to avoid 
the name confusion (Davidxl). This option is for clang instrumentation only.
(2) improve the test suggested by Sean.
(3) move the logic of checking if argument ProfileIRInstr needs to be added to 
Tools.C (suggested by Chad and Sean). This still does not look very clean -- I 
need to manually expand the -Xclang option for this. The difficulty here is 
that we have shared driver level arguments (-fprofile-generate and 
-fprofile-use etc) and there is no cc1 option for clang instrumentation. Once 
we have driver level option for IR level instrumentation, the code can be 
improved.


http://reviews.llvm.org/D15829

Files:
  include/clang/Driver/CC1Options.td
  include/clang/Frontend/CodeGenOptions.def
  lib/CodeGen/BackendUtil.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenPGO.cpp
  lib/Driver/Tools.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/pgotest.profraw
  test/CodeGen/pgo-instrumentation.c

Index: test/CodeGen/pgo-instrumentation.c
===================================================================
--- /dev/null
+++ test/CodeGen/pgo-instrumentation.c
@@ -0,0 +1,23 @@
+// Test if PGO instrumentation and use pass are invoked.
+//
+// Ensure Pass PGOInstrumentationGenPass is invoked.
+// RUN: %clang -O2 -c -Xclang -fprofile-ir-instr -fprofile-instr-generate %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-V1
+// CHECK-PGOGENPASS-INVOKED-V1: PGOInstrumentationGenPass
+//
+// Ensure Pass PGOInstrumentationGenPass is invoked.
+// RUN: %clang -O2 -c -Xclang -fprofile-ir-instr -fprofile-generate %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-V2
+// CHECK-PGOGENPASS-INVOKED-V2: PGOInstrumentationGenPass
+//
+// Ensure Pass PGOInstrumentationUsePass is invoked.
+// RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotest.profraw
+// RUN: %clang -O2 -c -Xclang -fprofile-ir-instr -fprofile-instr-use=%t.profdata %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-V1
+// CHECK-PGOUSEPASS-INVOKED-V1: PGOInstrumentationUsePass
+//
+// Ensure Pass PGOInstrumentationUsePass is invoked.
+// RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotest.profraw
+// RUN: %clang -O2 -c -Xclang -fprofile-ir-instr -fprofile-use=%t.profdata %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-V2
+// CHECK-PGOUSEPASS-INVOKED-V2: PGOInstrumentationUsePass
+//
+// Ensure cc1 option -fprofile-ir-instr is null operation without existing pgo options.
+// RUN: %clang -O2 -c -Xclang -fprofile-ir-instr %s -mllvm -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=CHECK-PGOPASS-INVOKED
+// CHECK-PGOPASS-INVOKED-NOT: PGOInstrumentation{Gen|USE}Pass
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -477,8 +477,13 @@
   Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as);
   Opts.Autolink = !Args.hasArg(OPT_fno_autolink);
   Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
-  Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate) ||
-      Args.hasArg(OPT_fprofile_instr_generate_EQ);
+  if (Args.hasArg(OPT_fprofile_ir_instr))
+    // Set ProfileIRInstr when there are profile generate or use options.
+    Opts.ProfileIRInstr = true;
+  else
+    // Opts.ClangProfInstrGen will be used for Clang instrumentation only.
+    Opts.ClangProfInstrGen = Args.hasArg(OPT_fprofile_instr_generate) ||
+                             Args.hasArg(OPT_fprofile_instr_generate_EQ);
   Opts.InstrProfileOutput = Args.getLastArgValue(OPT_fprofile_instr_generate_EQ);
   Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
   Opts.CoverageMapping =
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -5514,7 +5514,20 @@
 
   // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
   // parser.
-  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
+  //Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
+  for (const Arg *A : Args.filtered(options::OPT_Xclang)) {
+    A->claim();
+    if ((StringRef(A->getValue(0)) == "-fprofile-ir-instr") &&
+        (Args.hasArg(options::OPT_fprofile_instr_generate) ||
+         Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
+         Args.hasArg(options::OPT_fprofile_generate) ||
+         Args.hasArg(options::OPT_fprofile_generate_EQ) ||
+         Args.hasArg(options::OPT_fprofile_instr_use) ||
+         Args.hasArg(options::OPT_fprofile_instr_use_EQ) ||
+         Args.hasArg(options::OPT_fprofile_use) ||
+         Args.hasArg(options::OPT_fprofile_use_EQ)))
+      CmdArgs.push_back("-fprofile-ir-instr");
+  }
   for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
     A->claim();
 
Index: lib/CodeGen/CodeGenPGO.cpp
===================================================================
--- lib/CodeGen/CodeGenPGO.cpp
+++ lib/CodeGen/CodeGenPGO.cpp
@@ -34,7 +34,7 @@
       PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
 
   // If we're generating a profile, create a variable for the name.
-  if (CGM.getCodeGenOpts().ProfileInstrGenerate)
+  if (CGM.getCodeGenOpts().ClangProfInstrGen)
     FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
 }
 
@@ -607,7 +607,7 @@
 
 void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
   const Decl *D = GD.getDecl();
-  bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
+  bool InstrumentRegions = CGM.getCodeGenOpts().ClangProfInstrGen;
   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
   if (!InstrumentRegions && !PGOReader)
     return;
@@ -726,7 +726,7 @@
 }
 
 void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) {
-  if (!CGM.getCodeGenOpts().ProfileInstrGenerate || !RegionCounterMap)
+  if (!CGM.getCodeGenOpts().ClangProfInstrGen || !RegionCounterMap)
     return;
   if (!Builder.GetInsertBlock())
     return;
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -147,7 +147,7 @@
   if (C.getLangOpts().ObjC1)
     ObjCData = new ObjCEntrypoints();
 
-  if (!CodeGenOpts.InstrProfileInput.empty()) {
+  if (!CodeGenOpts.ProfileIRInstr && !CodeGenOpts.InstrProfileInput.empty()) {
     auto ReaderOrErr =
         llvm::IndexedInstrProfReader::create(CodeGenOpts.InstrProfileInput);
     if (std::error_code EC = ReaderOrErr.getError()) {
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -952,7 +952,7 @@
 public:
   /// Increment the profiler's counter for the given statement.
   void incrementProfileCounter(const Stmt *S) {
-    if (CGM.getCodeGenOpts().ProfileInstrGenerate)
+    if (CGM.getCodeGenOpts().ClangProfInstrGen)
       PGO.emitCounterIncrement(Builder, S);
     PGO.setCurrentStmt(S);
   }
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -883,7 +883,7 @@
 void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
                                                const Stmt *S) {
   llvm::BasicBlock *SkipCountBB = nullptr;
-  if (HaveInsertPoint() && CGM.getCodeGenOpts().ProfileInstrGenerate) {
+  if (HaveInsertPoint() && CGM.getCodeGenOpts().ClangProfInstrGen) {
     // When instrumenting for profiling, the fallthrough to certain
     // statements needs to skip over the instrumentation code so that we
     // get an accurate count.
Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp
+++ lib/CodeGen/CGStmt.cpp
@@ -1153,7 +1153,7 @@
   // If the body of the case is just a 'break', try to not emit an empty block.
   // If we're profiling or we're not optimizing, leave the block in for better
   // debug and coverage analysis.
-  if (!CGM.getCodeGenOpts().ProfileInstrGenerate &&
+  if (!CGM.getCodeGenOpts().ClangProfInstrGen &&
       CGM.getCodeGenOpts().OptimizationLevel > 0 &&
       isa<BreakStmt>(S.getSubStmt())) {
     JumpDest Block = BreakContinueStack.back().BreakBlock;
@@ -1200,7 +1200,7 @@
 
     if (SwitchWeights)
       SwitchWeights->push_back(getProfileCount(NextCase));
-    if (CGM.getCodeGenOpts().ProfileInstrGenerate) {
+    if (CGM.getCodeGenOpts().ClangProfInstrGen) {
       CaseDest = createBasicBlock("sw.bb");
       EmitBlockWithFallThrough(CaseDest, &S);
     }
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -429,13 +429,25 @@
       MPM->add(createStripSymbolsPass(true));
   }
 
-  if (CodeGenOpts.ProfileInstrGenerate) {
+  if (CodeGenOpts.ClangProfInstrGen) {
     InstrProfOptions Options;
     Options.NoRedZone = CodeGenOpts.DisableRedZone;
     Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
     MPM->add(createInstrProfilingPass(Options));
   }
 
+  if (CodeGenOpts.ProfileIRInstr) {
+    // Should not have ClangProfInstrGen set -- it is for clang
+    // instrumentation only.
+    assert (!CodeGenOpts.ClangProfInstrGen);
+    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())
     MPM->add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile));
 
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ include/clang/Frontend/CodeGenOptions.def
@@ -103,8 +103,9 @@
 VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
 VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
 
-CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate
-                                        ///< execution counts to use with PGO.
+CODEGENOPT(ClangProfInstrGen, 1, 0) ///< Clang Instrumentation to generate
+                                    ///< execution counts to use with PGO.
+CODEGENOPT(ProfileIRInstr, 1, 0) ///< IR level PGO instrumentation and use.
 CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to
                                    ///< enable code coverage analysis.
 CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -268,6 +268,9 @@
 def fsanitize_coverage_8bit_counters
     : Flag<["-"], "fsanitize-coverage-8bit-counters">,
       HelpText<"Enable frequency counters in sanitizer coverage">;
+def fprofile_ir_instr : Flag<["-"], "fprofile-ir-instr">,
+    HelpText<"Use IR level instrumentation rather the FE implementation">;
+
 
 //===----------------------------------------------------------------------===//
 // Dependency Output Options
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to