[Flang][Driver] Handle target CPU and features

This patch:

- Adds target-feature and target-cpu to FC1Options.
- Moves getTargetFeatures() from Clang.cpp to CommonArgs.cpp.
- Processes target cpu and features in the flang driver. Right now
  features are only added for AArch64/x86 because I only did basic
  testing on them but it should generally work for others as well.
  Option handling is similar to clang.
- Adds appropriate structures in TargetOptions and passes them to
  the target machine.

What's missing:

- Adding the CPU info and the features as attributes in the LLVM IR
  module.
- Processing target specific flags, e.g. SVE vector bits for AArch64,
  ABI etc.

Differential Revision: https://reviews.llvm.org/D137995

Change-Id: Ib081a74ea98617674845518a5d2754edba596418
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 588fabd..b2b08f9 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -80,6 +80,32 @@
   }
 }
 
+void Flang::addTargetOptions(const ArgList &Args,
+                             ArgStringList &CmdArgs) const {
+  const ToolChain &TC = getToolChain();
+  const llvm::Triple &Triple = TC.getEffectiveTriple();
+  const Driver &D = TC.getDriver();
+
+  std::string CPU = getCPUName(D, Args, Triple);
+  if (!CPU.empty()) {
+    CmdArgs.push_back("-target-cpu");
+    CmdArgs.push_back(Args.MakeArgString(CPU));
+  }
+
+  // Add the target features.
+  switch (TC.getArch()) {
+  default:
+    break;
+  case llvm::Triple::aarch64:
+    [[fallthrough]];
+  case llvm::Triple::x86_64:
+    getTargetFeatures(D, Triple, Args, CmdArgs, /*ForAs*/ false);
+    break;
+  }
+
+  // TODO: Add target specific flags, ABI, mtune option etc.
+}
+
 static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
                                     ArgStringList &CmdArgs) {
   StringRef FPContract;
@@ -243,6 +269,9 @@
   // Floating point related options
   addFloatingPointOptions(D, Args, CmdArgs);
 
+  // Add target args, features, etc.
+  addTargetOptions(Args, CmdArgs);
+
   // Add other compile options
   addOtherOptions(Args, CmdArgs);