driver: stop before codegen if -emit-llvm is specified

When -emit-llvm is specified, we are asked to emit the IR (text
or binary). Stop after the IR passes and don't run the code
generation passes.

Change-Id: Ib091ff0a57eeb788b6082c302ce88576bfcb7d59
Reviewed-on: https://go-review.googlesource.com/c/140877
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/driver/CompileGo.cpp b/driver/CompileGo.cpp
index 7af05eb..976e40b 100644
--- a/driver/CompileGo.cpp
+++ b/driver/CompileGo.cpp
@@ -225,7 +225,8 @@
   if (args_.hasArg(gollvm::options::OPT_v) || hashHashHash) {
     errs() << "Target: " << triple_.str() << "\n";
     errs() << " " << executablePath_;
-    if (!args_.hasArg(gollvm::options::OPT_S))
+    if (!args_.hasArg(gollvm::options::OPT_S) &&
+        !args_.hasArg(gollvm::options::OPT_emit_llvm))
       errs() << " " << "-S";
     for (auto arg : args_) {
       // Special case for -L. Here even if the user said "-L /x"
@@ -711,6 +712,10 @@
       createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis()));
   createPasses(modulePasses, functionPasses);
 
+  legacy::PassManager codeGenPasses;
+  bool noverify = args_.hasArg(gollvm::options::OPT_noverify);
+  TargetMachine::CodeGenFileType ft = TargetMachine::CGFT_AssemblyFile;
+
   // Add passes to emit bitcode or LLVM IR as appropriate. Here we mimic
   // clang behavior, which is to emit bitcode when "-emit-llvm" is specified
   // but an LLVM IR dump of "-S -emit-llvm" is used.
@@ -724,23 +729,22 @@
     modulePasses.add(bitcode ?
                      createBitcodeWriterPass(*OS, preserveUseLists) :
                      createPrintModulePass(*OS, "", preserveUseLists));
+    goto run;
   }
 
   // Set up codegen passes
-  legacy::PassManager codeGenPasses;
   codeGenPasses.add(
       createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis()));
 
   // Codegen setup
   codeGenPasses.add(new TargetLibraryInfoWrapperPass(*tlii_));
-  bool noverify = args_.hasArg(gollvm::options::OPT_noverify);
-  TargetMachine::CodeGenFileType ft = TargetMachine::CGFT_AssemblyFile;
   if (target_->addPassesToEmitFile(codeGenPasses, *OS, nullptr, ft,
                                    /*DisableVerify=*/ noverify)) {
     errs() << "error: unable to interface with target\n";
     return false;
   }
 
+run:
   // Here we go... first function passes
   functionPasses.doInitialization();
   for (Function &F : *module_.get())
@@ -752,7 +756,8 @@
   modulePasses.run(*module_.get());
 
   // ... and finally code generation
-  codeGenPasses.run(*module_.get());
+  if (!args_.hasArg(gollvm::options::OPT_emit_llvm))
+    codeGenPasses.run(*module_.get());
 
   if (hasError_)
     return false;
diff --git a/driver/Driver.cpp b/driver/Driver.cpp
index 3f76e59..dfe748f 100644
--- a/driver/Driver.cpp
+++ b/driver/Driver.cpp
@@ -446,7 +446,7 @@
     compilation.addAction(gocompact);
 
     // Schedule assemble action now if no -S.
-    if (!OPT_S) {
+    if (!OPT_S && !args_.hasArg(gollvm::options::OPT_emit_llvm)) {
       // Create action
       Action *asmact =
           new Action(Action::A_Assemble, gocompact);