xur updated this revision to Diff 46960. xur added a comment. Now http://reviews.llvm.org/D16730 has been committed (as r259811)
Here is the patch that adds cc1 option -fprofile-instrument=llvm to enable IR level PGO generate and use. The pgo use part of the patch depends http://reviews.llvm.org/D15540 which differentiates the IR level and clang profiles. To detect the profile automatically, we need to first the profile. It can either done in driver or in Clang codegen (lib/CodeGen/CodeGenModule.cpp). If we do this in Clang codegen, we would have to change the Codegen option which does not seem to be a good approach. As a result, we do this in the driver in this patch. Again like in http://reviews.llvm.org/D16730, this patch won't change any driver (user level) options. Only cc1 options are touched. Thanks, -Rong http://reviews.llvm.org/D15829 Files: include/clang/Driver/CC1Options.td include/clang/Frontend/CodeGenOptions.h lib/CodeGen/BackendUtil.cpp lib/CodeGen/CodeGenModule.cpp lib/Driver/CMakeLists.txt lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/Inputs/pgotestclang.profraw test/CodeGen/Inputs/pgotestir.profraw test/CodeGen/pgo-instrumentation.c
Index: test/CodeGen/pgo-instrumentation.c =================================================================== --- test/CodeGen/pgo-instrumentation.c +++ 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-instrument=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-instrument=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-instrument=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/pgotestir.profraw +// RUN: %clang -O2 -c -Xclang -fprofile-instrument=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/pgotestir.profraw +// RUN: %clang -O2 -c -Xclang -fprofile-instrument=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/pgotestclang.profraw +// RUN: %clang -O2 -c -Xclang -fprofile-instrument=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: test/CodeGen/Inputs/pgotestir.profraw =================================================================== --- test/CodeGen/Inputs/pgotestir.profraw +++ test/CodeGen/Inputs/pgotestir.profraw @@ -0,0 +1 @@ +:ir Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -478,14 +478,18 @@ 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; Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -32,6 +32,7 @@ #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" +#include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Compression.h" #include "llvm/Support/ErrorHandling.h" @@ -3196,6 +3197,18 @@ return VersionTuple(); } +// Set the profile kind if it's not the default clang kind. +static void setProfileKindFlag(ArgStringList &CmdArgs, + std::string ProfileName) { + auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName); + if (ReaderOrErr.getError()) + return; + std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader = + std::move(ReaderOrErr.get()); + if (PGOReader->isIRLevelProfile()) + CmdArgs.push_back("-fprofile-instrument=llvm"); +} + static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, const InputInfo &Output, const ArgList &Args, ArgStringList &CmdArgs) { @@ -3238,8 +3251,10 @@ } if (ProfileUseArg) { - if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ)) + if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ)) { ProfileUseArg->render(Args, CmdArgs); + setProfileKindFlag(CmdArgs, ProfileUseArg->getValue()); + } else if ((ProfileUseArg->getOption().matches( options::OPT_fprofile_use_EQ) || ProfileUseArg->getOption().matches( @@ -3250,6 +3265,7 @@ llvm::sys::path::append(Path, "default.profdata"); CmdArgs.push_back( Args.MakeArgString(Twine("-fprofile-instr-use=") + Path)); + setProfileKindFlag(CmdArgs, Path.str().str()); } } Index: lib/Driver/CMakeLists.txt =================================================================== --- lib/Driver/CMakeLists.txt +++ lib/Driver/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_LINK_COMPONENTS Option Support + ProfileData ) add_clang_library(clangDriver Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -146,7 +146,8 @@ if (C.getLangOpts().ObjC1) ObjCData = new ObjCEntrypoints(); - if (!CodeGenOpts.InstrProfileInput.empty()) { + if (!CodeGenOpts.hasProfileIRInstr() && + !CodeGenOpts.InstrProfileInput.empty()) { auto ReaderOrErr = llvm::IndexedInstrProfReader::create(CodeGenOpts.InstrProfileInput); if (std::error_code EC = ReaderOrErr.getError()) { Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -434,6 +434,13 @@ Options.NoRedZone = CodeGenOpts.DisableRedZone; Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput; MPM->add(createInstrProfilingPass(Options)); + } else if (CodeGenOpts.hasProfileIRInstr()) { + 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()) Index: include/clang/Frontend/CodeGenOptions.h =================================================================== --- include/clang/Frontend/CodeGenOptions.h +++ include/clang/Frontend/CodeGenOptions.h @@ -87,8 +87,9 @@ enum ProfileInstrKind { ProfileNoInstr, // No instrumentation. - ProfileClangInstr // Clang instrumentation to generate execution counts + ProfileClangInstr, // Clang instrumentation to generate execution counts // to use with PGO. + ProfileIRInstr // IR level PGO instrumentation in LLVM. }; /// The code model to use (-mcmodel). @@ -229,6 +230,11 @@ bool hasProfileClangInstr() const { return getProfileInstr() == ProfileClangInstr; } + + /// \brief Check if IR profile instrumenation is on. + bool hasProfileIRInstr() const { + return getProfileInstr() == ProfileIRInstr; + } }; } // end namespace clang Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -269,8 +269,8 @@ : Flag<["-"], "fsanitize-coverage-8bit-counters">, HelpText<"Enable frequency counters 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)">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits