]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_codegen_llvm/back/write.rs
Removed code duplication for CommonWriteMethods
[rust.git] / src / librustc_codegen_llvm / back / write.rs
index 184be4b9eab39d76841af69ce451f065c2ee9757..24f58ac59c15ca244880c284de920531d9c9e178 100644 (file)
@@ -24,7 +24,7 @@
 use rustc::session::Session;
 use rustc::util::nodemap::FxHashMap;
 use time_graph::{self, TimeGraph, Timeline};
-use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
+use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic, BasicBlock};
 use llvm_util;
 use {CodegenResults, ModuleCodegen, CompiledModule, ModuleKind, // ModuleLlvm,
      CachedModuleCodegen};
 use syntax_pos::symbol::Symbol;
 use type_::Type;
 use context::{is_pie_binary, get_reloc_model};
-use common::{C_bytes_in_context, val_ty};
+use interfaces::{Backend, CommonWriteMethods};
+use common;
 use jobserver::{Client, Acquired};
 use rustc_demangle;
+use value::Value;
+use std::marker::PhantomData;
 
 use std::any::Any;
 use std::ffi::{CString, CStr};
@@ -64,7 +67,7 @@
 use std::thread;
 use libc::{c_uint, c_void, c_char, size_t};
 
-pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 7] = [
+pub const RELOC_MODEL_ARGS : [(&str, llvm::RelocMode); 7] = [
     ("pic", llvm::RelocMode::PIC),
     ("static", llvm::RelocMode::Static),
     ("default", llvm::RelocMode::Default),
@@ -81,7 +84,7 @@
     ("large", llvm::CodeModel::Large),
 ];
 
-pub const TLS_MODEL_ARGS : [(&'static str, llvm::ThreadLocalMode); 4] = [
+pub const TLS_MODEL_ARGS : [(&str, llvm::ThreadLocalMode); 4] = [
     ("global-dynamic", llvm::ThreadLocalMode::GeneralDynamic),
     ("local-dynamic", llvm::ThreadLocalMode::LocalDynamic),
     ("initial-exec", llvm::ThreadLocalMode::InitialExec),
@@ -90,7 +93,7 @@
 
 const PRE_THIN_LTO_BC_EXT: &str = "pre-thin-lto.bc";
 
-pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError {
+pub fn llvm_err(handler: &errors::Handler, msg: &str) -> FatalError {
     match llvm::last_error() {
         Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
         None => handler.fatal(&msg),
@@ -106,11 +109,10 @@ pub fn write_output_file(
         file_type: llvm::FileType) -> Result<(), FatalError> {
     unsafe {
         let output_c = path2cstr(output);
-        let result = llvm::LLVMRustWriteOutputFile(
-                target, pm, m, output_c.as_ptr(), file_type);
+        let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
         if result.into_result().is_err() {
             let msg = format!("could not write output to {}", output.display());
-            Err(llvm_err(handler, msg))
+            Err(llvm_err(handler, &msg))
         } else {
             Ok(())
         }
@@ -140,7 +142,7 @@ pub fn create_target_machine(
     find_features: bool,
 ) -> &'static mut llvm::TargetMachine {
     target_machine_factory(sess, find_features)().unwrap_or_else(|err| {
-        llvm_err(sess.diagnostic(), err).raise()
+        llvm_err(sess.diagnostic(), &err).raise()
     })
 }
 
@@ -352,7 +354,7 @@ struct AssemblerCommand {
 
 /// Additional resources used by optimize_and_codegen (not module specific)
 #[derive(Clone)]
-pub struct CodegenContext {
+pub struct CodegenContext<'ll> {
     // Resources needed when running LTO
     pub time_passes: bool,
     pub lto: Lto,
@@ -394,9 +396,12 @@ pub struct CodegenContext {
     time_graph: Option<TimeGraph>,
     // The assembler command if no_integrated_as option is enabled, None otherwise
     assembler_cmd: Option<Arc<AssemblerCommand>>,
+    // This field is used to give a lifetime parameter to the struct so that it can implement
+    // the Backend trait.
+    phantom: PhantomData<&'ll ()>
 }
 
-impl CodegenContext {
+impl CodegenContext<'ll> {
     pub fn create_diag_handler(&self) -> Handler {
         Handler::with_emitter(true, false, Box::new(self.diag_emitter.clone()))
     }
@@ -424,13 +429,40 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
     }
 }
 
+impl<'ll> Backend for CodegenContext<'ll> {
+    type Value = &'ll Value;
+    type BasicBlock = &'ll BasicBlock;
+    type Type = &'ll Type;
+    type Context = &'ll llvm::Context;
+}
+
+impl CommonWriteMethods for CodegenContext<'ll> {
+    fn val_ty(&self, v: &'ll Value) -> &'ll Type {
+        common::val_ty(v)
+    }
+
+    fn c_bytes_in_context(&self, llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value {
+        common::c_bytes_in_context(llcx, bytes)
+    }
+
+    fn c_struct_in_context(
+        &self,
+        llcx: &'a llvm::Context,
+        elts: &[&'a Value],
+        packed: bool,
+    ) -> &'a Value {
+        common::c_struct_in_context(llcx, elts, packed)
+    }
+}
+
+
 pub struct DiagnosticHandlers<'a> {
-    data: *mut (&'a CodegenContext, &'a Handler),
+    data: *mut (&'a CodegenContext<'a>, &'a Handler),
     llcx: &'a llvm::Context,
 }
 
 impl<'a> DiagnosticHandlers<'a> {
-    pub fn new(cgcx: &'a CodegenContext,
+    pub fn new(cgcx: &'a CodegenContext<'a>,
                handler: &'a Handler,
                llcx: &'a llvm::Context) -> Self {
         let data = Box::into_raw(Box::new((cgcx, handler)));
@@ -456,7 +488,7 @@ fn drop(&mut self) {
 unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext,
                                                msg: &'b str,
                                                cookie: c_uint) {
-    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_string());
+    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
 }
 
 unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic,
@@ -590,8 +622,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
 
             for pass in &config.passes {
                 if !addpass(pass) {
-                    diag_handler.warn(&format!("unknown pass `{}`, ignoring",
-                                            pass));
+                    diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass));
                 }
                 if pass == "name-anon-globals" {
                     have_name_anon_globals_pass = true;
@@ -601,8 +632,8 @@ unsafe fn optimize(cgcx: &CodegenContext,
             for pass in &cgcx.plugin_passes {
                 if !addpass(pass) {
                     diag_handler.err(&format!("a plugin asked for LLVM pass \
-                                            `{}` but LLVM does not \
-                                            recognize it", pass));
+                                               `{}` but LLVM does not \
+                                               recognize it", pass));
                 }
                 if pass == "name-anon-globals" {
                     have_name_anon_globals_pass = true;
@@ -613,12 +644,12 @@ unsafe fn optimize(cgcx: &CodegenContext,
                 // As described above, this will probably cause an error in LLVM
                 if config.no_prepopulate_passes {
                     diag_handler.err("The current compilation is going to use thin LTO buffers \
-                                     without running LLVM's NameAnonGlobals pass. \
-                                     This will likely cause errors in LLVM. Consider adding \
-                                     -C passes=name-anon-globals to the compiler command line.");
+                                      without running LLVM's NameAnonGlobals pass. \
+                                      This will likely cause errors in LLVM. Consider adding \
+                                      -C passes=name-anon-globals to the compiler command line.");
                 } else {
                     bug!("We are using thin LTO buffers without running the NameAnonGlobals pass. \
-                         This will likely cause errors in LLVM and should never happen.");
+                          This will likely cause errors in LLVM and should never happen.");
                 }
             }
         }
@@ -704,9 +735,9 @@ unsafe fn codegen(cgcx: &CodegenContext,
         // escape the closure itself, and the manager should only be
         // used once.
         unsafe fn with_codegen<'ll, F, R>(tm: &'ll llvm::TargetMachine,
-                                    llmod: &'ll llvm::Module,
-                                    no_builtins: bool,
-                                    f: F) -> R
+                                          llmod: &'ll llvm::Module,
+                                          no_builtins: bool,
+                                          f: F) -> R
             where F: FnOnce(&'ll mut PassManager<'ll>) -> R,
         {
             let cpm = llvm::LLVMCreatePassManager();
@@ -818,7 +849,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
                 };
                 with_codegen(tm, llmod, config.no_builtins, |cpm| {
                     write_output_file(diag_handler, tm, cpm, llmod, &path,
-                                    llvm::FileType::AssemblyFile)
+                                      llvm::FileType::AssemblyFile)
                 })?;
                 timeline.record("asm");
             }
@@ -826,7 +857,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
             if write_obj {
                 with_codegen(tm, llmod, config.no_builtins, |cpm| {
                     write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
-                                    llvm::FileType::ObjectFile)
+                                      llvm::FileType::ObjectFile)
                 })?;
                 timeline.record("obj");
             } else if asm_to_obj {
@@ -886,10 +917,10 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
                         llcx: &llvm::Context,
                         llmod: &llvm::Module,
                         bitcode: Option<&[u8]>) {
-    let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
+    let llconst = cgcx.c_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
     let llglobal = llvm::LLVMAddGlobal(
         llmod,
-        val_ty(llconst),
+        cgcx.val_ty(llconst),
         "rustc.embedded.module\0".as_ptr() as *const _,
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
@@ -906,10 +937,10 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
     llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
     llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
 
-    let llconst = C_bytes_in_context(llcx, &[]);
+    let llconst = cgcx.c_bytes_in_context(llcx, &[]);
     let llglobal = llvm::LLVMAddGlobal(
         llmod,
-        val_ty(llconst),
+        cgcx.val_ty(llconst),
         "rustc.embedded.cmdline\0".as_ptr() as *const _,
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
@@ -947,11 +978,11 @@ fn need_pre_thin_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
 }
 
 pub fn start_async_codegen(tcx: TyCtxt,
-                               time_graph: Option<TimeGraph>,
-                               metadata: EncodedMetadata,
-                               coordinator_receive: Receiver<Box<dyn Any + Send>>,
-                               total_cgus: usize)
-                               -> OngoingCodegen {
+                           time_graph: Option<TimeGraph>,
+                           metadata: EncodedMetadata,
+                           coordinator_receive: Receiver<Box<dyn Any + Send>>,
+                           total_cgus: usize)
+                           -> OngoingCodegen {
     let sess = tcx.sess;
     let crate_name = tcx.crate_name(LOCAL_CRATE);
     let crate_hash = tcx.crate_hash(LOCAL_CRATE);
@@ -1116,7 +1147,8 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
         }
 
         if let Some((id, product)) =
-                copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files) {
+            copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files)
+        {
             work_products.insert(id, product);
         }
     }
@@ -1441,15 +1473,12 @@ fn execute_copy_from_cache_work_item(cgcx: &CodegenContext,
                module.name,
                source_file,
                obj_out.display());
-        match link_or_copy(&source_file, &obj_out) {
-            Ok(_) => { }
-            Err(err) => {
-                let diag_handler = cgcx.create_diag_handler();
-                diag_handler.err(&format!("unable to copy {} to {}: {}",
-                                          source_file.display(),
-                                          obj_out.display(),
-                                          err));
-            }
+        if let Err(err) = link_or_copy(&source_file, &obj_out) {
+            let diag_handler = cgcx.create_diag_handler();
+            diag_handler.err(&format!("unable to copy {} to {}: {}",
+                                      source_file.display(),
+                                      obj_out.display(),
+                                      err));
         }
     }
 
@@ -1584,10 +1613,8 @@ fn start_executing_work(tcx: TyCtxt,
 
         let (name, mut cmd) = get_linker(sess, &linker, flavor);
         cmd.args(&sess.target.target.options.asm_args);
-        Some(Arc::new(AssemblerCommand {
-            name,
-            cmd,
-        }))
+
+        Some(Arc::new(AssemblerCommand { name, cmd }))
     } else {
         None
     };
@@ -1620,6 +1647,7 @@ fn start_executing_work(tcx: TyCtxt,
         target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(),
         debuginfo: tcx.sess.opts.debuginfo,
         assembler_cmd,
+        phantom: PhantomData
     };
 
     // This is the "main loop" of parallel work happening for parallel codegen.
@@ -2114,7 +2142,7 @@ fn maybe_start_llvm_timer(config: &ModuleConfig,
 const LLVM_WORK_PACKAGE_KIND: time_graph::WorkPackageKind =
     time_graph::WorkPackageKind(&["#7DB67A", "#C6EEC4", "#ACDAAA", "#579354", "#3E6F3C"]);
 
-fn spawn_work(cgcx: CodegenContext, work: WorkItem) {
+fn spawn_work(cgcx: CodegenContext<'static>, work: WorkItem) {
     let depth = time_depth();
 
     thread::spawn(move || {
@@ -2186,9 +2214,9 @@ pub fn run_assembler(cgcx: &CodegenContext, handler: &Handler, assembly: &Path,
                 handler.struct_err(&format!("linking with `{}` failed: {}",
                                             pname.display(),
                                             prog.status))
-                    .note(&format!("{:?}", &cmd))
-                    .note(str::from_utf8(&note[..]).unwrap())
-                    .emit();
+                       .note(&format!("{:?}", &cmd))
+                       .note(str::from_utf8(&note[..]).unwrap())
+                       .emit();
                 handler.abort_if_errors();
             }
         },
@@ -2450,8 +2478,8 @@ pub(crate) fn join(
     }
 
     pub(crate) fn submit_pre_codegened_module_to_llvm(&self,
-                                                       tcx: TyCtxt,
-                                                       module: ModuleCodegen) {
+                                                      tcx: TyCtxt,
+                                                      module: ModuleCodegen) {
         self.wait_for_signal_to_codegen_item();
         self.check_for_errors(tcx.sess);