rustc: Add obj_is_bitcode to TargetOptions
This tells trans:🔙: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.
This commit is contained in:
parent
d6c0d859f6
commit
81ba4a78b5
3 changed files with 44 additions and 10 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -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 { }
|
||||
|
|
@ -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,
|
||||
|
|
@ -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
|
||||
|
|
@ -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), || {
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue