diff options
-rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 4 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CodeGenOptions.def | 2 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CodeGenOptions.h | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 9 | ||||
-rw-r--r-- | clang/test/CodeGen/pgo-instrumentation.c | 9 |
6 files changed, 33 insertions, 7 deletions
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index b725b5f6af9..d6905db9625 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -274,8 +274,8 @@ def fsanitize_coverage_trace_pc : Flag<["-"], "fsanitize-coverage-trace-pc">, HelpText<"Enable PC tracing 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)">; diff --git a/clang/include/clang/Frontend/CodeGenOptions.def b/clang/include/clang/Frontend/CodeGenOptions.def index 9e8d4d12d72..ef416b431a7 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.def +++ b/clang/include/clang/Frontend/CodeGenOptions.def @@ -104,7 +104,7 @@ VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified. VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified. /// \brief Choose profile instrumenation kind or no instrumentation. -ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNoInstr) +ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone) CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to ///< enable code coverage analysis. CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index 0974288cc83..570663fdb33 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -80,9 +80,10 @@ public: }; enum ProfileInstrKind { - ProfileNoInstr, // No instrumentation. - ProfileClangInstr // Clang instrumentation to generate execution counts + ProfileNone, // Profile instrumentation is turned off. + ProfileClangInstr, // Clang instrumentation to generate execution counts // to use with PGO. + ProfileIRInstr, // IR level PGO instrumentation in LLVM. }; /// The code model to use (-mcmodel). @@ -226,6 +227,11 @@ public: bool hasProfileClangInstr() const { return getProfileInstr() == ProfileClangInstr; } + + /// \brief Check if IR level profile instrumentation is on. + bool hasProfileIRInstr() const { + return getProfileInstr() == ProfileIRInstr; + } }; } // end namespace clang diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index f5afc68eddc..8af9c30dca7 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -437,6 +437,12 @@ void EmitAssemblyHelper::CreatePasses(FunctionInfoIndex *FunctionIndex) { Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput; MPM->add(createInstrProfilingPass(Options)); } + if (CodeGenOpts.hasProfileIRInstr()) { + if (!CodeGenOpts.InstrProfileOutput.empty()) + PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput; + else + PMBuilder.PGOInstrGen = "default.profraw"; + } if (!CodeGenOpts.SampleProfileFile.empty()) MPM->add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile)); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 953d2a8479d..b23eb354375 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -481,18 +481,23 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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; case None: + // Null operation -- The default is ProfileNone. break; case Unknown: Diags.Report(diag::err_drv_invalid_pgo_instrumentor) diff --git a/clang/test/CodeGen/pgo-instrumentation.c b/clang/test/CodeGen/pgo-instrumentation.c new file mode 100644 index 00000000000..f78ab20a129 --- /dev/null +++ b/clang/test/CodeGen/pgo-instrumentation.c @@ -0,0 +1,9 @@ +// Test if PGO instrumentation and use pass are invoked. +// +// Ensure Pass PGOInstrumentationGenPass is invoked. +// RUN: %clang_cc1 -O2 -fprofile-instrument=llvm %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN +// CHECK-PGOGENPASS-INVOKED-INSTR-GEN: PGOInstrumentationGenPass +// +// Ensure Pass PGOInstrumentationGenPass is not invoked. +// RUN: %clang_cc1 -O2 -fprofile-instrument=clang %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN-CLANG +// CHECK-PGOGENPASS-INVOKED-INSTR-GEN-CLANG-NOT: PGOInstrumentationGenPass |