Skip to content

Commit

Permalink
rustc: Add obj_is_bitcode to TargetOptions
Browse files Browse the repository at this point in the history
This tells trans::back::write not to LLVM codegen to create .o
files but to put LLMV bitcode in .o files.

Emscripten's emcc supports .o in this format, and this is,
I think, slightly easier than making rlibs work without .o
files.
  • Loading branch information
brson committed Feb 6, 2016
1 parent d6c0d85 commit 81ba4a7
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/librustc_back/target/asmjs_unknown_emscripten.rs
Expand Up @@ -22,6 +22,7 @@ pub fn target() -> Target {
linker_is_gnu: true,
allow_asm: false,
archive_format: "gnu".to_string(),
obj_is_bitcode: true,
.. Default::default()
};
Target {
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_back/target/mod.rs
Expand Up @@ -204,6 +204,10 @@ pub struct TargetOptions {
/// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for
/// this target.
pub has_elf_tls: bool,
// This is mainly for easy compatibility with emscripten.
// If we give emcc .o files that are actually .bc files it
// will 'just work'.
pub obj_is_bitcode: bool,
}

impl Default for TargetOptions {
Expand Down Expand Up @@ -251,6 +255,7 @@ impl Default for TargetOptions {
exe_allocation_crate: "alloc_system".to_string(),
allow_asm: true,
has_elf_tls: false,
obj_is_bitcode: false,
}
}
}
Expand Down
48 changes: 38 additions & 10 deletions src/librustc_trans/back/write.rs
Expand Up @@ -244,7 +244,6 @@ pub struct ModuleConfig {
emit_ir: bool,
emit_asm: bool,
emit_obj: bool,

// Miscellaneous flags. These are mostly copied from command-line
// options.
no_verify: bool,
Expand All @@ -254,7 +253,11 @@ pub struct ModuleConfig {
vectorize_loop: bool,
vectorize_slp: bool,
merge_functions: bool,
inline_threshold: Option<usize>
inline_threshold: Option<usize>,
// Instead of creating an object file by doing LLVM codegen, just
// make the object file bitcode. Provides easy compatibility with
// emscripten's ecc compiler, when used as the linker.
obj_is_bitcode: bool,
}

unsafe impl Send for ModuleConfig { }
Expand All @@ -272,6 +275,7 @@ impl ModuleConfig {
emit_ir: false,
emit_asm: false,
emit_obj: false,
obj_is_bitcode: false,

no_verify: false,
no_prepopulate_passes: false,
Expand All @@ -290,6 +294,7 @@ impl ModuleConfig {
self.no_builtins = trans.no_builtins;
self.time_passes = sess.time_passes();
self.inline_threshold = sess.opts.cg.inline_threshold;
self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode;

// Copy what clang does by turning on loop vectorization at O2 and
// slp vectorization at O3. Otherwise configure other optimization aspects
Expand Down Expand Up @@ -530,11 +535,21 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
f(cpm);
}

if config.emit_bc {
let ext = format!("{}.bc", name_extra);
let out = output_names.with_extension(&ext);
let out = path2cstr(&out);
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
// Change what we write and cleanup based on whether obj files are
// just llvm bitcode. In that case write bitcode, and possibly
// delete the bitcode if it wasn't requested. Don't generate the
// machine code, instead copy the .o file from the .bc
let write_bc = config.emit_bc || config.obj_is_bitcode;
let rm_bc = !config.emit_bc && config.obj_is_bitcode;
let write_obj = config.emit_obj && !config.obj_is_bitcode;
let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode;

let bc_out = output_names.with_extension(&format!("{}.bc", name_extra));
let obj_out = output_names.with_extension(&format!("{}.o", name_extra));

if write_bc {
let bc_out_c = path2cstr(&bc_out);
llvm::LLVMWriteBitcodeToFile(llmod, bc_out_c.as_ptr());
}

time(config.time_passes, &format!("codegen passes [{}]", cgcx.worker), || {
Expand Down Expand Up @@ -568,14 +583,27 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
}
}

if config.emit_obj {
let path = output_names.with_extension(&format!("{}.o", name_extra));
if write_obj {
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::ObjectFileType);
write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out, llvm::ObjectFileType);
});
}
});

if copy_bc_to_obj {
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
if let Err(e) = fs::copy(&bc_out, &obj_out) {
cgcx.handler.err(&format!("failed to copy bitcode to object file: {}", e));
}
}

if rm_bc {
debug!("removing_bitcode {:?}", bc_out);
if let Err(e) = fs::remove_file(&bc_out) {
cgcx.handler.err(&format!("failed to remove bitcode: {}", e));
}
}

llvm::LLVMDisposeModule(llmod);
llvm::LLVMContextDispose(llcx);
llvm::LLVMRustDisposeTargetMachine(tm);
Expand Down

0 comments on commit 81ba4a7

Please sign in to comment.