rustc: Add support of generating LLVM assembly

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
This commit is contained in:
Haitao Li 2011-11-07 21:32:13 +08:00
parent f3468d03a2
commit b12de98814
5 changed files with 32 additions and 5 deletions

View file

@ -30,6 +30,7 @@ tag output_type {
output_type_none;
output_type_bitcode;
output_type_assembly;
output_type_llvm_assembly;
output_type_object;
output_type_exe;
}
@ -254,12 +255,19 @@ mod write {
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(); }
}

View 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"

View file

@ -866,6 +866,9 @@ native "c-stack-cdecl" mod llvm = "rustllvm" {
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. */

View 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;

View file

@ -24,6 +24,7 @@ LLVMAddAlias
LLVMAddArgumentPromotionPass
LLVMAddAttribute
LLVMAddBasicAliasAnalysisPass
LLVMRustAddPrintModulePass
LLVMAddCFGSimplificationPass
LLVMAddCase
LLVMAddClause