Add GCC-compatible flags -fprofile-generate and -fprofile-use.

This patch adds support for specifying where the profile is emitted in a
way similar to GCC. These flags are used to specify directories instead
of filenames. When -fprofile-generate=DIR is used, the compiler will
generate code to write to <DIR>/default.profraw.

The patch also adds a couple of extensions: LLVM_PROFILE_FILE can still be
used to override the directory and file name to use and -fprofile-use
accepts both directories and filenames.

To simplify the set of flags used in the backend, all the flags get
canonicalized to -fprofile-instr-{generate,use} when passed to the
backend. The decision to use a default name for the profile is done
in the driver.

llvm-svn: 241825
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 1795ccf..6a1ac11 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -2298,6 +2298,7 @@
   if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
                      false) ||
         Args.hasArg(options::OPT_fprofile_generate) ||
+        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_fcreate_profile) ||
@@ -3532,23 +3533,47 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
 
-  if ((Args.hasArg(options::OPT_fprofile_instr_generate) ||
-       Args.hasArg(options::OPT_fprofile_instr_generate_EQ)) &&
-      (Args.hasArg(options::OPT_fprofile_instr_use) ||
-       Args.hasArg(options::OPT_fprofile_instr_use_EQ)))
-    D.Diag(diag::err_drv_argument_not_allowed_with)
-        << "-fprofile-instr-generate"
-        << "-fprofile-instr-use";
+  auto *ProfileGenerateArg = Args.getLastArg(
+      options::OPT_fprofile_instr_generate,
+      options::OPT_fprofile_instr_generate_EQ, options::OPT_fprofile_generate,
+      options::OPT_fprofile_generate_EQ);
 
-  if (Arg *A = Args.getLastArg(options::OPT_fprofile_instr_generate_EQ))
-    A->render(Args, CmdArgs);
-  else
+  auto *ProfileUseArg = Args.getLastArg(
+      options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
+      options::OPT_fprofile_use, options::OPT_fprofile_use_EQ);
+
+  if (ProfileGenerateArg && ProfileUseArg)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+        << ProfileGenerateArg->getSpelling()
+        << ProfileUseArg->getSpelling();
+
+  if (ProfileGenerateArg &&
+      ProfileGenerateArg->getOption().matches(
+          options::OPT_fprofile_instr_generate_EQ))
+    ProfileGenerateArg->render(Args, CmdArgs);
+  else if (ProfileGenerateArg &&
+           ProfileGenerateArg->getOption().matches(
+               options::OPT_fprofile_generate_EQ)) {
+    SmallString<128> Path(ProfileGenerateArg->getValue());
+    llvm::sys::path::append(Path, "default.profraw");
+    CmdArgs.push_back(
+        Args.MakeArgString(Twine("-fprofile-instr-generate=") + Path));
+  } else
     Args.AddAllArgs(CmdArgs, options::OPT_fprofile_instr_generate);
 
-  if (Arg *A = Args.getLastArg(options::OPT_fprofile_instr_use_EQ))
-    A->render(Args, CmdArgs);
-  else if (Args.hasArg(options::OPT_fprofile_instr_use))
-    CmdArgs.push_back("-fprofile-instr-use=pgo-data");
+  if (ProfileUseArg &&
+      ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
+    ProfileUseArg->render(Args, CmdArgs);
+  else if (ProfileUseArg &&
+           (ProfileUseArg->getOption().matches(options::OPT_fprofile_use_EQ) ||
+            ProfileUseArg->getOption().matches(
+                options::OPT_fprofile_instr_use))) {
+    SmallString<128> Path(
+        ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
+    if (Path.empty() || llvm::sys::fs::is_directory(Path))
+      llvm::sys::path::append(Path, "default.profdata");
+    CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instr-use=") + Path));
+  }
 
   if (Args.hasArg(options::OPT_ftest_coverage) ||
       Args.hasArg(options::OPT_coverage))
@@ -3558,9 +3583,7 @@
       Args.hasArg(options::OPT_coverage))
     CmdArgs.push_back("-femit-coverage-data");
 
-  if (Args.hasArg(options::OPT_fcoverage_mapping) &&
-      !(Args.hasArg(options::OPT_fprofile_instr_generate) ||
-        Args.hasArg(options::OPT_fprofile_instr_generate_EQ)))
+  if (Args.hasArg(options::OPT_fcoverage_mapping) && !ProfileGenerateArg)
     D.Diag(diag::err_drv_argument_only_allowed_with)
         << "-fcoverage-mapping"
         << "-fprofile-instr-generate";