diff options
| author | Denis Merigoux <denis.merigoux@gmail.com> | 2018-08-29 18:42:25 +0200 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2018-11-16 14:11:59 +0200 |
| commit | 4cc18d3de50b6540e53ddcfefb88dee9ed991264 (patch) | |
| tree | 7d7cc48d8ddff1b195f9b3caec2138a104b4dc12 /src/librustc_codegen_llvm | |
| parent | 3aee77277efbac0b9b14b2097ea8a2c449fb1fc3 (diff) | |
| download | rust-4cc18d3de50b6540e53ddcfefb88dee9ed991264.tar.gz rust-4cc18d3de50b6540e53ddcfefb88dee9ed991264.zip | |
CommonWriteMethods are not static any more
Diffstat (limited to 'src/librustc_codegen_llvm')
| -rw-r--r-- | src/librustc_codegen_llvm/back/lto.rs | 2 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/back/write.rs | 66 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/base.rs | 25 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/builder.rs | 16 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/callee.rs | 4 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/common.rs | 64 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/consts.rs | 6 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/interfaces/common.rs | 15 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/lib.rs | 58 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/mir/rvalue.rs | 8 |
10 files changed, 179 insertions, 85 deletions
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 60b06c579cb..95b1b6ff3ce 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -26,6 +26,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_codegen_utils::symbol_export; use time_graph::Timeline; use {ModuleCodegen, ModuleLlvm, ModuleKind}; +use std::marker::PhantomData; use libc; @@ -767,6 +768,7 @@ impl ThinModule { llmod_raw, llcx, tm, + phantom: PhantomData }, name: self.name().to_string(), kind: ModuleKind::Regular, diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 5d23ff27c49..3c32da43031 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -24,7 +24,7 @@ use rustc::session::config::{self, OutputFilenames, OutputType, Passes, Sanitize 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, True}; use llvm_util; use {CodegenResults, ModuleCodegen, CompiledModule, ModuleKind, // ModuleLlvm, CachedModuleCodegen}; @@ -45,10 +45,12 @@ use syntax::ext::hygiene::Mark; use syntax_pos::MultiSpan; use syntax_pos::symbol::Symbol; use type_::Type; -use context::{is_pie_binary, get_reloc_model, CodegenCx}; -use interfaces::CommonWriteMethods; +use context::{is_pie_binary, get_reloc_model}; +use interfaces::{Backend, CommonWriteMethods}; use jobserver::{Client, Acquired}; use rustc_demangle; +use value::Value; +use std::marker::PhantomData; use std::any::Any; use std::ffi::{CString, CStr}; @@ -351,7 +353,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, @@ -393,9 +395,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())) } @@ -423,13 +428,49 @@ impl CodegenContext { } } +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 { + unsafe { + llvm::LLVMTypeOf(v) + } + } + + fn c_bytes_in_context(&self, llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { + unsafe { + let ptr = bytes.as_ptr() as *const c_char; + return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True); + } + } + + fn c_struct_in_context( + &self, + llcx: &'a llvm::Context, + elts: &[&'a Value], + packed: bool, + ) -> &'a Value { + unsafe { + llvm::LLVMConstStructInContext(llcx, + elts.as_ptr(), elts.len() as c_uint, + packed as llvm::Bool) + } + } +} + + 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))); @@ -884,10 +925,10 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::Module, bitcode: Option<&[u8]>) { - let llconst = CodegenCx::c_bytes_in_context(llcx, bitcode.unwrap_or(&[])); + let llconst = cgcx.c_bytes_in_context(llcx, bitcode.unwrap_or(&[])); let llglobal = llvm::LLVMAddGlobal( llmod, - CodegenCx::val_ty(llconst), + cgcx.val_ty(llconst), "rustc.embedded.module\0".as_ptr() as *const _, ); llvm::LLVMSetInitializer(llglobal, llconst); @@ -904,10 +945,10 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext, llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); llvm::LLVMSetGlobalConstant(llglobal, llvm::True); - let llconst = CodegenCx::c_bytes_in_context(llcx, &[]); + let llconst = cgcx.c_bytes_in_context(llcx, &[]); let llglobal = llvm::LLVMAddGlobal( llmod, - CodegenCx::val_ty(llconst), + cgcx.val_ty(llconst), "rustc.embedded.cmdline\0".as_ptr() as *const _, ); llvm::LLVMSetInitializer(llglobal, llconst); @@ -1614,6 +1655,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. @@ -2108,7 +2150,7 @@ pub const CODEGEN_WORK_PACKAGE_KIND: time_graph::WorkPackageKind = 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 || { diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 2a4d549adcb..6a2f437b1da 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -334,12 +334,13 @@ pub fn coerce_unsized_into( } pub fn cast_shift_expr_rhs( - cx: &Builder<'_, 'll, '_>, op: hir::BinOpKind, lhs: &'ll Value, rhs: &'ll Value + bx: &Builder<'_, 'll, '_>, op: hir::BinOpKind, lhs: &'ll Value, rhs: &'ll Value ) -> &'ll Value { - cast_shift_rhs(op, lhs, rhs, |a, b| cx.trunc(a, b), |a, b| cx.zext(a, b)) + cast_shift_rhs(bx, op, lhs, rhs, |a, b| bx.trunc(a, b), |a, b| bx.zext(a, b)) } -fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind, +fn cast_shift_rhs<'ll, F, G>(bx: &Builder<'_, 'll, '_>, + op: hir::BinOpKind, lhs: &'ll Value, rhs: &'ll Value, trunc: F, @@ -350,8 +351,8 @@ fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind, { // Shifts may have any size int on the rhs if op.is_shift() { - let mut rhs_llty = CodegenCx::val_ty(rhs); - let mut lhs_llty = CodegenCx::val_ty(lhs); + let mut rhs_llty = bx.cx().val_ty(rhs); + let mut lhs_llty = bx.cx().val_ty(lhs); if rhs_llty.kind() == TypeKind::Vector { rhs_llty = rhs_llty.element_type() } @@ -392,7 +393,7 @@ pub fn from_immediate<'a, 'll: 'a, 'tcx: 'll>( bx: &Builder<'_ ,'ll, '_, &'ll Value>, val: &'ll Value ) -> &'ll Value { - if CodegenCx::val_ty(val) == Type::i1(bx.cx()) { + if bx.cx().val_ty(val) == Type::i1(bx.cx()) { bx.zext(val, Type::i8(bx.cx())) } else { val @@ -433,7 +434,7 @@ pub fn call_memcpy<'a, 'll: 'a, 'tcx: 'll>( if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memcpy. let val = bx.load(src, src_align); - let ptr = bx.pointercast(dst, CodegenCx::val_ty(val).ptr_to()); + let ptr = bx.pointercast(dst, bx.cx().val_ty(val).ptr_to()); bx.store_with_flags(val, ptr, dst_align, flags); return; } @@ -648,12 +649,12 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, DeflateEncoder::new(&mut compressed, Compression::fast()) .write_all(&metadata.raw_data).unwrap(); - let llmeta = CodegenCx::c_bytes_in_context(metadata_llcx, &compressed); - let llconst = CodegenCx::c_struct_in_context(metadata_llcx, &[llmeta], false); + let llmeta = llvm_module.c_bytes_in_context(metadata_llcx, &compressed); + let llconst = llvm_module.c_struct_in_context(metadata_llcx, &[llmeta], false); let name = exported_symbols::metadata_symbol_name(tcx); let buf = CString::new(name).unwrap(); let llglobal = unsafe { - llvm::LLVMAddGlobal(metadata_llmod, CodegenCx::val_ty(llconst), buf.as_ptr()) + llvm::LLVMAddGlobal(metadata_llmod, llvm_module.val_ty(llconst), buf.as_ptr()) }; unsafe { llvm::LLVMSetInitializer(llglobal, llconst); @@ -1139,7 +1140,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Run replace-all-uses-with for statics that need it for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() { unsafe { - let bitcast = llvm::LLVMConstPointerCast(new_g, CodegenCx::val_ty(old_g)); + let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g)); llvm::LLVMReplaceAllUsesWith(old_g, bitcast); llvm::LLVMDeleteGlobal(old_g); } @@ -1154,7 +1155,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, unsafe { let g = llvm::LLVMAddGlobal(cx.llmod, - CodegenCx::val_ty(array), + cx.val_ty(array), name.as_ptr()); llvm::LLVMSetInitializer(g, array); llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage); diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 8a6cf1335cd..2aaccd3c4f8 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -527,7 +527,7 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> { } unsafe { - let llty = CodegenCx::val_ty(load); + let llty = self.cx.val_ty(load); let v = [ self.cx.c_uint_big(llty, range.start), self.cx.c_uint_big(llty, range.end) @@ -760,7 +760,7 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> { let argtys = inputs.iter().map(|v| { debug!("Asm Input Type: {:?}", *v); - CodegenCx::val_ty(*v) + self.cx.val_ty(*v) }).collect::<Vec<_>>(); debug!("Asm Output Type: {:?}", output); @@ -859,7 +859,7 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> { fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value { unsafe { - let elt_ty = CodegenCx::val_ty(elt); + let elt_ty = self.cx.val_ty(elt); let undef = llvm::LLVMGetUndef(type_::Type::vector(elt_ty, num_elts as u64)); let vec = self.insert_element(undef, elt, CodegenCx::c_i32(self.cx, 0)); let vec_i32_ty = type_::Type::vector(type_::Type::i32(self.cx), num_elts as u64); @@ -1139,8 +1139,8 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> { fn check_store<'b>(&self, val: &'ll Value, ptr: &'ll Value) -> &'ll Value { - let dest_ptr_ty = CodegenCx::val_ty(ptr); - let stored_ty = CodegenCx::val_ty(val); + let dest_ptr_ty = self.cx.val_ty(ptr); + let stored_ty = self.cx.val_ty(val); let stored_ptr_ty = stored_ty.ptr_to(); assert_eq!(dest_ptr_ty.kind(), llvm::TypeKind::Pointer); @@ -1160,7 +1160,7 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> { typ: &str, llfn: &'ll Value, args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> { - let mut fn_ty = CodegenCx::val_ty(llfn); + let mut fn_ty = self.cx.val_ty(llfn); // Strip off pointers while fn_ty.kind() == llvm::TypeKind::Pointer { fn_ty = fn_ty.element_type(); @@ -1172,7 +1172,7 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> { let param_tys = fn_ty.func_params(); let all_args_match = param_tys.iter() - .zip(args.iter().map(|&v| CodegenCx::val_ty(v))) + .zip(args.iter().map(|&v| self.cx().val_ty(v))) .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); if all_args_match { @@ -1183,7 +1183,7 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> { .zip(args.iter()) .enumerate() .map(|(i, (expected_ty, &actual_val))| { - let actual_ty = CodegenCx::val_ty(actual_val); + let actual_ty = self.cx().val_ty(actual_val); if expected_ty != actual_ty { debug!("Type mismatch in function call of {:?}. \ Expected {:?} for param {}, got {:?}; injecting bitcast", diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index a593cd64efe..a58692d5f41 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -84,7 +84,7 @@ pub fn get_fn( // This can occur on either a crate-local or crate-external // reference. It also occurs when testing libcore and in some // other weird situations. Annoying. - if CodegenCx::val_ty(llfn) != llptrty { + if cx.val_ty(llfn) != llptrty { debug!("get_fn: casting {:?} to {:?}", llfn, llptrty); consts::ptrcast(llfn, llptrty) } else { @@ -93,7 +93,7 @@ pub fn get_fn( } } else { let llfn = declare::declare_fn(cx, &sym, sig); - assert_eq!(CodegenCx::val_ty(llfn), llptrty); + assert_eq!(cx.val_ty(llfn), llptrty); debug!("get_fn: not casting pointer!"); if instance.def.is_inline(tcx) { diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index cf88a973162..ba8d92d37ac 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -282,7 +282,7 @@ impl<'ll, 'tcx : 'll> CommonMethods for CodegenCx<'ll, 'tcx> { s.len() as c_uint, !null_terminated as Bool); let sym = &self.generate_local_symbol_name("str"); - let g = declare::define_global(&self, &sym[..], Self::val_ty(sc)).unwrap_or_else(||{ + let g = declare::define_global(&self, &sym[..], &self.val_ty(sc)).unwrap_or_else(||{ bug!("symbol `{}` is already defined", sym); }); llvm::LLVMSetInitializer(g, sc); @@ -318,19 +318,7 @@ impl<'ll, 'tcx : 'll> CommonMethods for CodegenCx<'ll, 'tcx> { elts: &[&'ll Value], packed: bool ) -> &'ll Value { - Self::c_struct_in_context(&self.llcx, elts, packed) - } - - fn c_struct_in_context( - llcx: &'a llvm::Context, - elts: &[&'a Value], - packed: bool, - ) -> &'a Value { - unsafe { - llvm::LLVMConstStructInContext(llcx, - elts.as_ptr(), elts.len() as c_uint, - packed as Bool) - } + &self.c_struct_in_context(&self.llcx, elts, packed) } fn c_array(ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value { @@ -346,7 +334,7 @@ impl<'ll, 'tcx : 'll> CommonMethods for CodegenCx<'ll, 'tcx> { } fn c_bytes(&self, bytes: &[u8]) -> &'ll Value { - Self::c_bytes_in_context(&self.llcx, bytes) + &self.c_bytes_in_context(&self.llcx, bytes) } fn const_get_elt(v: &'ll Value, idx: u64) -> &'ll Value { @@ -411,6 +399,35 @@ impl<'ll, 'tcx : 'll> CommonMethods for CodegenCx<'ll, 'tcx> { } } +impl<'ll, 'tcx : 'll> CommonWriteMethods for CodegenCx<'ll, 'tcx> { + fn val_ty(&self, v: &'ll Value) -> &'ll Type { + unsafe { + llvm::LLVMTypeOf(v) + } + } + + fn c_bytes_in_context(&self, llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { + unsafe { + let ptr = bytes.as_ptr() as *const c_char; + return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True); + } + } + + fn c_struct_in_context( + &self, + llcx: &'a llvm::Context, + elts: &[&'a Value], + packed: bool, + ) -> &'a Value { + unsafe { + llvm::LLVMConstStructInContext(llcx, + elts.as_ptr(), elts.len() as c_uint, + packed as Bool) + } + } +} + + #[inline] fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 { ((hi as u128) << 64) | (lo as u128) @@ -461,7 +478,7 @@ pub fn build_unchecked_rshift( } fn shift_mask_rhs(bx: &Builder<'a, 'll, 'tcx>, rhs: &'ll Value) -> &'ll Value { - let rhs_llty = CodegenCx::val_ty(rhs); + let rhs_llty = bx.cx().val_ty(rhs); bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false)) } @@ -489,18 +506,3 @@ pub fn shift_mask_val( _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind), } } - -impl<'ll, 'tcx : 'll> CommonWriteMethods for CodegenCx<'ll, 'tcx> { - fn val_ty(v: &'ll Value) -> &'ll Type { - unsafe { - llvm::LLVMTypeOf(v) - } - } - - fn c_bytes_in_context(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { - unsafe { - let ptr = bytes.as_ptr() as *const c_char; - return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True); - } - } -} diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index a97614e4e50..f8f759365c0 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -74,13 +74,13 @@ pub fn addr_of_mut( Some(kind) if !cx.tcx.sess.fewer_names() => { let name = cx.generate_local_symbol_name(kind); let gv = declare::define_global(cx, &name[..], - CodegenCx::val_ty(cv)).unwrap_or_else(||{ + cx.val_ty(cv)).unwrap_or_else(||{ bug!("symbol `{}` is already defined", name); }); llvm::LLVMRustSetLinkage(gv, llvm::Linkage::PrivateLinkage); gv }, - _ => declare::define_private_global(cx, CodegenCx::val_ty(cv)), + _ => declare::define_private_global(cx, cx.val_ty(cv)), }; llvm::LLVMSetInitializer(gv, cv); set_global_alignment(cx, gv, align); @@ -312,7 +312,7 @@ pub fn codegen_static<'a, 'tcx>( // boolean SSA values are i1, but they have to be stored in i8 slots, // otherwise some LLVM optimization passes don't work as expected - let mut val_llty = CodegenCx::val_ty(v); + let mut val_llty = cx.val_ty(v); let v = if val_llty == Type::i1(cx) { val_llty = Type::i8(cx); llvm::LLVMConstZExt(v, val_llty) diff --git a/src/librustc_codegen_llvm/interfaces/common.rs b/src/librustc_codegen_llvm/interfaces/common.rs index f58338f384f..9eaf94cff66 100644 --- a/src/librustc_codegen_llvm/interfaces/common.rs +++ b/src/librustc_codegen_llvm/interfaces/common.rs @@ -40,11 +40,6 @@ pub trait CommonMethods : Backend + CommonWriteMethods { elts: &[Self::Value], packed: bool ) -> Self::Value; - fn c_struct_in_context( - llcx: Self::Context, - elts: &[Self::Value], - packed: bool, - ) -> Self::Value; fn c_array(ty: Self::Type, elts: &[Self::Value]) -> Self::Value; fn c_vector(elts: &[Self::Value]) -> Self::Value; fn c_bytes(&self, bytes: &[u8]) -> Self::Value; @@ -58,6 +53,12 @@ pub trait CommonMethods : Backend + CommonWriteMethods { } pub trait CommonWriteMethods : Backend { - fn val_ty(v: Self::Value) -> Self::Type; - fn c_bytes_in_context(llcx: Self::Context, bytes: &[u8]) -> Self::Value; + fn val_ty(&self, v: Self::Value) -> Self::Type; + fn c_bytes_in_context(&self, llcx: Self::Context, bytes: &[u8]) -> Self::Value; + fn c_struct_in_context( + &self, + llcx: Self::Context, + elts: &[Self::Value], + packed: bool, + ) -> Self::Value; } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 43942b0db85..2ef90c03c67 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -68,10 +68,15 @@ extern crate tempfile; extern crate memmap; use back::bytecode::RLIB_BYTECODE_EXTENSION; +use interfaces::{Backend, CommonWriteMethods}; +use value::Value; +use type_::Type; pub use llvm_util::target_features; use std::any::Any; use std::sync::mpsc; +use std::marker::PhantomData; +use libc::{c_uint, c_char}; use rustc_data_structures::sync::Lrc; use rustc::dep_graph::DepGraph; @@ -273,7 +278,7 @@ struct ModuleCodegen { /// as the crate name and disambiguator. /// We currently generate these names via CodegenUnit::build_cgu_name(). name: String, - module_llvm: ModuleLlvm, + module_llvm: ModuleLlvm<'static>, kind: ModuleKind, } @@ -315,16 +320,24 @@ impl ModuleCodegen { } } -struct ModuleLlvm { +struct ModuleLlvm<'ll> { llcx: &'static mut llvm::Context, llmod_raw: *const llvm::Module, tm: &'static mut llvm::TargetMachine, + phantom: PhantomData<&'ll ()> } -unsafe impl Send for ModuleLlvm { } -unsafe impl Sync for ModuleLlvm { } +impl<'ll> Backend for ModuleLlvm<'ll> { + type Value = &'ll Value; + type BasicBlock = &'ll llvm::BasicBlock; + type Type = &'ll Type; + type Context = &'ll llvm::Context; +} + +unsafe impl Send for ModuleLlvm<'ll> { } +unsafe impl Sync for ModuleLlvm<'ll> { } -impl ModuleLlvm { +impl ModuleLlvm<'ll> { fn new(sess: &Session, mod_name: &str) -> Self { unsafe { let llcx = llvm::LLVMRustContextCreate(sess.fewer_names()); @@ -334,6 +347,7 @@ impl ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(sess, false), + phantom: PhantomData } } } @@ -345,7 +359,39 @@ impl ModuleLlvm { } } -impl Drop for ModuleLlvm { +impl CommonWriteMethods for ModuleLlvm<'ll> { + fn val_ty(&self, v: &'ll Value) -> &'ll Type { + unsafe { + llvm::LLVMTypeOf(v) + } + } + + fn c_bytes_in_context(&self, llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { + unsafe { + let ptr = bytes.as_ptr() as *const c_char; + return llvm::LLVMConstStringInContext( + llcx, + ptr, + bytes.len() as c_uint, + llvm::True); + } + } + + fn c_struct_in_context( + &self, + llcx: &'a llvm::Context, + elts: &[&'a Value], + packed: bool, + ) -> &'a Value { + unsafe { + llvm::LLVMConstStructInContext(llcx, + elts.as_ptr(), elts.len() as c_uint, + packed as llvm::Bool) + } + } +} + +impl Drop for ModuleLlvm<'ll> { fn drop(&mut self) { unsafe { llvm::LLVMContextDispose(&mut *(self.llcx as *mut _)); diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs index 889bfeeb8ca..3c469cffaf3 100644 --- a/src/librustc_codegen_llvm/mir/rvalue.rs +++ b/src/librustc_codegen_llvm/mir/rvalue.rs @@ -118,7 +118,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> { // Use llvm.memset.p0i8.* to initialize byte arrays let v = base::from_immediate(&bx, v); - if CodegenCx::val_ty(v) == Type::i8(bx.cx()) { + if bx.cx().val_ty(v) == Type::i8(bx.cx()) { base::call_memset(&bx, start, v, size, align, false); return bx; } @@ -132,7 +132,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> { let next_bx = bx.build_sibling_block("repeat_loop_next"); bx.br(header_bx.llbb()); - let current = header_bx.phi(CodegenCx::val_ty(start), &[start], &[bx.llbb()]); + let current = header_bx.phi(bx.cx().val_ty(start), &[start], &[bx.llbb()]); let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end); header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb()); @@ -705,8 +705,8 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> { bx.extract_value(res, 1)) } mir::BinOp::Shl | mir::BinOp::Shr => { - let lhs_llty = CodegenCx::val_ty(lhs); - let rhs_llty = CodegenCx::val_ty(rhs); + let lhs_llty = bx.cx().val_ty(lhs); + let rhs_llty = bx.cx().val_ty(rhs); let invert_mask = common::shift_mask_val(&bx, lhs_llty, rhs_llty, true); let outer_bits = bx.and(rhs, invert_mask); |
