From: Rong Xu Date: Mon, 29 Feb 2016 18:54:59 +0000 (+0000) Subject: [PGO] clang cc1 option change to enable IR level instrumentation X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9c5efc9808b7e456857497166d38c0f8663716bc;p=clang [PGO] clang cc1 option change to enable IR level instrumentation This patch expands cc1 option -fprofile-instrument= with a new value: -fprofile-instrument=llvm which enables IR level PGO instrumentation. Reviewers: davidxl, silvas Differential Revision: http://reviews.llvm.org/D17622 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@262239 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index b725b5f6af..d6905db962 100644 --- a/include/clang/Driver/CC1Options.td +++ b/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 " " (overridden by LLVM_PROFILE_FILE env var)">; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 9e8d4d12d7..ef416b431a 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/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/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 0974288cc8..570663fdb3 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/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/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index f5afc68edd..8af9c30dca 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/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/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 953d2a8479..b23eb35437 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/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(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/test/CodeGen/pgo-instrumentation.c b/test/CodeGen/pgo-instrumentation.c new file mode 100644 index 0000000000..f78ab20a12 --- /dev/null +++ b/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