xur updated this revision to Diff 46199.
xur added a comment.
This new version implemented the usage model David proposed. We now have a cc1
option -fprofile-instrumentor={llvm | clang} to choose which instrumentation to
use. The slight difference from David's proposal is that we can use this option
with -fprofile-instr-use.
Thanks,
-Rong
http://reviews.llvm.org/D15829
Files:
include/clang/Basic/DiagnosticDriverKinds.td
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/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,28 @@
+// Test if PGO instrumentation and use pass are invoked.
+//
+// Ensure Pass PGOInstrumentationGenPass is invoked.
+// RUN: %clang -O2 -c -Xclang -fprofile-instrumentor=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-instrumentor=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-instrumentor=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/pgotest.profraw
+// RUN: %clang -O2 -c -Xclang -fprofile-instrumentor=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/pgotest.profraw
+// RUN: %clang -O2 -c -Xclang -fprofile-instrumentor=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/pgotest.profraw
+// RUN: %clang -O2 -c -Xclang -fprofile-instrumentor=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: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -477,8 +477,28 @@
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);
+
+ enum PGOInstrumentor { Unknown, Clang, LLVM };
+ if (Arg *A = Args.getLastArg(OPT_fprofile_instrumentor_EQ)) {
+ StringRef Value = A->getValue();
+ PGOInstrumentor Method = llvm::StringSwitch<PGOInstrumentor>(Value)
+ .Case("clang", Clang)
+ .Case("llvm", LLVM)
+ .Default(Unknown);
+ if (Method == Unknown)
+ Diags.Report(diag::err_drv_invalid_pgo_instrumentor)
+ << A->getAsString(Args) << Value;
+ else {
+ Opts.ProfileIRInstr = (Method == LLVM);
+ Opts.ProfileClangInstr = (Method == Clang);
+ }
+ } else {
+ // Default PGO instrumentor is Clang instrumentation.
+ Opts.ProfileClangInstr = Args.hasArg(OPT_fprofile_instr_generate) ||
+ Args.hasArg(OPT_fprofile_instr_generate_EQ);
+ Opts.ProfileIRInstr = false;
+ }
+
Opts.InstrProfileOutput = Args.getLastArgValue(OPT_fprofile_instr_generate_EQ);
Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
Opts.CoverageMapping =
Index: lib/CodeGen/CodeGenPGO.cpp
===================================================================
--- lib/CodeGen/CodeGenPGO.cpp
+++ lib/CodeGen/CodeGenPGO.cpp
@@ -37,7 +37,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().ProfileClangInstr)
FuncNameVar = llvm::createPGOFuncNameVar(CGM.getModule(), Linkage, FuncName);
}
@@ -610,7 +610,7 @@
void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
const Decl *D = GD.getDecl();
- bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
+ bool InstrumentRegions = CGM.getCodeGenOpts().ProfileClangInstr;
llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
if (!InstrumentRegions && !PGOReader)
return;
@@ -729,7 +729,7 @@
}
void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) {
- if (!CGM.getCodeGenOpts().ProfileInstrGenerate || !RegionCounterMap)
+ if (!CGM.getCodeGenOpts().ProfileClangInstr || !RegionCounterMap)
return;
if (!Builder.GetInsertBlock())
return;
@@ -754,7 +754,7 @@
if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
return;
- bool InstrumentValueSites = CGM.getCodeGenOpts().ProfileInstrGenerate;
+ bool InstrumentValueSites = CGM.getCodeGenOpts().ProfileClangInstr;
if (InstrumentValueSites && RegionCounterMap) {
llvm::LLVMContext &Ctx = CGM.getLLVMContext();
auto *I8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
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().ProfileClangInstr)
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().ProfileClangInstr) {
// 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().ProfileClangInstr &&
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().ProfileClangInstr) {
CaseDest = createBasicBlock("sw.bb");
EmitBlockWithFallThrough(CaseDest, &S);
}
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -429,13 +429,22 @@
MPM->add(createStripSymbolsPass(true));
}
- if (CodeGenOpts.ProfileInstrGenerate) {
+ if (CodeGenOpts.ProfileClangInstr) {
InstrProfOptions Options;
Options.NoRedZone = CodeGenOpts.DisableRedZone;
Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
MPM->add(createInstrProfilingPass(Options));
}
+ if (CodeGenOpts.ProfileIRInstr) {
+ 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(ProfileClangInstr, 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_instrumentor_EQ: Joined<["-"], "fprofile-instrumentor=">,
+ HelpText<"Specify the instrumentor that instruments the code to generate "
+ "execution counts to use with PGO">;
//===----------------------------------------------------------------------===//
// Dependency Output Options
Index: include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- include/clang/Basic/DiagnosticDriverKinds.td
+++ include/clang/Basic/DiagnosticDriverKinds.td
@@ -27,6 +27,8 @@
"invalid thread model '%0' in '%1' for this target">;
def err_drv_invalid_linker_name : Error<
"invalid linker name in argument '%0'">;
+def err_drv_invalid_pgo_instrumentor: Error<
+ "invalid PGO instrumentor in argument '%0'">;
def err_drv_invalid_rtlib_name : Error<
"invalid runtime library name in argument '%0'">;
def err_drv_unsupported_rtlib_for_platform : Error<
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits