Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -274,8 +274,8 @@ : 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)">; Index: include/clang/Frontend/CodeGenOptions.h =================================================================== --- include/clang/Frontend/CodeGenOptions.h +++ include/clang/Frontend/CodeGenOptions.h @@ -80,9 +80,10 @@ }; 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 @@ bool hasProfileClangInstr() const { return getProfileInstr() == ProfileClangInstr; } + + /// \brief Check if IR level profile instrumentation is on. + bool hasProfileIRInstr() const { + return getProfileInstr() == ProfileIRInstr; + } }; } // end namespace clang Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -104,7 +104,7 @@ 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 Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -437,6 +437,12 @@ 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)); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -481,18 +481,23 @@ 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) Index: test/CodeGen/pgo-instrumentation.c =================================================================== --- test/CodeGen/pgo-instrumentation.c +++ 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