]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Add support of generating LLVM assembly
authorHaitao Li <lihaitao@gmail.com>
Mon, 7 Nov 2011 13:32:13 +0000 (21:32 +0800)
committerHaitao Li <lihaitao@gmail.com>
Mon, 7 Nov 2011 13:44:40 +0000 (21:44 +0800)
rustc generates output files in LLVM bitcode format if "--emit-llvm"
option is given. When used with the "-S" option, rustc generates LLVM
intermediate language assembly files.

Fixes Issue #476

src/comp/back/link.rs
src/comp/driver/rustc.rs
src/comp/lib/llvm.rs
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.def.in

index 8d46774712ab228a7b29edf3cfef92433420aeb8..05cd3ba6d36ef218f150da7699ad71ee44f6ebd5 100644 (file)
@@ -30,6 +30,7 @@
     output_type_none;
     output_type_bitcode;
     output_type_assembly;
+    output_type_llvm_assembly;
     output_type_object;
     output_type_exe;
 }
@@ -254,12 +255,19 @@ fn run_passes(sess: session::session, llmod: ModuleRef, output: str) {
             if opts.time_llvm_passes { llvm::LLVMRustPrintPassTimings(); }
             ret;
         }
-        // If only a bitcode file is asked for by using the '--emit-llvm'
-        // flag, then output it here
 
-        llvm::LLVMRunPassManager(pm.llpm, llmod);
-        str::as_buf(output,
-                    {|buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) });
+        if opts.output_type == output_type_llvm_assembly {
+            // Given options "-S --emit-llvm": output LLVM assembly
+            str::as_buf(output, {|buf_o|
+                llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
+        } else {
+            // If only a bitcode file is asked for by using the '--emit-llvm'
+            // flag, then output it here
+            llvm::LLVMRunPassManager(pm.llpm, llmod);
+            str::as_buf(output,
+                        {|buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) });
+        }
+
         llvm::LLVMDisposeModule(llmod);
         if opts.time_llvm_passes { llvm::LLVMRustPrintPassTimings(); }
     }
index 74d13c9a4ca00c3e3d006a0d2d86010daaaef407..3787baffc8253062354cf5544ddc7b23bf77c6cd 100644 (file)
@@ -344,6 +344,8 @@ fn build_session_options(match: getopts::match)
     let output_type =
         if parse_only || no_trans {
             link::output_type_none
+        } else if opt_present(match, "S") && opt_present(match, "emit-llvm") {
+            link::output_type_llvm_assembly
         } else if opt_present(match, "S") {
             link::output_type_assembly
         } else if opt_present(match, "c") {
@@ -475,6 +477,7 @@ fn build_output_filenames(ifile: str, ofile: option::t<str>,
               link::output_type_none. { "none" }
               link::output_type_bitcode. { "bc" }
               link::output_type_assembly. { "s" }
+              link::output_type_llvm_assembly. { "s" }
               // Object and exe output both use the '.o' extension here
               link::output_type_object. | link::output_type_exe. {
                 "o"
index b189f2177c0560b4ef73545b646785cb341e7993..ed38682ff7af7359a60a4457763051aa331661d6 100644 (file)
@@ -866,6 +866,9 @@ fn LLVMRustWriteOutputFile(PM: PassManagerRef, M: ModuleRef, Triple: sbuf,
     fn LLVMRustConstSmallInt(IntTy: TypeRef, N: uint, SignExtend: Bool) ->
        ValueRef;
 
+    fn LLVMRustAddPrintModulePass(PM: PassManagerRef, M: ModuleRef,
+                                  Output: sbuf);
+
     /** Turn on LLVM pass-timing. */
     fn LLVMRustEnableTimePasses();
     /** Turn on LLVM segmented stacks. */
index a9373b6c7e5bba5a231ed500b9744cb55100e46f..26d0764934e05d1964cb6855cf8c5b1a3e0bb7f7 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/Linker.h"
 #include "llvm/PassManager.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/Assembly/PrintModulePass.h"
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
@@ -46,6 +47,17 @@ extern "C" const char *LLVMRustGetLastError(void) {
 
 extern "C" void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
 
+extern "C" void LLVMRustAddPrintModulePass(LLVMPassManagerRef PMR,
+                                           LLVMModuleRef M,
+                                           const char* path) {
+  PassManager *PM = unwrap<PassManager>(PMR);
+  std::string ErrorInfo;
+  raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
+  formatted_raw_ostream FOS(OS);
+  PM->add(createPrintModulePass(&FOS));
+  PM->run(*unwrap(M));
+}
+
 extern "C" bool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src) {
   static std::string err;
 
index beaa3980d8ee29c850ee31b074465d420160a797..b418ba168c8814ef0495db2b079e860e5cb574be 100644 (file)
@@ -24,6 +24,7 @@ LLVMAddAlias
 LLVMAddArgumentPromotionPass
 LLVMAddAttribute
 LLVMAddBasicAliasAnalysisPass
+LLVMRustAddPrintModulePass
 LLVMAddCFGSimplificationPass
 LLVMAddCase
 LLVMAddClause