jakev updated this revision to Diff 62527.
jakev added a comment.

Don't allow `-fpgo-train` and `-fpgo-apply` together. Add 
`-fpgo-train-default-output=*` to set the default profile output file.


Repository:
  rL LLVM

http://reviews.llvm.org/D21823

Files:
  include/clang/Driver/Options.td
  lib/Driver/ToolChain.cpp
  lib/Driver/Tools.cpp
  test/Driver/clang_f_opts.c

Index: test/Driver/clang_f_opts.c
===================================================================
--- test/Driver/clang_f_opts.c
+++ test/Driver/clang_f_opts.c
@@ -97,23 +97,42 @@
 // RUN: %clang -### -S -fcoverage-mapping %s 2>&1 | FileCheck -check-prefix=CHECK-COVERAGE-AND-GEN %s
 // 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
+// RUN: %clang -### -S -fpgo-train=source-cfg %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE %s
+// RUN: %clang -### -S -fpgo-train=optimizer-cfg %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-LLVM %s
+// RUN: %clang -### -S -fpgo-train-default-output=file %s 2>&1 | FileCheck -check-prefix=CHECK-DEFAULT-AND-TRAIN %s
+// RUN: %clang -### -S -fpgo-train=source-cfg -fpgo-train-default-output=/tmp/somefile.profraw %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-FILE %s
+// RUN: %clang -### -S -fpgo-train=optimizer-cfg -fpgo-train-default-output=/tmp/somefile.profraw %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-FILE %s
+// RUN: %clang -### -S -fpgo-train=source-cfg -fcoverage-mapping %s 2>&1 | FileCheck -check-prefix=CHECK-COVERAGE-AND-GEN %s
+// RUN: %clang -### -S -fpgo-train=optimizer-cfg -fcoverage-mapping %s 2>&1 | FileCheck -check-prefix=CHECK-COVERAGE-AND-GEN %s
+// RUN: %clang -### -S -fpgo-train=source-cfg -fprofile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-TRAIN-GEN %s
+// RUN: %clang -### -S -fpgo-train=optimizer-cfg -fprofile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-TRAIN-GEN %s
+// RUN: %clang -### -S -fpgo-train=source-cfg -fpgo-apply=file %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-GEN-USE %s
+// RUN: %clang -### -S -fpgo-train=optimizer-cfg -fpgo-apply=file %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-GEN-USE %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-TRAIN-GEN: '{{[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'
+// CHECK-DEFAULT-AND-TRAIN: '-fpgo-train-default-output' only allowed with '-fpgo-train'
 // CHECK-DISABLE-COVERAGE-NOT: "-fcoverage-mapping"
 
 // RUN: %clang -### -S -fprofile-use %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE %s
 // RUN: %clang -### -S -fprofile-instr-use %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE %s
 // RUN: mkdir -p %t.d/some/dir
 // RUN: %clang -### -S -fprofile-use=%t.d/some/dir %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE-DIR %s
 // RUN: %clang -### -S -fprofile-instr-use=/tmp/somefile.prof %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE-FILE %s
+// RUN: %clang -### -S -fpgo-apply=/tmp/somefile.prof %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE-FILE %s
+// RUN: %clang -### -S -fpgo-train=source-cfg -fpgo-apply=/tmp/somefile.prof %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE-FILE %s
+// RUN: %clang -### -S -fpgo-train=optimizer-cfg  -fpgo-apply=/tmp/somefile.prof %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE-FILE %s
+// RUN: %clang -### -S -fprofile-instr-use=/tmp/somefile.prof -fpgo-apply=/tmp/somefile.prof %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-APPLY-USE %s
 // CHECK-PROFILE-USE: "-fprofile-instrument-use-path=default.profdata"
 // CHECK-PROFILE-USE-DIR: "-fprofile-instrument-use-path={{.*}}.d/some/dir{{/|\\\\}}default.profdata"
 // CHECK-PROFILE-USE-FILE: "-fprofile-instrument-use-path=/tmp/somefile.prof"
+// CHECK-NO-MIX-APPLY-USE: '{{[a-z=-]*}}' not allowed with '{{[a-z=-]*}}'
 
 // RUN: %clang -### -S -fvectorize %s 2>&1 | FileCheck -check-prefix=CHECK-VECTORIZE %s
 // RUN: %clang -### -S -fno-vectorize -fvectorize %s 2>&1 | FileCheck -check-prefix=CHECK-VECTORIZE %s
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -3468,6 +3468,28 @@
 static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
                                    const InputInfo &Output, const ArgList &Args,
                                    ArgStringList &CmdArgs) {
+
+  auto *PGOTrainArg =
+      Args.getLastArg(options::OPT_fpgo_train_EQ,
+                      options::OPT_fno_pgo_train);
+  if (PGOTrainArg &&
+      PGOTrainArg->getOption().matches(options::OPT_fno_pgo_train))
+    PGOTrainArg = nullptr;
+
+  auto *PGODefaultOutputArg =
+      Args.getLastArg(options::OPT_fpgo_train_default_output_EQ);
+
+  if (PGODefaultOutputArg && !PGOTrainArg)
+    D.Diag(diag::err_drv_argument_only_allowed_with)
+        << "-fpgo-train-default-output"
+        << "-fpgo-train";
+
+  if (PGODefaultOutputArg)
+    if (PGODefaultOutputArg->getOption().matches(
+            options::OPT_fpgo_train_default_output_EQ))
+      CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instrument-path=") +
+                                           PGODefaultOutputArg->getValue()));
+
   auto *ProfileGenerateArg = Args.getLastArg(
       options::OPT_fprofile_instr_generate,
       options::OPT_fprofile_instr_generate_EQ, options::OPT_fprofile_generate,
@@ -3478,14 +3500,41 @@
           options::OPT_fno_profile_instr_generate))
     ProfileGenerateArg = nullptr;
 
+  else if (PGOTrainArg && ProfileGenerateArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << PGOTrainArg->getSpelling()
+        << ProfileGenerateArg->getSpelling();
+
+  auto *PGOApplyArg =
+      Args.getLastArg(options::OPT_fpgo_apply_EQ, options::OPT_fno_pgo_apply);
+  if (PGOApplyArg &&
+      PGOApplyArg->getOption().matches(options::OPT_fno_pgo_apply))
+    PGOApplyArg = nullptr;
+
+  if (PGOTrainArg && PGOApplyArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << PGOTrainArg->getSpelling() << PGOApplyArg->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,
       options::OPT_fno_profile_instr_use);
   if (ProfileUseArg &&
       ProfileUseArg->getOption().matches(options::OPT_fno_profile_instr_use))
     ProfileUseArg = nullptr;
 
+  if (PGOTrainArg && PGOApplyArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << PGOApplyArg->getSpelling() << PGOTrainArg->getSpelling();
+
+  if (PGOApplyArg && ProfileUseArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << ProfileUseArg->getSpelling() << PGOApplyArg->getSpelling();
+
+  if (PGOTrainArg && ProfileUseArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << ProfileUseArg->getSpelling() << PGOTrainArg->getSpelling();
+
   if (ProfileGenerateArg && ProfileUseArg)
     D.Diag(diag::err_drv_argument_not_allowed_with)
         << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
@@ -3506,6 +3555,22 @@
     CmdArgs.push_back("-fprofile-instrument=clang");
   }
 
+  if (PGOTrainArg) {
+    if (PGOTrainArg->getOption().matches(options::OPT_fpgo_train_EQ)) {
+      if (StringRef(PGOTrainArg->getValue()) == "source-cfg")
+        CmdArgs.push_back("-fprofile-instrument=clang");
+      else if (StringRef(PGOTrainArg->getValue()) == "optimizer-cfg")
+        CmdArgs.push_back("-fprofile-instrument=llvm");
+    }
+  }
+
+  if (PGOApplyArg) {
+    if (PGOApplyArg->getOption().matches(options::OPT_fpgo_apply_EQ))
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-fprofile-instrument-use-path=") +
+                             PGOApplyArg->getValue()));
+  }
+
   if (ProfileUseArg) {
     if (ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
       CmdArgs.push_back(Args.MakeArgString(
@@ -3576,6 +3641,8 @@
                     options::OPT_fno_profile_instr_generate, false) ||
        Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,
                     options::OPT_fno_profile_instr_generate, false) ||
+       Args.hasFlag(options::OPT_fpgo_train_EQ,
+                    options::OPT_fno_pgo_train, false) ||
        Args.hasArg(options::OPT_fcreate_profile) ||
        Args.hasArg(options::OPT_coverage)))
     CmdArgs.push_back("--dependent-lib=libclang_rt.profile-x86_64.a");
Index: lib/Driver/ToolChain.cpp
===================================================================
--- lib/Driver/ToolChain.cpp
+++ lib/Driver/ToolChain.cpp
@@ -317,6 +317,7 @@
       Args.hasArg(options::OPT_fprofile_generate_EQ) ||
       Args.hasArg(options::OPT_fprofile_instr_generate) ||
       Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
+      Args.hasArg(options::OPT_fpgo_train_EQ) ||
       Args.hasArg(options::OPT_fcreate_profile) ||
       Args.hasArg(options::OPT_coverage))
     return true;
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -499,6 +499,15 @@
 def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">,
     Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<file>">,
     HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">;
+def fpgo_train_EQ : Joined<["-"], "fpgo-train=">,
+    Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<options>">,
+    HelpText<"Instrument the code to collect profiling information into default.profraw file (overridden by LLVM_PROFILE_FILE env var)">;
+def fpgo_train_default_output_EQ : Joined<["-"], "fpgo-train-default-output=">,
+    Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<file>">,
+    HelpText<"Set <file> to be the default profile output file (overridden by LLVM_PROFILE_FILE env var)">;
+def fpgo_apply_EQ : Joined<["-"], "fpgo-apply=">,
+    Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<file>">,
+    HelpText<"Apply profile data to the code for use in profile-guided optimization">;
 def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>,
     Flags<[DriverOption]>;
 def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
@@ -523,6 +532,12 @@
 def fno_profile_instr_generate : Flag<["-"], "fno-profile-instr-generate">,
     Group<f_Group>, Flags<[DriverOption]>,
     HelpText<"Disable generation of profile instrumentation.">;
+def fno_pgo_train : Flag<["-"], "fno-pgo-train">,
+    Group<f_Group>, Flags<[DriverOption]>,
+    HelpText<"Disable profiling instrumentation.">;
+def fno_pgo_apply : Flag<["-"], "fno-pgo-apply">,
+    Group<f_Group>, Flags<[DriverOption]>,
+    HelpText<"Disable using profile data for profile-guided optimization">;
 def fno_profile_generate : Flag<["-"], "fno-profile-generate">,
     Alias<fno_profile_instr_generate>;
 def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to