Introduce -fembed-bitcode driver option

Summary:
This is the clang driver part of the change to embedded bitcode. This
includes:
1. -fembed-bitcode option which breaks down the compilation into two
stages. The first stage emits optimized bitcode and the second stage
compiles bitcode into object file.
2. -fembed-bitcode-marker option which doesn't really break down to
two stages to speedup the compilation flow.
3. pass the correct linker flag to darwin linker if tool chains supports
embedded bitcode.

Reviewers: rsmith, thakis

Subscribers: thakis, cfe-commits

Differential Revision: http://reviews.llvm.org/D17390

llvm-svn: 262282
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index e5dbe9b..a0fceb9 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -3625,6 +3625,17 @@
     Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
   }
 
+  // Embed-bitcode option.
+  if (C.getDriver().embedBitcodeEnabled() &&
+      (isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
+    // Add flags implied by -fembed-bitcode.
+    CmdArgs.push_back("-fembed-bitcode");
+    // Disable all llvm IR level optimizations.
+    CmdArgs.push_back("-disable-llvm-optzns");
+  }
+  if (C.getDriver().embedBitcodeMarkerOnly())
+    CmdArgs.push_back("-fembed-bitcode-marker");
+
   // We normally speed up the clang process a bit by skipping destructors at
   // exit, but when we're generating diagnostics we can rely on some of the
   // cleanup.
@@ -7262,6 +7273,15 @@
     else
       CmdArgs.push_back("-no_pie");
   }
+  // for embed-bitcode, use -bitcode_bundle in linker command
+  if (C.getDriver().embedBitcodeEnabled() ||
+      C.getDriver().embedBitcodeMarkerOnly()) {
+    // Check if the toolchain supports bitcode build flow.
+    if (MachOTC.SupportsEmbeddedBitcode())
+      CmdArgs.push_back("-bitcode_bundle");
+    else
+      D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
+  }
 
   Args.AddLastArg(CmdArgs, options::OPT_prebind);
   Args.AddLastArg(CmdArgs, options::OPT_noprebind);