Index: cfe/trunk/docs/UsersManual.rst =================================================================== --- cfe/trunk/docs/UsersManual.rst +++ cfe/trunk/docs/UsersManual.rst @@ -1502,19 +1502,21 @@ profile. As you make changes to your code, clang may no longer be able to use the profile data. It will warn you when this happens. -Profile generation and use can also be controlled by the GCC-compatible flags -``-fprofile-generate`` and ``-fprofile-use``. Although these flags are -semantically equivalent to their GCC counterparts, they *do not* handle -GCC-compatible profiles. They are only meant to implement GCC's semantics -with respect to profile creation and use. +Profile generation using an alternative instrumentation method can be +controlled by the GCC-compatible flags ``-fprofile-generate`` and +``-fprofile-use``. Although these flags are semantically equivalent to +their GCC counterparts, they *do not* handle GCC-compatible profiles. +They are only meant to implement GCC's semantics with respect to +profile creation and use. .. option:: -fprofile-generate[=] - Without any other arguments, ``-fprofile-generate`` behaves identically to - ``-fprofile-instr-generate``. When given a directory name, it generates the - profile file ``default.profraw`` in the directory named ``dirname``. If - ``dirname`` does not exist, it will be created at runtime. The environment - variable ``LLVM_PROFILE_FILE`` can be used to override the directory and + The ``-fprofile-generate`` and ``-fprofile-generate=`` flags will use + an alterantive instrumentation method for profile generation. When + given a directory name, it generates the profile file + ``default.profraw`` in the directory named ``dirname``. If ``dirname`` + does not exist, it will be created at runtime. The environment variable + ``LLVM_PROFILE_FILE`` can be used to override the directory and filename for the profile file at runtime. For example, .. code-block:: console Index: cfe/trunk/include/clang/Driver/Options.td =================================================================== --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -516,7 +516,8 @@ Group, Flags<[DriverOption]>, HelpText<"Disable code coverage analysis">; def fprofile_generate : Flag<["-"], "fprofile-generate">, - Alias; + Group, Flags<[DriverOption]>, + HelpText<"Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">; def fprofile_generate_EQ : Joined<["-"], "fprofile-generate=">, Group, Flags<[DriverOption]>, MetaVarName<"">, HelpText<"Generate instrumented code to collect execution counts into /default.profraw (overridden by LLVM_PROFILE_FILE env var)">; @@ -529,7 +530,8 @@ Group, Flags<[DriverOption]>, HelpText<"Disable generation of profile instrumentation.">; def fno_profile_generate : Flag<["-"], "fno-profile-generate">, - Alias; + Group, Flags<[DriverOption]>, + HelpText<"Disable generation of profile instrumentation.">; def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">, Group, Flags<[DriverOption]>, HelpText<"Disable using instrumentation data for profile-guided optimization">; Index: cfe/trunk/lib/Driver/Tools.cpp =================================================================== --- cfe/trunk/lib/Driver/Tools.cpp +++ cfe/trunk/lib/Driver/Tools.cpp @@ -3529,16 +3529,27 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, const InputInfo &Output, const ArgList &Args, ArgStringList &CmdArgs) { + + auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate, + options::OPT_fprofile_generate_EQ, + options::OPT_fno_profile_generate); + if (PGOGenerateArg && + PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)) + PGOGenerateArg = nullptr; + auto *ProfileGenerateArg = Args.getLastArg( options::OPT_fprofile_instr_generate, - options::OPT_fprofile_instr_generate_EQ, options::OPT_fprofile_generate, - options::OPT_fprofile_generate_EQ, + options::OPT_fprofile_instr_generate_EQ, options::OPT_fno_profile_instr_generate); if (ProfileGenerateArg && ProfileGenerateArg->getOption().matches( options::OPT_fno_profile_instr_generate)) ProfileGenerateArg = nullptr; + if (PGOGenerateArg && ProfileGenerateArg) + D.Diag(diag::err_drv_argument_not_allowed_with) + << PGOGenerateArg->getSpelling() << ProfileGenerateArg->getSpelling(); + auto *ProfileUseArg = Args.getLastArg( options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ, options::OPT_fprofile_use, options::OPT_fprofile_use_EQ, @@ -3547,6 +3558,10 @@ ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use)) ProfileUseArg = nullptr; + if (PGOGenerateArg && ProfileUseArg) + D.Diag(diag::err_drv_argument_not_allowed_with) + << ProfileUseArg->getSpelling() << PGOGenerateArg->getSpelling(); + if (ProfileGenerateArg && ProfileUseArg) D.Diag(diag::err_drv_argument_not_allowed_with) << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling(); @@ -3556,15 +3571,19 @@ options::OPT_fprofile_instr_generate_EQ)) CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instrument-path=") + ProfileGenerateArg->getValue())); - else if (ProfileGenerateArg->getOption().matches( - options::OPT_fprofile_generate_EQ)) { - SmallString<128> Path(ProfileGenerateArg->getValue()); + // The default is to use Clang Instrumentation. + CmdArgs.push_back("-fprofile-instrument=clang"); + } + + if (PGOGenerateArg) { + CmdArgs.push_back("-fprofile-instrument=llvm"); + if (PGOGenerateArg->getOption().matches( + options::OPT_fprofile_generate_EQ)) { + SmallString<128> Path(PGOGenerateArg->getValue()); llvm::sys::path::append(Path, "default.profraw"); CmdArgs.push_back( Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path)); } - // The default is to use Clang Instrumentation. - CmdArgs.push_back("-fprofile-instrument=clang"); } if (ProfileUseArg) { Index: cfe/trunk/test/Driver/clang_f_opts.c =================================================================== --- cfe/trunk/test/Driver/clang_f_opts.c +++ cfe/trunk/test/Driver/clang_f_opts.c @@ -66,7 +66,7 @@ // CHECK-PROFILE-ARCS: "-femit-coverage-data" // CHECK-NO-PROFILE-ARCS-NOT: "-femit-coverage-data" -// RUN: %clang -### -S -fprofile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE %s +// RUN: %clang -### -S -fprofile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-LLVM %s // RUN: %clang -### -S -fprofile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE %s // RUN: %clang -### -S -fprofile-generate=/some/dir %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-DIR %s // RUN: %clang -### -S -fprofile-instr-generate=/tmp/somefile.profraw %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-FILE %s @@ -87,9 +87,9 @@ // RUN: %clang -### -S -fprofile-generate=dir -fprofile-instr-use %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-GEN-USE %s // RUN: %clang -### -S -fprofile-generate=dir -fprofile-instr-use=file %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-GEN-USE %s // RUN: %clang -### -S -fprofile-instr-generate=file -fno-profile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-GEN %s -// RUN: %clang -### -S -fprofile-instr-generate=file -fno-profile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-GEN %s +// RUN: %clang -### -S -fprofile-instr-generate -fprofile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-GENERATE %s +// RUN: %clang -### -S -fprofile-instr-generate -fprofile-generate=file %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-GENERATE %s // RUN: %clang -### -S -fprofile-generate=dir -fno-profile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-GEN %s -// RUN: %clang -### -S -fprofile-generate=dir -fno-profile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-GEN %s // RUN: %clang -### -S -fprofile-instr-use=file -fno-profile-instr-use %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-USE %s // RUN: %clang -### -S -fprofile-instr-use=file -fno-profile-use %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-USE %s // RUN: %clang -### -S -fprofile-use=file -fno-profile-use %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-USE %s @@ -98,9 +98,11 @@ // RUN: %clang -### -S -fcoverage-mapping -fno-coverage-mapping %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-COVERAGE %s // RUN: %clang -### -S -fprofile-instr-generate -fcoverage-mapping -fno-coverage-mapping %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-COVERAGE %s // CHECK-PROFILE-GENERATE: "-fprofile-instrument=clang" +// CHECK-PROFILE-GENERATE-LLVM: "-fprofile-instrument=llvm" // CHECK-PROFILE-GENERATE-DIR: "-fprofile-instrument-path=/some/dir{{/|\\\\}}default.profraw" // CHECK-PROFILE-GENERATE-FILE: "-fprofile-instrument-path=/tmp/somefile.profraw" // CHECK-NO-MIX-GEN-USE: '{{[a-z=-]*}}' not allowed with '{{[a-z=-]*}}' +// CHECK-NO-MIX-GENERATE: '{{[a-z=-]*}}' not allowed with '{{[a-z=-]*}}' // CHECK-DISABLE-GEN-NOT: "-fprofile-instrument=clang" // CHECK-DISABLE-USE-NOT: "-fprofile-instr-use" // CHECK-COVERAGE-AND-GEN: '-fcoverage-mapping' only allowed with '-fprofile-instr-generate' Index: cfe/trunk/test/Profile/gcc-flag-compatibility.c =================================================================== --- cfe/trunk/test/Profile/gcc-flag-compatibility.c +++ cfe/trunk/test/Profile/gcc-flag-compatibility.c @@ -7,10 +7,11 @@ // -fprofile-use= Uses the profile file /default.profdata // -fprofile-use=/file Uses the profile file /file -// Check that -fprofile-generate uses the runtime default profile file. +// FIXME: IRPGO shouldn't use the override API when no profraw name is given. +// Check that -fprofile-generate overrides the default profraw. // RUN: %clang %s -c -S -o - -emit-llvm -fprofile-generate | FileCheck -check-prefix=PROFILE-GEN %s -// PROFILE-GEN-NOT: call void @__llvm_profile_override_default_filename -// PROFILE-GEN-NOT: declare void @__llvm_profile_override_default_filename(i8*) +// PROFILE-GEN: call void @__llvm_profile_override_default_filename +// PROFILE-GEN: declare void @__llvm_profile_override_default_filename(i8*) // Check that -fprofile-generate=/path/to generates /path/to/default.profraw // RUN: %clang %s -c -S -o - -emit-llvm -fprofile-generate=/path/to | FileCheck -check-prefix=PROFILE-GEN-EQ %s