From 9c6f1538cc0f70fe43d47cf818ad797c82b61d5f Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Wed, 2 Mar 2016 20:59:36 +0000 Subject: [PGO] Change profile use cc1 option to handle IR level profiles This patch changes cc1 option for PGO profile use from -fprofile-instr-use= to -fprofile-instrument-use-path=. -fprofile-instr-use= is now a driver only option. In addition to decouple the cc1 option from the driver level option, this patch also enables IR level profile use. cc1 option handling now reads the profile header and sets CodeGenOpt ProfileUse (valid values are {None, Clang, LLVM} -- this is a common enum for -fprofile-instrument={}, for the profile instrumentation), and invoke the pipeline to enable the respective PGO use pass. Reviewers: silvas, davidxl Differential Revision: http://reviews.llvm.org/D17737 llvm-svn: 262515 --- clang/lib/Frontend/CompilerInvocation.cpp | 73 ++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 26 deletions(-) (limited to 'clang/lib/Frontend/CompilerInvocation.cpp') diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 9bb33e7..bf845b2 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -33,6 +33,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" +#include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -375,6 +376,45 @@ static void parseSanitizerKinds(StringRef FlagName, } } +// Set the profile kind for fprofile-instrument. +static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags) { + Arg *A = Args.getLastArg(OPT_fprofile_instrument_EQ); + if (A == nullptr) + return; + StringRef S = A->getValue(); + unsigned I = llvm::StringSwitch(S) + .Case("none", CodeGenOptions::ProfileNone) + .Case("clang", CodeGenOptions::ProfileClangInstr) + .Case("llvm", CodeGenOptions::ProfileIRInstr) + .Default(~0U); + if (I == ~0U) { + Diags.Report(diag::err_drv_invalid_pgo_instrumentor) << A->getAsString(Args) + << S; + return; + } + CodeGenOptions::ProfileInstrKind Instrumentor = + static_cast(I); + Opts.setProfileInstr(Instrumentor); +} + +// Set the profile kind using fprofile-instrument-use-path. +static void setPGOUseInstrumentor(CodeGenOptions &Opts, + const std::string ProfileName) { + auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName); + // In error, return silently and let Clang PGOUse report the error message. + if (ReaderOrErr.getError()) { + Opts.setProfileUse(CodeGenOptions::ProfileClangInstr); + return; + } + std::unique_ptr PGOReader = + std::move(ReaderOrErr.get()); + if (PGOReader->isIRLevelProfile()) + Opts.setProfileUse(CodeGenOptions::ProfileIRInstr); + else + Opts.setProfileUse(CodeGenOptions::ProfileClangInstr); +} + static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, DiagnosticsEngine &Diags, const TargetOptions &TargetOpts) { @@ -481,33 +521,14 @@ 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, LLVM }; - if (Arg *A = Args.getLastArg(OPT_fprofile_instrument_EQ)) { - StringRef Value = A->getValue(); - PGOInstrumentor Method = llvm::StringSwitch(Value) - .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) - << A->getAsString(Args) << Value; - break; - } - } + setPGOInstrumentor(Opts, Args, Diags); + Opts.InstrProfileOutput = + Args.getLastArgValue(OPT_fprofile_instrument_path_EQ); + Opts.ProfileInstrumentUsePath = + Args.getLastArgValue(OPT_fprofile_instrument_use_path_EQ); + if (!Opts.ProfileInstrumentUsePath.empty()) + setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath); - Opts.InstrProfileOutput = Args.getLastArgValue(OPT_fprofile_instrument_path_EQ); - Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ); Opts.CoverageMapping = Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false); Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping); -- cgit v1.1