From 2b688a959def6d3441d3e4854fde557de0913e36 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 12:54:54 +0100 Subject: [PATCH 01/18] Don't use c_uint in cg_ssa --- src/librustc_codegen_llvm/context.rs | 4 ++-- src/librustc_codegen_ssa/mir/mod.rs | 13 ++++++------- src/librustc_codegen_ssa/traits/misc.rs | 3 +-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 619304ad9afd0..0060751d60641 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -326,8 +326,8 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { get_fn(self, instance) } - fn get_param(&self, llfn: &'ll Value, index: c_uint) -> &'ll Value { - llvm::get_param(llfn, index) + fn get_param(&self, llfn: &'ll Value, index: usize) -> &'ll Value { + llvm::get_param(llfn, index as c_uint) } fn eh_personality(&self) -> &'ll Value { diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index bc77097425bd1..b0f53de17ea31 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -1,4 +1,3 @@ -use libc::c_uint; use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; use rustc::ty::layout::{TyLayout, HasTyCtxt}; use rustc::mir::{self, Mir}; @@ -534,18 +533,18 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( } PassMode::Ignore(IgnoreMode::CVarArgs) => {} PassMode::Direct(_) => { - let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint); + let llarg = bx.get_param(bx.llfn(), llarg_idx); bx.set_value_name(llarg, &name); llarg_idx += 1; return local( OperandRef::from_immediate_or_packed_pair(bx, llarg, arg.layout)); } PassMode::Pair(..) => { - let a = bx.get_param(bx.llfn(), llarg_idx as c_uint); + let a = bx.get_param(bx.llfn(), llarg_idx); bx.set_value_name(a, &(name.clone() + ".0")); llarg_idx += 1; - let b = bx.get_param(bx.llfn(), llarg_idx as c_uint); + let b = bx.get_param(bx.llfn(), llarg_idx); bx.set_value_name(b, &(name + ".1")); llarg_idx += 1; @@ -562,16 +561,16 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Don't copy an indirect argument to an alloca, the caller // already put it in a temporary alloca and gave it up. // FIXME: lifetimes - let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint); + let llarg = bx.get_param(bx.llfn(), llarg_idx); bx.set_value_name(llarg, &name); llarg_idx += 1; PlaceRef::new_sized(llarg, arg.layout, arg.layout.align.abi) } else if arg.is_unsized_indirect() { // As the storage for the indirect argument lives during // the whole function call, we just copy the fat pointer. - let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint); + let llarg = bx.get_param(bx.llfn(), llarg_idx); llarg_idx += 1; - let llextra = bx.get_param(bx.llfn(), llarg_idx as c_uint); + let llextra = bx.get_param(bx.llfn(), llarg_idx); llarg_idx += 1; let indirect_operand = OperandValue::Pair(llarg, llextra); diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs index b23155563665d..b3d458f3a3be8 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/src/librustc_codegen_ssa/traits/misc.rs @@ -1,5 +1,4 @@ use super::BackendTypes; -use libc::c_uint; use rustc::mir::mono::Stats; use rustc::session::Session; use rustc::ty::{self, Instance, Ty}; @@ -15,7 +14,7 @@ pub trait MiscMethods<'tcx>: BackendTypes { fn check_overflow(&self) -> bool; fn instances(&self) -> &RefCell, Self::Value>>; fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value; - fn get_param(&self, llfn: Self::Value, index: c_uint) -> Self::Value; + fn get_param(&self, llfn: Self::Value, index: usize) -> Self::Value; fn eh_personality(&self) -> Self::Value; fn eh_unwind_resume(&self) -> Self::Value; fn sess(&self) -> &Session; From a0c2ca1b56e64f4a5658ae0371da44e7af7cd58f Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 13:57:41 +0100 Subject: [PATCH 02/18] `eval_mir_constant` doesn't need a builder param --- src/librustc_codegen_ssa/mir/block.rs | 2 +- src/librustc_codegen_ssa/mir/constant.rs | 7 +++---- src/librustc_codegen_ssa/mir/operand.rs | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 4774f8fe5a380..494355efeaaa7 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -657,7 +657,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { span_bug!(span, "shuffle indices must be constant"); } mir::Operand::Constant(ref constant) => { - let c = self.eval_mir_constant(&bx, constant); + let c = self.eval_mir_constant(constant); let (llval, ty) = self.simd_shuffle_indices( &bx, constant.span, diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index a1d44b228a516..3f8dc420cf402 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -3,7 +3,7 @@ use rustc_mir::const_eval::const_field; use rustc::mir; use rustc_data_structures::indexed_vec::Idx; use rustc::ty::{self, Ty}; -use rustc::ty::layout; +use rustc::ty::layout::{self, HasTyCtxt}; use syntax::source_map::Span; use crate::traits::*; @@ -12,20 +12,19 @@ use super::FunctionCx; impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn eval_mir_constant( &mut self, - bx: &Bx, constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { match constant.literal.val { mir::interpret::ConstValue::Unevaluated(def_id, ref substs) => { let substs = self.monomorphize(substs); let instance = ty::Instance::resolve( - bx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs, + self.cx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs, ).unwrap(); let cid = mir::interpret::GlobalId { instance, promoted: None, }; - bx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid)) + self.cx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid)) }, _ => Ok(*self.monomorphize(&constant.literal)), } diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index e17a6e7b03f81..289129e8e62ff 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -460,7 +460,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Operand::Constant(ref constant) => { let ty = self.monomorphize(&constant.ty); - self.eval_mir_constant(bx, constant) + self.eval_mir_constant(constant) .and_then(|c| OperandRef::from_const(bx, c)) .unwrap_or_else(|err| { match err { From 83e80a74436179588703db2d597e80f57e42efbe Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 1 Mar 2019 15:03:48 +0100 Subject: [PATCH 03/18] Use Builder instead of CodegenCx for OperandRef and LocalRef --- src/librustc_codegen_llvm/builder.rs | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 14 ++++++------ src/librustc_codegen_ssa/mir/operand.rs | 30 ++++++++++++------------- src/librustc_codegen_ssa/mir/rvalue.rs | 7 ++++-- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index d4d38a464576d..d0a861171c17c 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -616,7 +616,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { assert_eq!(place.llextra.is_some(), place.layout.is_unsized()); if place.layout.is_zst() { - return OperandRef::new_zst(self.cx(), place.layout); + return OperandRef::new_zst(self, place.layout); } fn scalar_load_metadata<'a, 'll, 'tcx>( diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index b0f53de17ea31..5e2144751c125 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -178,16 +178,16 @@ enum LocalRef<'tcx, V> { Operand(Option>), } -impl<'tcx, V: CodegenObject> LocalRef<'tcx, V> { - fn new_operand>( - cx: &Cx, +impl<'a, 'tcx: 'a, V: CodegenObject> LocalRef<'tcx, V> { + fn new_operand>( + bx: &mut Bx, layout: TyLayout<'tcx>, ) -> LocalRef<'tcx, V> { if layout.is_zst() { // Zero-size temporaries aren't always initialized, which // doesn't matter because they don't contain data, but // we need something in the operand. - LocalRef::Operand(Some(OperandRef::new_zst(cx, layout))) + LocalRef::Operand(Some(OperandRef::new_zst(bx, layout))) } else { LocalRef::Operand(None) } @@ -275,7 +275,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( if !memory_locals.contains(local) && !dbg { debug!("alloc: {:?} ({}) -> operand", local, name); - return LocalRef::new_operand(bx.cx(), layout); + return LocalRef::new_operand(&mut bx, layout); } debug!("alloc: {:?} ({}) -> place", local, name); @@ -320,7 +320,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // alloca in advance. Instead we wait until we see the // definition and update the operand there. debug!("alloc: {:?} -> operand", local); - LocalRef::new_operand(bx.cx(), layout) + LocalRef::new_operand(&mut bx, layout) } } }; @@ -529,7 +529,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let local = |op| LocalRef::Operand(Some(op)); match arg.mode { PassMode::Ignore(IgnoreMode::Zst) => { - return local(OperandRef::new_zst(bx.cx(), arg.layout)); + return local(OperandRef::new_zst(bx, arg.layout)); } PassMode::Ignore(IgnoreMode::CVarArgs) => {} PassMode::Direct(_) => { diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 289129e8e62ff..c2b1021f816a6 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -54,13 +54,13 @@ impl fmt::Debug for OperandRef<'tcx, V> { } impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { - pub fn new_zst>( - cx: &Cx, + pub fn new_zst>( + bx: &mut Bx, layout: TyLayout<'tcx> ) -> OperandRef<'tcx, V> { assert!(layout.is_zst()); OperandRef { - val: OperandValue::Immediate(cx.const_undef(cx.immediate_backend_type(layout))), + val: OperandValue::Immediate(bx.const_undef(bx.immediate_backend_type(layout))), layout } } @@ -69,10 +69,10 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { bx: &mut Bx, val: ty::Const<'tcx> ) -> Result { - let layout = bx.cx().layout_of(val.ty); + let layout = bx.layout_of(val.ty); if layout.is_zst() { - return Ok(OperandRef::new_zst(bx.cx(), layout)); + return Ok(OperandRef::new_zst(bx, layout)); } let val = match val.val { @@ -84,10 +84,10 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { layout::Abi::Scalar(ref x) => x, _ => bug!("from_const: invalid ByVal layout: {:#?}", layout) }; - let llval = bx.cx().scalar_to_backend( + let llval = bx.scalar_to_backend( x, scalar, - bx.cx().immediate_backend_type(layout), + bx.immediate_backend_type(layout), ); OperandValue::Immediate(llval) }, @@ -96,16 +96,16 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { layout::Abi::ScalarPair(ref a, _) => a, _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout) }; - let a_llval = bx.cx().scalar_to_backend( + let a_llval = bx.scalar_to_backend( a, a_scalar, - bx.cx().scalar_pair_element_backend_type(layout, 0, true), + bx.scalar_pair_element_backend_type(layout, 0, true), ); - let b_llval = bx.cx().const_usize(b); + let b_llval = bx.const_usize(b); OperandValue::Pair(a_llval, b_llval) }, ConstValue::ByRef(ptr, alloc) => { - return Ok(bx.load_operand(bx.cx().from_const_alloc(layout, alloc, ptr.offset))); + return Ok(bx.load_operand(bx.from_const_alloc(layout, alloc, ptr.offset))); }, }; @@ -124,7 +124,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { } } - pub fn deref>( + pub fn deref>( self, cx: &Cx ) -> PlaceRef<'tcx, V> { @@ -199,7 +199,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { let mut val = match (self.val, &self.layout.abi) { // If the field is ZST, it has no data. _ if field.is_zst() => { - return OperandRef::new_zst(bx.cx(), field); + return OperandRef::new_zst(bx, field); } // Newtype of a scalar, scalar pair or vector. @@ -409,7 +409,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // checks in `codegen_consume` and `extract_field`. let elem = o.layout.field(bx.cx(), 0); if elem.is_zst() { - return Some(OperandRef::new_zst(bx.cx(), elem)); + return Some(OperandRef::new_zst(bx, elem)); } } _ => {} @@ -432,7 +432,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // ZSTs don't require any actual memory access. if layout.is_zst() { - return OperandRef::new_zst(bx.cx(), layout); + return OperandRef::new_zst(bx, layout); } if let Some(o) = self.maybe_codegen_consume_direct(bx, place) { diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index b8131671320e1..c20d3f44bc528 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -523,8 +523,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // According to `rvalue_creates_operand`, only ZST // aggregate rvalues are allowed to be operands. let ty = rvalue.ty(self.mir, self.cx.tcx()); - (bx, OperandRef::new_zst(self.cx, - self.cx.layout_of(self.monomorphize(&ty)))) + let operand = OperandRef::new_zst( + &mut bx, + self.cx.layout_of(self.monomorphize(&ty)), + ); + (bx, operand) } } } From fe88440bd2aa2647d41ed33193ce5eac682afa17 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 1 Mar 2019 15:05:18 +0100 Subject: [PATCH 04/18] Add a comment --- src/librustc_codegen_llvm/builder.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index d0a861171c17c..048adb0fb80ff 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -1472,6 +1472,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn get_static(&self, def_id: DefId) -> &'ll Value { + // Forward to the `get_static` method of `CodegenCx` self.cx().get_static(def_id) } } From a0056333f12ae3b916fbd0a14c1b641460140797 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 14:35:11 +0100 Subject: [PATCH 05/18] Misc --- src/librustc_codegen_llvm/builder.rs | 2 +- src/librustc_codegen_ssa/mir/place.rs | 5 +++-- src/librustc_codegen_ssa/traits/statics.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 048adb0fb80ff..ebe3a81acc601 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -1471,7 +1471,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { - fn get_static(&self, def_id: DefId) -> &'ll Value { + fn get_static(&mut self, def_id: DefId) -> &'ll Value { // Forward to the `get_static` method of `CodegenCx` self.cx().get_static(def_id) } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 7cafa0088a012..bf2afbbabab96 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -80,7 +80,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { Self::alloca(bx, ptr_layout, name) } - pub fn len>( + pub fn len>( &self, cx: &Cx ) -> V { @@ -447,7 +447,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // NB: The layout of a static may be unsized as is the case when working // with a static that is an extern_type. let layout = cx.layout_of(self.monomorphize(&ty)); - PlaceRef::new_thin_place(bx, bx.get_static(def_id), layout, layout.align.abi) + let static_ = bx.get_static(def_id); + PlaceRef::new_thin_place(bx, static_, layout, layout.align.abi) }, mir::Place::Projection(box mir::Projection { ref base, diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs index c4e7fe703c219..55c1253f10673 100644 --- a/src/librustc_codegen_ssa/traits/statics.rs +++ b/src/librustc_codegen_ssa/traits/statics.rs @@ -8,5 +8,5 @@ pub trait StaticMethods: BackendTypes { } pub trait StaticBuilderMethods<'tcx>: BackendTypes { - fn get_static(&self, def_id: DefId) -> Self::Value; + fn get_static(&mut self, def_id: DefId) -> Self::Value; } From a3fa1161d22f5055e28340cd6c00d1451e4d9572 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 15:58:40 +0100 Subject: [PATCH 06/18] Remove const_{fat_ptr,array,vector,bytes} from cg_ssa --- src/librustc_codegen_llvm/common.rs | 54 ++++++++++++----------- src/librustc_codegen_ssa/traits/consts.rs | 4 -- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 4bd036ea3b17a..aab0d8ac60271 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -93,6 +93,34 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> { type DIScope = &'ll llvm::debuginfo::DIScope; } +impl CodegenCx<'ll, 'tcx> { + pub fn const_fat_ptr( + &self, + ptr: &'ll Value, + meta: &'ll Value + ) -> &'ll Value { + assert_eq!(abi::FAT_PTR_ADDR, 0); + assert_eq!(abi::FAT_PTR_EXTRA, 1); + self.const_struct(&[ptr, meta], false) + } + + pub fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value { + unsafe { + return llvm::LLVMConstArray(ty, elts.as_ptr(), elts.len() as c_uint); + } + } + + pub fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value { + unsafe { + return llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint); + } + } + + pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value { + bytes_in_context(self.llcx, bytes) + } +} + impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn const_null(&self, t: &'ll Type) -> &'ll Value { unsafe { @@ -189,16 +217,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.const_fat_ptr(cs, self.const_usize(len as u64)) } - fn const_fat_ptr( - &self, - ptr: &'ll Value, - meta: &'ll Value - ) -> &'ll Value { - assert_eq!(abi::FAT_PTR_ADDR, 0); - assert_eq!(abi::FAT_PTR_EXTRA, 1); - self.const_struct(&[ptr, meta], false) - } - fn const_struct( &self, elts: &[&'ll Value], @@ -207,22 +225,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { struct_in_context(self.llcx, elts, packed) } - fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value { - unsafe { - return llvm::LLVMConstArray(ty, elts.as_ptr(), elts.len() as c_uint); - } - } - - fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value { - unsafe { - return llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint); - } - } - - fn const_bytes(&self, bytes: &[u8]) -> &'ll Value { - bytes_in_context(self.llcx, bytes) - } - fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value { unsafe { assert_eq!(idx as c_uint as u64, idx); diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index 319f4b4e5e4b5..61db94d53d881 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/src/librustc_codegen_ssa/traits/consts.rs @@ -24,11 +24,7 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_cstr(&self, s: LocalInternedString, null_terminated: bool) -> Self::Value; fn const_str_slice(&self, s: LocalInternedString) -> Self::Value; - fn const_fat_ptr(&self, ptr: Self::Value, meta: Self::Value) -> Self::Value; fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value; - fn const_array(&self, ty: Self::Type, elts: &[Self::Value]) -> Self::Value; - fn const_vector(&self, elts: &[Self::Value]) -> Self::Value; - fn const_bytes(&self, bytes: &[u8]) -> Self::Value; fn const_get_elt(&self, v: Self::Value, idx: u64) -> Self::Value; fn const_get_real(&self, v: Self::Value) -> Option<(f64, bool)>; From 7b94195c22f20feed07dd033f4e2f866a0a29b0b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 16:53:39 +0100 Subject: [PATCH 07/18] Remove const_{cstr,str_slice,get_elt,get_real} and is_const_real methods from cg_ssa This introduces the static_panic_msg trait method to StaticBuilderMethods. --- src/librustc_codegen_llvm/builder.rs | 31 +++++ src/librustc_codegen_llvm/common.rs | 132 ++++++++++----------- src/librustc_codegen_ssa/mir/block.rs | 53 ++++----- src/librustc_codegen_ssa/traits/consts.rs | 9 -- src/librustc_codegen_ssa/traits/statics.rs | 9 ++ 5 files changed, 126 insertions(+), 108 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index ebe3a81acc601..3b3b437007aeb 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -5,6 +5,7 @@ use crate::context::CodegenCx; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; +use syntax::symbol::LocalInternedString; use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate}; use rustc_codegen_ssa::MemFlags; use libc::{c_uint, c_char}; @@ -1475,6 +1476,36 @@ impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { // Forward to the `get_static` method of `CodegenCx` self.cx().get_static(def_id) } + + fn static_panic_msg( + &mut self, + msg: Option, + filename: LocalInternedString, + line: Self::Value, + col: Self::Value, + kind: &str, + ) -> Self::Value { + let align = self.tcx.data_layout.aggregate_align.abi + .max(self.tcx.data_layout.i32_align.abi) + .max(self.tcx.data_layout.pointer_align.abi); + + let filename = self.const_str_slice(filename); + + let with_msg_components; + let without_msg_components; + + let components = if let Some(msg) = msg { + let msg = self.const_str_slice(msg); + with_msg_components = [msg, filename, line, col]; + &with_msg_components as &[_] + } else { + without_msg_components = [filename, line, col]; + &without_msg_components as &[_] + }; + + let struct_ = self.const_struct(&components, false); + self.static_addr_of(struct_, align, Some(kind)) + } } impl Builder<'a, 'll, 'tcx> { diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index aab0d8ac60271..9554e54e4142a 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -119,6 +119,72 @@ impl CodegenCx<'ll, 'tcx> { pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value { bytes_in_context(self.llcx, bytes) } + + fn const_cstr( + &self, + s: LocalInternedString, + null_terminated: bool, + ) -> &'ll Value { + unsafe { + if let Some(&llval) = self.const_cstr_cache.borrow().get(&s) { + return llval; + } + + let sc = llvm::LLVMConstStringInContext(self.llcx, + s.as_ptr() as *const c_char, + s.len() as c_uint, + !null_terminated as Bool); + let sym = self.generate_local_symbol_name("str"); + let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{ + bug!("symbol `{}` is already defined", sym); + }); + llvm::LLVMSetInitializer(g, sc); + llvm::LLVMSetGlobalConstant(g, True); + llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage); + + self.const_cstr_cache.borrow_mut().insert(s, g); + g + } + } + + pub fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value { + let len = s.len(); + let cs = consts::ptrcast(self.const_cstr(s, false), + self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self))); + self.const_fat_ptr(cs, self.const_usize(len as u64)) + } + + pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value { + unsafe { + assert_eq!(idx as c_uint as u64, idx); + let us = &[idx as c_uint]; + let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint); + + debug!("const_get_elt(v={:?}, idx={}, r={:?})", + v, idx, r); + + r + } + } + + pub fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> { + unsafe { + if self.is_const_real(v) { + let mut loses_info: llvm::Bool = ::std::mem::uninitialized(); + let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info); + let loses_info = if loses_info == 1 { true } else { false }; + Some((r, loses_info)) + } else { + None + } + } + } + + fn is_const_real(&self, v: &'ll Value) -> bool { + unsafe { + llvm::LLVMIsAConstantFP(v).is_some() + } + } } impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -183,40 +249,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.const_uint(self.type_i8(), i as u64) } - fn const_cstr( - &self, - s: LocalInternedString, - null_terminated: bool, - ) -> &'ll Value { - unsafe { - if let Some(&llval) = self.const_cstr_cache.borrow().get(&s) { - return llval; - } - - let sc = llvm::LLVMConstStringInContext(self.llcx, - s.as_ptr() as *const c_char, - s.len() as c_uint, - !null_terminated as Bool); - let sym = self.generate_local_symbol_name("str"); - let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{ - bug!("symbol `{}` is already defined", sym); - }); - llvm::LLVMSetInitializer(g, sc); - llvm::LLVMSetGlobalConstant(g, True); - llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage); - - self.const_cstr_cache.borrow_mut().insert(s, g); - g - } - } - - fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value { - let len = s.len(); - let cs = consts::ptrcast(self.const_cstr(s, false), - self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self))); - self.const_fat_ptr(cs, self.const_usize(len as u64)) - } - fn const_struct( &self, elts: &[&'ll Value], @@ -225,32 +257,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { struct_in_context(self.llcx, elts, packed) } - fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value { - unsafe { - assert_eq!(idx as c_uint as u64, idx); - let us = &[idx as c_uint]; - let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint); - - debug!("const_get_elt(v={:?}, idx={}, r={:?})", - v, idx, r); - - r - } - } - - fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> { - unsafe { - if self.is_const_real(v) { - let mut loses_info: llvm::Bool = ::std::mem::uninitialized(); - let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info); - let loses_info = if loses_info == 1 { true } else { false }; - Some((r, loses_info)) - } else { - None - } - } - } - fn const_to_uint(&self, v: &'ll Value) -> u64 { unsafe { llvm::LLVMConstIntGetZExtValue(v) @@ -263,12 +269,6 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - fn is_const_real(&self, v: &'ll Value) -> bool { - unsafe { - llvm::LLVMIsAConstantFP(v).is_some() - } - } - fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option { unsafe { if self.is_const_integral(v) { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 494355efeaaa7..f0e8a18c479b1 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -399,12 +399,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Get the location information. let loc = bx.sess().source_map().lookup_char_pos(span.lo()); let filename = Symbol::intern(&loc.file.name.to_string()).as_str(); - let filename = bx.const_str_slice(filename); let line = bx.const_u32(loc.line as u32); let col = bx.const_u32(loc.col.to_usize() as u32 + 1); - let align = self.cx.tcx().data_layout.aggregate_align.abi - .max(self.cx.tcx().data_layout.i32_align.abi) - .max(self.cx.tcx().data_layout.pointer_align.abi); // Put together the arguments to the panic entry point. let (lang_item, args) = match *msg { @@ -412,30 +408,28 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let len = self.codegen_operand(&mut bx, len).immediate(); let index = self.codegen_operand(&mut bx, index).immediate(); - let file_line_col = bx.const_struct(&[filename, line, col], false); - let file_line_col = bx.static_addr_of( - file_line_col, - align, - Some("panic_bounds_check_loc") + let file_line_col = bx.static_panic_msg( + None, + filename, + line, + col, + "panic_bounds_check_loc", ); (lang_items::PanicBoundsCheckFnLangItem, - vec![file_line_col, index, len]) + vec![file_line_col, index, len]) } _ => { let str = msg.description(); let msg_str = Symbol::intern(str).as_str(); - let msg_str = bx.const_str_slice(msg_str); - let msg_file_line_col = bx.const_struct( - &[msg_str, filename, line, col], - false - ); - let msg_file_line_col = bx.static_addr_of( - msg_file_line_col, - align, - Some("panic_loc") + let msg_file_line_col = bx.static_panic_msg( + Some(msg_str), + filename, + line, + col, + "panic_loc", ); (lang_items::PanicFnLangItem, - vec![msg_file_line_col]) + vec![msg_file_line_col]) } }; @@ -539,27 +533,20 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if layout.abi.is_uninhabited() { let loc = bx.sess().source_map().lookup_char_pos(span.lo()); let filename = Symbol::intern(&loc.file.name.to_string()).as_str(); - let filename = bx.const_str_slice(filename); let line = bx.const_u32(loc.line as u32); let col = bx.const_u32(loc.col.to_usize() as u32 + 1); - let align = self.cx.tcx().data_layout.aggregate_align.abi - .max(self.cx.tcx().data_layout.i32_align.abi) - .max(self.cx.tcx().data_layout.pointer_align.abi); let str = format!( "Attempted to instantiate uninhabited type {}", ty ); let msg_str = Symbol::intern(&str).as_str(); - let msg_str = bx.const_str_slice(msg_str); - let msg_file_line_col = bx.const_struct( - &[msg_str, filename, line, col], - false, - ); - let msg_file_line_col = bx.static_addr_of( - msg_file_line_col, - align, - Some("panic_loc"), + let msg_file_line_col = bx.static_panic_msg( + Some(msg_str), + filename, + line, + col, + "panic_loc", ); // Obtain the panic entry point. diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index 61db94d53d881..32412f303c155 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/src/librustc_codegen_ssa/traits/consts.rs @@ -3,7 +3,6 @@ use crate::mir::place::PlaceRef; use rustc::mir::interpret::Allocation; use rustc::mir::interpret::Scalar; use rustc::ty::layout; -use syntax::symbol::LocalInternedString; pub trait ConstMethods<'tcx>: BackendTypes { // Constant constructors @@ -19,20 +18,12 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_usize(&self, i: u64) -> Self::Value; fn const_u8(&self, i: u8) -> Self::Value; - // This is a 'c-like' raw string, which differs from - // our boxed-and-length-annotated strings. - fn const_cstr(&self, s: LocalInternedString, null_terminated: bool) -> Self::Value; - - fn const_str_slice(&self, s: LocalInternedString) -> Self::Value; fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value; - fn const_get_elt(&self, v: Self::Value, idx: u64) -> Self::Value; - fn const_get_real(&self, v: Self::Value) -> Option<(f64, bool)>; fn const_to_uint(&self, v: Self::Value) -> u64; fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option; fn is_const_integral(&self, v: Self::Value) -> bool; - fn is_const_real(&self, v: Self::Value) -> bool; fn scalar_to_backend( &self, diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs index 55c1253f10673..d8992c159337d 100644 --- a/src/librustc_codegen_ssa/traits/statics.rs +++ b/src/librustc_codegen_ssa/traits/statics.rs @@ -1,4 +1,5 @@ use super::BackendTypes; +use syntax_pos::symbol::LocalInternedString; use rustc::hir::def_id::DefId; use rustc::ty::layout::Align; @@ -9,4 +10,12 @@ pub trait StaticMethods: BackendTypes { pub trait StaticBuilderMethods<'tcx>: BackendTypes { fn get_static(&mut self, def_id: DefId) -> Self::Value; + fn static_panic_msg( + &mut self, + msg: Option, + filename: LocalInternedString, + line: Self::Value, + col: Self::Value, + kind: &str, + ) -> Self::Value; } From f1fe9253e2b9ed072af6bc2d80feb6be0ffee8a5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 18:04:39 +0100 Subject: [PATCH 08/18] Remove param_substs from FunctionCx --- src/librustc_codegen_ssa/mir/mod.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 5e2144751c125..62bbfa316b50d 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -1,7 +1,6 @@ use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; use rustc::ty::layout::{TyLayout, HasTyCtxt}; use rustc::mir::{self, Mir}; -use rustc::ty::subst::SubstsRef; use rustc::session::config::DebugInfo; use rustc_mir::monomorphize::Instance; use rustc_target::abi::call::{FnType, PassMode, IgnoreMode}; @@ -83,9 +82,6 @@ pub struct FunctionCx<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> { /// Debug information for MIR scopes. scopes: IndexVec>, - /// If this function is being monomorphized, this contains the type substitutions used. - param_substs: SubstsRef<'tcx>, - /// If this function is a C-variadic function, this contains the `PlaceRef` of the /// "spoofed" `VaList`. va_list_ref: Option>, @@ -96,7 +92,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { where T: TypeFoldable<'tcx> { self.cx.tcx().subst_and_normalize_erasing_regions( - self.param_substs, + self.instance.substs, ty::ParamEnv::reveal_all(), value, ) @@ -203,6 +199,8 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, ) { + assert!(!instance.substs.needs_infer()); + let fn_ty = cx.new_fn_type(sig, &[]); debug!("fn_ty: {:?}", fn_ty); let debug_context = @@ -245,10 +243,6 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( scopes, locals: IndexVec::new(), debug_context, - param_substs: { - assert!(!instance.substs.needs_infer()); - instance.substs - }, va_list_ref: None, }; From ab8f1527e485d0de49139ca7b9d42c320991a53b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 18:09:26 +0100 Subject: [PATCH 09/18] Remove internal mutability from source_locations_enabled --- src/librustc_codegen_llvm/debuginfo/mod.rs | 6 +++--- src/librustc_codegen_llvm/debuginfo/source_loc.rs | 2 +- src/librustc_codegen_ssa/debuginfo.rs | 9 ++++----- src/librustc_codegen_ssa/mir/mod.rs | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index c0869bb889afa..c262167d92092 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -32,7 +32,7 @@ use rustc_codegen_ssa::debuginfo::{FunctionDebugContext, MirDebugScope, Variable VariableKind, FunctionDebugContextData}; use libc::c_uint; -use std::cell::{Cell, RefCell}; +use std::cell::RefCell; use std::ffi::CString; use syntax_pos::{self, Span, Pos}; @@ -158,7 +158,7 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { variable_kind: VariableKind, span: Span, ) { - assert!(!dbg_context.get_ref(span).source_locations_enabled.get()); + assert!(!dbg_context.get_ref(span).source_locations_enabled); let cx = self.cx(); let file = span_start(cx, span).file; @@ -327,7 +327,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { // Initialize fn debug context (including scope map and namespace map) let fn_debug_context = FunctionDebugContextData { fn_metadata, - source_locations_enabled: Cell::new(false), + source_locations_enabled: false, defining_crate: def_id.krate, }; diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index f7620e11c233d..dec93a65dbaf4 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -30,7 +30,7 @@ pub fn set_source_location( FunctionDebugContext::RegularContext(ref data) => data }; - let dbg_loc = if function_debug_context.source_locations_enabled.get() { + let dbg_loc = if function_debug_context.source_locations_enabled { debug!("set_source_location: {}", bx.sess().source_map().span_to_string(span)); let loc = span_start(bx.cx(), span); InternalDebugLocation::new(scope.unwrap(), loc.line, loc.col.to_usize()) diff --git a/src/librustc_codegen_ssa/debuginfo.rs b/src/librustc_codegen_ssa/debuginfo.rs index c4531ff90ae7c..aa7cdbed99446 100644 --- a/src/librustc_codegen_ssa/debuginfo.rs +++ b/src/librustc_codegen_ssa/debuginfo.rs @@ -1,6 +1,5 @@ use syntax_pos::{BytePos, Span}; use rustc::hir::def_id::CrateNum; -use std::cell::Cell; pub enum FunctionDebugContext { RegularContext(FunctionDebugContextData), @@ -36,10 +35,10 @@ impl FunctionDebugContext { /// they are disabled when beginning to codegen a new function. This functions /// switches source location emitting on and must therefore be called before the /// first real statement/expression of the function is codegened. -pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext) { +pub fn start_emitting_source_locations(dbg_context: &mut FunctionDebugContext) { match *dbg_context { - FunctionDebugContext::RegularContext(ref data) => { - data.source_locations_enabled.set(true) + FunctionDebugContext::RegularContext(ref mut data) => { + data.source_locations_enabled = true; }, _ => { /* safe to ignore */ } } @@ -47,7 +46,7 @@ pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext) pub struct FunctionDebugContextData { pub fn_metadata: D, - pub source_locations_enabled: Cell, + pub source_locations_enabled: bool, pub defining_crate: CrateNum, } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 62bbfa316b50d..15597542d4992 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -334,7 +334,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Up until here, IR instructions for this function have explicitly not been annotated with // source code location, so we don't step into call setup code. From here on, source location // emitting should be enabled. - debuginfo::start_emitting_source_locations(&fx.debug_context); + debuginfo::start_emitting_source_locations(&mut fx.debug_context); let rpo = traversal::reverse_postorder(&mir); let mut visited = BitSet::new_empty(mir.basic_blocks().len()); From 794ecd965ab39d767caebd79c0e32702e86a3ff1 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 18:25:42 +0100 Subject: [PATCH 10/18] [WIP] Make some debug info methods take &mut FunctionDebugContext declare_local still takes &FunctionDebugContext, because of borrowck errors --- src/librustc_codegen_llvm/debuginfo/mod.rs | 4 ++-- src/librustc_codegen_ssa/mir/mod.rs | 14 +++++--------- src/librustc_codegen_ssa/traits/debuginfo.rs | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index c262167d92092..066ac8f019e00 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -216,7 +216,7 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn set_source_location( &mut self, - debug_context: &FunctionDebugContext<&'ll DISubprogram>, + debug_context: &mut FunctionDebugContext<&'ll DISubprogram>, scope: Option<&'ll DIScope>, span: Span, ) { @@ -519,7 +519,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn create_mir_scopes( &self, mir: &mir::Mir<'_>, - debug_context: &FunctionDebugContext<&'ll DISubprogram>, + debug_context: &mut FunctionDebugContext<&'ll DISubprogram>, ) -> IndexVec> { create_scope_map::create_mir_scopes(self, mir, debug_context) } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 15597542d4992..4d9579504c857 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -104,7 +104,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { source_info: mir::SourceInfo ) { let (scope, span) = self.debug_loc(source_info); - bx.set_source_location(&self.debug_context, scope, span); + bx.set_source_location(&mut self.debug_context, scope, span); } pub fn debug_loc(&self, source_info: mir::SourceInfo) -> (Option, Span) { @@ -203,7 +203,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let fn_ty = cx.new_fn_type(sig, &[]); debug!("fn_ty: {:?}", fn_ty); - let debug_context = + let mut debug_context = cx.create_function_debug_context(instance, sig, llfn, mir); let mut bx = Bx::new_block(cx, llfn, "start"); @@ -225,7 +225,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( }).collect(); // Compute debuginfo scopes from MIR scopes. - let scopes = cx.create_mir_scopes(mir, &debug_context); + let scopes = cx.create_mir_scopes(mir, &mut debug_context); let (landing_pads, funclets) = create_funclets(mir, &mut bx, &cleanup_kinds, &block_bxs); let mut fx = FunctionCx { @@ -253,7 +253,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // FIXME(dlrobertson): This is ugly. Find a better way of getting the `PlaceRef` or // `LocalRef` from `arg_local_refs` let mut va_list_ref = None; - let args = arg_local_refs(&mut bx, &fx, &fx.scopes, &memory_locals, &mut va_list_ref); + let args = arg_local_refs(&mut bx, &fx, &memory_locals, &mut va_list_ref); fx.va_list_ref = va_list_ref; let mut allocate_local = |local| { @@ -430,10 +430,6 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, fx: &FunctionCx<'a, 'tcx, Bx>, - scopes: &IndexVec< - mir::SourceScope, - debuginfo::MirDebugScope - >, memory_locals: &BitSet, va_list_ref: &mut Option>, ) -> Vec> { @@ -443,7 +439,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let mut llarg_idx = fx.fn_ty.ret.is_indirect() as usize; // Get the argument scope, if it exists and if we need it. - let arg_scope = scopes[mir::OUTERMOST_SOURCE_SCOPE]; + let arg_scope = fx.scopes[mir::OUTERMOST_SOURCE_SCOPE]; let arg_scope = if bx.sess().opts.debuginfo == DebugInfo::Full { arg_scope.scope_metadata } else { diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index 135188e98c71c..dcbb4e66cb385 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -28,7 +28,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes { fn create_mir_scopes( &self, mir: &mir::Mir<'_>, - debug_context: &FunctionDebugContext, + debug_context: &mut FunctionDebugContext, ) -> IndexVec>; fn extend_scope_to_file( &self, @@ -53,7 +53,7 @@ pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes { ); fn set_source_location( &mut self, - debug_context: &FunctionDebugContext, + debug_context: &mut FunctionDebugContext, scope: Option, span: Span, ); From bcab49720e5226bc96a78e896877213d1773eaa5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 2 Dec 2018 18:54:46 +0100 Subject: [PATCH 11/18] Remove a lot of methods from BuilderMethods --- src/librustc_codegen_llvm/builder.rs | 426 ++++++++++----------- src/librustc_codegen_ssa/traits/builder.rs | 47 --- 2 files changed, 213 insertions(+), 260 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 3b3b437007aeb..ebee3ab6cedaa 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -133,19 +133,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn count_insn(&self, category: &str) { - if self.sess().codegen_stats() { - self.stats.borrow_mut().n_llvm_insns += 1; - } - if self.sess().count_llvm_insns() { - *self.stats - .borrow_mut() - .llvm_insns - .entry(category.to_string()) - .or_insert(0) += 1; - } - } - fn set_value_name(&mut self, value: &'ll Value, name: &str) { let cname = SmallCStr::new(name); unsafe { @@ -159,12 +146,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn position_at_start(&mut self, llbb: &'ll BasicBlock) { - unsafe { - llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb); - } - } - fn ret_void(&mut self) { self.count_insn("retvoid"); unsafe { @@ -897,17 +878,12 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } /* Miscellaneous instructions */ - fn empty_phi(&mut self, ty: &'ll Type) -> &'ll Value { - self.count_insn("emptyphi"); - unsafe { - llvm::LLVMBuildPhi(self.llbuilder, ty, noname()) - } - } - fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value { - assert_eq!(vals.len(), bbs.len()); - let phi = self.empty_phi(ty); self.count_insn("addincoming"); + assert_eq!(vals.len(), bbs.len()); + let phi = unsafe { + llvm::LLVMBuildPhi(self.llbuilder, ty, noname()) + }; unsafe { llvm::LLVMAddIncoming(phi, vals.as_ptr(), bbs.as_ptr(), @@ -1012,15 +988,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None); } - fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("minnum"); - unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) } - } - fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("maxnum"); - unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) } - } - fn select( &mut self, cond: &'ll Value, then_val: &'ll Value, @@ -1032,14 +999,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - #[allow(dead_code)] - fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { - self.count_insn("vaarg"); - unsafe { - llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname()) - } - } - fn extract_element(&mut self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value { self.count_insn("extractelement"); unsafe { @@ -1047,24 +1006,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn insert_element( - &mut self, vec: &'ll Value, - elt: &'ll Value, - idx: &'ll Value, - ) -> &'ll Value { - self.count_insn("insertelement"); - unsafe { - llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, noname()) - } - } - - fn shuffle_vector(&mut self, v1: &'ll Value, v2: &'ll Value, mask: &'ll Value) -> &'ll Value { - self.count_insn("shufflevector"); - unsafe { - llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname()) - } - } - fn vector_splat(&mut self, num_elts: usize, elt: &'ll Value) -> &'ll Value { unsafe { let elt_ty = self.cx.val_ty(elt); @@ -1075,81 +1016,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.fadd_fast"); - unsafe { - // FIXME: add a non-fast math version once - // https://bugs.llvm.org/show_bug.cgi?id=36732 - // is fixed. - let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); - llvm::LLVMRustSetHasUnsafeAlgebra(instr); - instr - } - } - fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.fmul_fast"); - unsafe { - // FIXME: add a non-fast math version once - // https://bugs.llvm.org/show_bug.cgi?id=36732 - // is fixed. - let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); - llvm::LLVMRustSetHasUnsafeAlgebra(instr); - instr - } - } - fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.add"); - unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) } - } - fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.mul"); - unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) } - } - fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.and"); - unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) } - } - fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.or"); - unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) } - } - fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.xor"); - unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) } - } - fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.fmin"); - unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) } - } - fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.fmax"); - unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) } - } - fn vector_reduce_fmin_fast(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.fmin_fast"); - unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true); - llvm::LLVMRustSetHasUnsafeAlgebra(instr); - instr - } - } - fn vector_reduce_fmax_fast(&mut self, src: &'ll Value) -> &'ll Value { - self.count_insn("vector.reduce.fmax_fast"); - unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true); - llvm::LLVMRustSetHasUnsafeAlgebra(instr); - instr - } - } - fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { - self.count_insn("vector.reduce.min"); - unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) } - } - fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { - self.count_insn("vector.reduce.max"); - unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) } - } - fn extract_value(&mut self, agg_val: &'ll Value, idx: u64) -> &'ll Value { self.count_insn("extractvalue"); assert_eq!(idx as c_uint as u64, idx); @@ -1177,12 +1043,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) { - unsafe { - llvm::LLVMAddClause(landing_pad, clause); - } - } - fn set_cleanup(&mut self, landing_pad: &'ll Value) { self.count_insn("setcleanup"); unsafe { @@ -1236,14 +1096,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { Funclet::new(ret.expect("LLVM does not have support for catchpad")) } - fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value { - self.count_insn("catchret"); - let ret = unsafe { - llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) - }; - ret.expect("LLVM does not have support for catchret") - } - fn catch_switch( &mut self, parent: Option<&'ll Value>, @@ -1347,67 +1199,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn check_store<'b>(&mut self, - val: &'ll Value, - ptr: &'ll Value) -> &'ll Value { - let dest_ptr_ty = self.cx.val_ty(ptr); - let stored_ty = self.cx.val_ty(val); - let stored_ptr_ty = self.cx.type_ptr_to(stored_ty); - - assert_eq!(self.cx.type_kind(dest_ptr_ty), TypeKind::Pointer); - - if dest_ptr_ty == stored_ptr_ty { - ptr - } else { - debug!("Type mismatch in store. \ - Expected {:?}, got {:?}; inserting bitcast", - dest_ptr_ty, stored_ptr_ty); - self.bitcast(ptr, stored_ptr_ty) - } - } - - fn check_call<'b>(&mut self, - typ: &str, - llfn: &'ll Value, - args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> { - let mut fn_ty = self.cx.val_ty(llfn); - // Strip off pointers - while self.cx.type_kind(fn_ty) == TypeKind::Pointer { - fn_ty = self.cx.element_type(fn_ty); - } - - assert!(self.cx.type_kind(fn_ty) == TypeKind::Function, - "builder::{} not passed a function, but {:?}", typ, fn_ty); - - let param_tys = self.cx.func_params_types(fn_ty); - - let all_args_match = param_tys.iter() - .zip(args.iter().map(|&v| self.val_ty(v))) - .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); - - if all_args_match { - return Cow::Borrowed(args); - } - - let casted_args: Vec<_> = param_tys.into_iter() - .zip(args.iter()) - .enumerate() - .map(|(i, (expected_ty, &actual_val))| { - let actual_ty = self.val_ty(actual_val); - if expected_ty != actual_ty { - debug!("Type mismatch in function call of {:?}. \ - Expected {:?} for param {}, got {:?}; injecting bitcast", - llfn, expected_ty, i, actual_ty); - self.bitcast(actual_val, expected_ty) - } else { - actual_val - } - }) - .collect(); - - Cow::Owned(casted_args) - } - fn lifetime_start(&mut self, ptr: &'ll Value, size: Size) { self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size); } @@ -1509,6 +1300,215 @@ impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { } impl Builder<'a, 'll, 'tcx> { + fn count_insn(&self, category: &str) { + if self.sess().codegen_stats() { + self.stats.borrow_mut().n_llvm_insns += 1; + } + if self.sess().count_llvm_insns() { + *self.stats + .borrow_mut() + .llvm_insns + .entry(category.to_string()) + .or_insert(0) += 1; + } + } + + fn position_at_start(&mut self, llbb: &'ll BasicBlock) { + unsafe { + llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb); + } + } + + pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + self.count_insn("minnum"); + unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) } + } + + pub fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + self.count_insn("maxnum"); + unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) } + } + + pub fn insert_element( + &mut self, vec: &'ll Value, + elt: &'ll Value, + idx: &'ll Value, + ) -> &'ll Value { + self.count_insn("insertelement"); + unsafe { + llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, noname()) + } + } + + pub fn shuffle_vector( + &mut self, + v1: &'ll Value, + v2: &'ll Value, + mask: &'ll Value, + ) -> &'ll Value { + self.count_insn("shufflevector"); + unsafe { + llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname()) + } + } + + pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.fadd_fast"); + unsafe { + // FIXME: add a non-fast math version once + // https://bugs.llvm.org/show_bug.cgi?id=36732 + // is fixed. + let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.fmul_fast"); + unsafe { + // FIXME: add a non-fast math version once + // https://bugs.llvm.org/show_bug.cgi?id=36732 + // is fixed. + let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.add"); + unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) } + } + pub fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.mul"); + unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) } + } + pub fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.and"); + unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) } + } + pub fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.or"); + unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) } + } + pub fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.xor"); + unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) } + } + pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.fmin"); + unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) } + } + pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.fmax"); + unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) } + } + pub fn vector_reduce_fmin_fast(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.fmin_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_fmax_fast(&mut self, src: &'ll Value) -> &'ll Value { + self.count_insn("vector.reduce.fmax_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { + self.count_insn("vector.reduce.min"); + unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) } + } + pub fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { + self.count_insn("vector.reduce.max"); + unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) } + } + + pub fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) { + unsafe { + llvm::LLVMAddClause(landing_pad, clause); + } + } + + pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value { + self.count_insn("catchret"); + let ret = unsafe { + llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) + }; + ret.expect("LLVM does not have support for catchret") + } + + fn check_store<'b>(&mut self, + val: &'ll Value, + ptr: &'ll Value) -> &'ll Value { + let dest_ptr_ty = self.cx.val_ty(ptr); + let stored_ty = self.cx.val_ty(val); + let stored_ptr_ty = self.cx.type_ptr_to(stored_ty); + + assert_eq!(self.cx.type_kind(dest_ptr_ty), TypeKind::Pointer); + + if dest_ptr_ty == stored_ptr_ty { + ptr + } else { + debug!("Type mismatch in store. \ + Expected {:?}, got {:?}; inserting bitcast", + dest_ptr_ty, stored_ptr_ty); + self.bitcast(ptr, stored_ptr_ty) + } + } + + fn check_call<'b>(&mut self, + typ: &str, + llfn: &'ll Value, + args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> { + let mut fn_ty = self.cx.val_ty(llfn); + // Strip off pointers + while self.cx.type_kind(fn_ty) == TypeKind::Pointer { + fn_ty = self.cx.element_type(fn_ty); + } + + assert!(self.cx.type_kind(fn_ty) == TypeKind::Function, + "builder::{} not passed a function, but {:?}", typ, fn_ty); + + let param_tys = self.cx.func_params_types(fn_ty); + + let all_args_match = param_tys.iter() + .zip(args.iter().map(|&v| self.val_ty(v))) + .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); + + if all_args_match { + return Cow::Borrowed(args); + } + + let casted_args: Vec<_> = param_tys.into_iter() + .zip(args.iter()) + .enumerate() + .map(|(i, (expected_ty, &actual_val))| { + let actual_ty = self.val_ty(actual_val); + if expected_ty != actual_ty { + debug!("Type mismatch in function call of {:?}. \ + Expected {:?} for param {}, got {:?}; injecting bitcast", + llfn, expected_ty, i, actual_ty); + self.bitcast(actual_val, expected_ty) + } else { + actual_val + } + }) + .collect(); + + Cow::Owned(casted_args) + } + + pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { + self.count_insn("vaarg"); + unsafe { + llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname()) + } + } + fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) { if self.cx.sess().opts.optimize == config::OptLevel::No { return; diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 5099107a39303..6dd2a36bf2648 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -13,7 +13,6 @@ use rustc::ty::Ty; use rustc::ty::layout::{Align, Size}; use std::ffi::CStr; -use std::borrow::Cow; use std::ops::Range; use syntax::ast::AsmDialect; @@ -39,11 +38,9 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn cx(&self) -> &Self::CodegenCx; fn llfn(&self) -> Self::Value; fn llbb(&self) -> Self::BasicBlock; - fn count_insn(&self, category: &str); fn set_value_name(&mut self, value: Self::Value, name: &str); fn position_at_end(&mut self, llbb: Self::BasicBlock); - fn position_at_start(&mut self, llbb: Self::BasicBlock); fn ret_void(&mut self); fn ret(&mut self, v: Self::Value); fn br(&mut self, dest: Self::BasicBlock); @@ -161,7 +158,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; - fn empty_phi(&mut self, ty: Self::Type) -> Self::Value; fn phi( &mut self, ty: Self::Type, @@ -206,8 +202,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: flags: MemFlags, ); - fn minnum(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; - fn maxnum(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn select( &mut self, cond: Self::Value, @@ -215,34 +209,8 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: else_val: Self::Value, ) -> Self::Value; - fn va_arg(&mut self, list: Self::Value, ty: Self::Type) -> Self::Value; fn extract_element(&mut self, vec: Self::Value, idx: Self::Value) -> Self::Value; - fn insert_element( - &mut self, - vec: Self::Value, - elt: Self::Value, - idx: Self::Value, - ) -> Self::Value; - fn shuffle_vector( - &mut self, - v1: Self::Value, - v2: Self::Value, - mask: Self::Value, - ) -> Self::Value; fn vector_splat(&mut self, num_elts: usize, elt: Self::Value) -> Self::Value; - fn vector_reduce_fadd_fast(&mut self, acc: Self::Value, src: Self::Value) -> Self::Value; - fn vector_reduce_fmul_fast(&mut self, acc: Self::Value, src: Self::Value) -> Self::Value; - fn vector_reduce_add(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_mul(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_and(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_or(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_xor(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_fmin(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_fmax(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_fmin_fast(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_fmax_fast(&mut self, src: Self::Value) -> Self::Value; - fn vector_reduce_min(&mut self, src: Self::Value, is_signed: bool) -> Self::Value; - fn vector_reduce_max(&mut self, src: Self::Value, is_signed: bool) -> Self::Value; fn extract_value(&mut self, agg_val: Self::Value, idx: u64) -> Self::Value; fn insert_value(&mut self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value; @@ -252,7 +220,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: pers_fn: Self::Value, num_clauses: usize, ) -> Self::Value; - fn add_clause(&mut self, landing_pad: Self::Value, clause: Self::Value); fn set_cleanup(&mut self, landing_pad: Self::Value); fn resume(&mut self, exn: Self::Value) -> Self::Value; fn cleanup_pad(&mut self, parent: Option, args: &[Self::Value]) -> Self::Funclet; @@ -262,7 +229,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: unwind: Option, ) -> Self::Value; fn catch_pad(&mut self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet; - fn catch_ret(&mut self, funclet: &Self::Funclet, unwind: Self::BasicBlock) -> Self::Value; fn catch_switch( &mut self, parent: Option, @@ -293,19 +259,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn add_incoming_to_phi(&mut self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock); fn set_invariant_load(&mut self, load: Self::Value); - /// Returns the ptr value that should be used for storing `val`. - fn check_store(&mut self, val: Self::Value, ptr: Self::Value) -> Self::Value; - - /// Returns the args that should be used for a call to `llfn`. - fn check_call<'b>( - &mut self, - typ: &str, - llfn: Self::Value, - args: &'b [Self::Value], - ) -> Cow<'b, [Self::Value]> - where - [Self::Value]: ToOwned; - /// Called for `StorageLive` fn lifetime_start(&mut self, ptr: Self::Value, size: Size); From 7de0b1de19beac340691d260e7d5ed3dfeb92081 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 4 Dec 2018 20:20:45 +0100 Subject: [PATCH 12/18] Move get_param and set_value_name --- src/librustc_codegen_llvm/abi.rs | 4 ++ src/librustc_codegen_llvm/builder.rs | 44 ++++++++++---------- src/librustc_codegen_llvm/context.rs | 5 --- src/librustc_codegen_llvm/debuginfo/mod.rs | 7 ++++ src/librustc_codegen_ssa/base.rs | 4 +- src/librustc_codegen_ssa/mir/mod.rs | 14 +++---- src/librustc_codegen_ssa/traits/abi.rs | 1 + src/librustc_codegen_ssa/traits/builder.rs | 3 +- src/librustc_codegen_ssa/traits/debuginfo.rs | 1 + src/librustc_codegen_ssa/traits/misc.rs | 1 - 10 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 49c9555a2c682..3a0d9e1334cf6 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -859,4 +859,8 @@ impl AbiBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { ) { ty.apply_attrs_callsite(self, callsite) } + + fn get_param(&self, index: usize) -> Self::Value { + llvm::get_param(self.llfn(), index as c_uint) + } } diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index ebee3ab6cedaa..8e6299a45ae03 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -121,25 +121,12 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { Builder::new_block(self.cx, self.llfn(), name) } - fn llfn(&self) -> &'ll Value { - unsafe { - llvm::LLVMGetBasicBlockParent(self.llbb()) - } - } - fn llbb(&self) -> &'ll BasicBlock { unsafe { llvm::LLVMGetInsertBlock(self.llbuilder) } } - fn set_value_name(&mut self, value: &'ll Value, name: &str) { - let cname = SmallCStr::new(name); - unsafe { - llvm::LLVMSetValueName(value, cname.as_ptr()); - } - } - fn position_at_end(&mut self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb); @@ -768,6 +755,14 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } + fn struct_gep(&mut self, ptr: &'ll Value, idx: u64) -> &'ll Value { + self.count_insn("structgep"); + assert_eq!(idx as c_uint as u64, idx); + unsafe { + llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, noname()) + } + } + /* Casts */ fn trunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("trunc"); @@ -999,6 +994,14 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } + #[allow(dead_code)] + fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { + self.count_insn("vaarg"); + unsafe { + llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname()) + } + } + fn extract_element(&mut self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value { self.count_insn("extractelement"); unsafe { @@ -1241,13 +1244,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn struct_gep(&mut self, ptr: &'ll Value, idx: u64) -> &'ll Value { - self.count_insn("structgep"); - assert_eq!(idx as c_uint as u64, idx); - unsafe { - llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, noname()) - } - } fn cx(&self) -> &CodegenCx<'ll, 'tcx> { self.cx @@ -1263,7 +1259,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { - fn get_static(&mut self, def_id: DefId) -> &'ll Value { +fn get_static(&mut self, def_id: DefId) -> &'ll Value { // Forward to the `get_static` method of `CodegenCx` self.cx().get_static(def_id) } @@ -1300,6 +1296,12 @@ impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { } impl Builder<'a, 'll, 'tcx> { + pub fn llfn(&self) -> &'ll Value { + unsafe { + llvm::LLVMGetBasicBlockParent(self.llbb()) + } + } + fn count_insn(&self, category: &str) { if self.sess().codegen_stats() { self.stats.borrow_mut().n_llvm_insns += 1; diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 0060751d60641..fc79e868fb4bf 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -10,7 +10,6 @@ use crate::monomorphize::partitioning::CodegenUnit; use crate::type_::Type; use crate::type_of::PointeeInfo; use rustc_codegen_ssa::traits::*; -use libc::c_uint; use rustc_data_structures::base_n; use rustc_data_structures::small_c_str::SmallCStr; @@ -326,10 +325,6 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { get_fn(self, instance) } - fn get_param(&self, llfn: &'ll Value, index: usize) -> &'ll Value { - llvm::get_param(llfn, index as c_uint) - } - fn eh_personality(&self) -> &'ll Value { // The exception handling personality function. // diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 066ac8f019e00..6abbcd9feba7a 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -225,6 +225,13 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) { gdb::insert_reference_to_gdb_debug_scripts_section_global(self) } + + fn set_value_name(&mut self, value: &'ll Value, name: &str) { + let cname = SmallCStr::new(name); + unsafe { + llvm::LLVMSetValueName(value, cname.as_ptr()); + } + } } impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 48743be3a2551..27e3e30669905 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -501,8 +501,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx.insert_reference_to_gdb_debug_scripts_section_global(); // Params from native main() used as args for rust start function - let param_argc = cx.get_param(llfn, 0); - let param_argv = cx.get_param(llfn, 1); + let param_argc = bx.get_param(0); + let param_argv = bx.get_param(1); let arg_argc = bx.intcast(param_argc, cx.type_isize(), true); let arg_argv = param_argv; diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 4d9579504c857..91aa9bcc7808b 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -295,7 +295,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Temporary or return place if local == mir::RETURN_PLACE && fx.fn_ty.ret.is_indirect() { debug!("alloc: {:?} (return place) -> place", local); - let llretptr = fx.cx.get_param(llfn, 0); + let llretptr = bx.get_param(0); LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align.abi)) } else if memory_locals.contains(local) { debug!("alloc: {:?} -> place", local); @@ -523,18 +523,18 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( } PassMode::Ignore(IgnoreMode::CVarArgs) => {} PassMode::Direct(_) => { - let llarg = bx.get_param(bx.llfn(), llarg_idx); + let llarg = bx.get_param(llarg_idx); bx.set_value_name(llarg, &name); llarg_idx += 1; return local( OperandRef::from_immediate_or_packed_pair(bx, llarg, arg.layout)); } PassMode::Pair(..) => { - let a = bx.get_param(bx.llfn(), llarg_idx); + let a = bx.get_param(llarg_idx); bx.set_value_name(a, &(name.clone() + ".0")); llarg_idx += 1; - let b = bx.get_param(bx.llfn(), llarg_idx); + let b = bx.get_param(llarg_idx); bx.set_value_name(b, &(name + ".1")); llarg_idx += 1; @@ -551,16 +551,16 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Don't copy an indirect argument to an alloca, the caller // already put it in a temporary alloca and gave it up. // FIXME: lifetimes - let llarg = bx.get_param(bx.llfn(), llarg_idx); + let llarg = bx.get_param(llarg_idx); bx.set_value_name(llarg, &name); llarg_idx += 1; PlaceRef::new_sized(llarg, arg.layout, arg.layout.align.abi) } else if arg.is_unsized_indirect() { // As the storage for the indirect argument lives during // the whole function call, we just copy the fat pointer. - let llarg = bx.get_param(bx.llfn(), llarg_idx); + let llarg = bx.get_param(llarg_idx); llarg_idx += 1; - let llextra = bx.get_param(bx.llfn(), llarg_idx); + let llextra = bx.get_param(llarg_idx); llarg_idx += 1; let indirect_operand = OperandValue::Pair(llarg, llextra); diff --git a/src/librustc_codegen_ssa/traits/abi.rs b/src/librustc_codegen_ssa/traits/abi.rs index 8f7fa199b057a..a8fd4e1d2c7c7 100644 --- a/src/librustc_codegen_ssa/traits/abi.rs +++ b/src/librustc_codegen_ssa/traits/abi.rs @@ -10,4 +10,5 @@ pub trait AbiMethods<'tcx> { pub trait AbiBuilderMethods<'tcx>: BackendTypes { fn apply_attrs_callsite(&mut self, ty: &FnType<'tcx, Ty<'tcx>>, callsite: Self::Value); + fn get_param(&self, index: usize) -> Self::Value; } diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 6dd2a36bf2648..da5da58d1674d 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -36,10 +36,8 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn with_cx(cx: &'a Self::CodegenCx) -> Self; fn build_sibling_block<'b>(&self, name: &'b str) -> Self; fn cx(&self) -> &Self::CodegenCx; - fn llfn(&self) -> Self::Value; fn llbb(&self) -> Self::BasicBlock; - fn set_value_name(&mut self, value: Self::Value, name: &str); fn position_at_end(&mut self, llbb: Self::BasicBlock); fn ret_void(&mut self); fn ret(&mut self, v: Self::Value); @@ -209,6 +207,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: else_val: Self::Value, ) -> Self::Value; + fn va_arg(&mut self, list: Self::Value, ty: Self::Type) -> Self::Value; fn extract_element(&mut self, vec: Self::Value, idx: Self::Value) -> Self::Value; fn vector_splat(&mut self, num_elts: usize, elt: Self::Value) -> Self::Value; fn extract_value(&mut self, agg_val: Self::Value, idx: u64) -> Self::Value; diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index dcbb4e66cb385..a0b53fde09c4d 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -58,4 +58,5 @@ pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes { span: Span, ); fn insert_reference_to_gdb_debug_scripts_section_global(&mut self); + fn set_value_name(&mut self, value: Self::Value, name: &str); } diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs index b3d458f3a3be8..2797dd89f5b15 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/src/librustc_codegen_ssa/traits/misc.rs @@ -14,7 +14,6 @@ pub trait MiscMethods<'tcx>: BackendTypes { fn check_overflow(&self) -> bool; fn instances(&self) -> &RefCell, Self::Value>>; fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value; - fn get_param(&self, llfn: Self::Value, index: usize) -> Self::Value; fn eh_personality(&self) -> Self::Value; fn eh_unwind_resume(&self) -> Self::Value; fn sess(&self) -> &Session; From b0ee1f7f99c1190d51ecdb592e23b868f488a346 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 7 Dec 2018 18:04:34 +0100 Subject: [PATCH 13/18] Remove scalar_lltypes from cg_ssa --- src/librustc_codegen_llvm/type_.rs | 6 ------ src/librustc_codegen_ssa/traits/type_.rs | 3 --- 2 files changed, 9 deletions(-) diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index d5424fa459166..426c70fb2dc58 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -11,7 +11,6 @@ use rustc_codegen_ssa::traits::*; use crate::common; use crate::type_of::LayoutLlvmExt; use crate::abi::{LlvmType, FnTypeExt}; -use rustc::util::nodemap::FxHashMap; use rustc::ty::Ty; use rustc::ty::layout::TyLayout; use rustc_target::abi::call::{CastTarget, FnType, Reg}; @@ -19,7 +18,6 @@ use rustc_data_structures::small_c_str::SmallCStr; use rustc_codegen_ssa::common::TypeKind; use std::fmt; -use std::cell::RefCell; use std::ptr; use libc::c_uint; @@ -232,10 +230,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn val_ty(&self, v: &'ll Value) -> &'ll Type { common::val_ty(v) } - - fn scalar_lltypes(&self) -> &RefCell, Self::Type>> { - &self.scalar_lltypes - } } impl Type { diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index fe00276a55a45..442b25ce0b61d 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -5,9 +5,7 @@ use crate::common::{self, TypeKind}; use crate::mir::place::PlaceRef; use rustc::ty::layout::{self, Align, Size, TyLayout}; use rustc::ty::{self, Ty}; -use rustc::util::nodemap::FxHashMap; use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg}; -use std::cell::RefCell; use syntax::ast; // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use @@ -49,7 +47,6 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { fn int_width(&self, ty: Self::Type) -> u64; fn val_ty(&self, v: Self::Value) -> Self::Type; - fn scalar_lltypes(&self) -> &RefCell, Self::Type>>; } pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { From 0e166bb217463a26028ad9b1724e686d54ba1415 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 1 Mar 2019 15:47:06 +0100 Subject: [PATCH 14/18] Remove a lot of methods from *TypeMethods --- src/librustc_codegen_llvm/type_.rs | 120 ++++++++++++++++------- src/librustc_codegen_ssa/common.rs | 16 +-- src/librustc_codegen_ssa/traits/type_.rs | 70 ++----------- 3 files changed, 92 insertions(+), 114 deletions(-) diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index 426c70fb2dc58..bcd90aeceb647 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -11,8 +11,9 @@ use rustc_codegen_ssa::traits::*; use crate::common; use crate::type_of::LayoutLlvmExt; use crate::abi::{LlvmType, FnTypeExt}; +use syntax::ast; use rustc::ty::Ty; -use rustc::ty::layout::TyLayout; +use rustc::ty::layout::{self, Align, Size, TyLayout}; use rustc_target::abi::call::{CastTarget, FnType, Reg}; use rustc_data_structures::small_c_str::SmallCStr; use rustc_codegen_ssa::common::TypeKind; @@ -50,21 +51,99 @@ impl CodegenCx<'ll, 'tcx> { els.len() as c_uint, packed as Bool) } } -} -impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { - fn type_void(&self) -> &'ll Type { + crate fn type_void(&self) -> &'ll Type { unsafe { llvm::LLVMVoidTypeInContext(self.llcx) } } - fn type_metadata(&self) -> &'ll Type { + crate fn type_metadata(&self) -> &'ll Type { unsafe { llvm::LLVMRustMetadataTypeInContext(self.llcx) } } + ///x Creates an integer type with the given number of bits, e.g., i24 + crate fn type_ix(&self, num_bits: u64) -> &'ll Type { + unsafe { + llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) + } + } + + crate fn type_x86_mmx(&self) -> &'ll Type { + unsafe { + llvm::LLVMX86MMXTypeInContext(self.llcx) + } + } + + crate fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type { + unsafe { + llvm::LLVMVectorType(ty, len as c_uint) + } + } + + crate fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> { + unsafe { + let n_args = llvm::LLVMCountParamTypes(ty) as usize; + let mut args = Vec::with_capacity(n_args); + llvm::LLVMGetParamTypes(ty, args.as_mut_ptr()); + args.set_len(n_args); + args + } + } + + crate fn type_bool(&self) -> &'ll Type { + self.type_i8() + } + + crate fn type_int_from_ty(&self, t: ast::IntTy) -> &'ll Type { + match t { + ast::IntTy::Isize => self.type_isize(), + ast::IntTy::I8 => self.type_i8(), + ast::IntTy::I16 => self.type_i16(), + ast::IntTy::I32 => self.type_i32(), + ast::IntTy::I64 => self.type_i64(), + ast::IntTy::I128 => self.type_i128(), + } + } + + crate fn type_uint_from_ty(&self, t: ast::UintTy) -> &'ll Type { + match t { + ast::UintTy::Usize => self.type_isize(), + ast::UintTy::U8 => self.type_i8(), + ast::UintTy::U16 => self.type_i16(), + ast::UintTy::U32 => self.type_i32(), + ast::UintTy::U64 => self.type_i64(), + ast::UintTy::U128 => self.type_i128(), + } + } + + crate fn type_float_from_ty(&self, t: ast::FloatTy) -> &'ll Type { + match t { + ast::FloatTy::F32 => self.type_f32(), + ast::FloatTy::F64 => self.type_f64(), + } + } + + crate fn type_pointee_for_align(&self, align: Align) -> &'ll Type { + // FIXME(eddyb) We could find a better approximation if ity.align < align. + let ity = layout::Integer::approximate_align(self, align); + self.type_from_integer(ity) + } + + /// Return a LLVM type that has at most the required alignment, + /// and exactly the required size, as a best-effort padding array. + crate fn type_padding_filler(&self, size: Size, align: Align) -> &'ll Type { + let unit = layout::Integer::approximate_align(self, align); + let size = size.bytes(); + let unit_size = unit.size().bytes(); + assert_eq!(size % unit_size, 0); + self.type_array(self.type_from_integer(unit), size / unit_size) + } +} + +impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn type_i1(&self) -> &'ll Type { unsafe { llvm::LLVMInt1TypeInContext(self.llcx) @@ -102,12 +181,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - fn type_ix(&self, num_bits: u64) -> &'ll Type { - unsafe { - llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) - } - } - fn type_isize(&self) -> &'ll Type { self.isize_ty } @@ -124,12 +197,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - fn type_x86_mmx(&self) -> &'ll Type { - unsafe { - llvm::LLVMX86MMXTypeInContext(self.llcx) - } - } - fn type_func( &self, args: &[&'ll Type], @@ -171,12 +238,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type { - unsafe { - llvm::LLVMVectorType(ty, len as c_uint) - } - } - fn type_kind(&self, ty: &'ll Type) -> TypeKind { unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() @@ -201,16 +262,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> { - unsafe { - let n_args = llvm::LLVMCountParamTypes(ty) as usize; - let mut args = Vec::with_capacity(n_args); - llvm::LLVMGetParamTypes(ty, args.as_mut_ptr()); - args.set_len(n_args); - args - } - } - fn float_width(&self, ty: &'ll Type) -> usize { match self.type_kind(ty) { TypeKind::Float => 32, @@ -288,9 +339,6 @@ impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn cast_backend_type(&self, ty: &CastTarget) -> &'ll Type { ty.llvm_type(self) } - fn fn_backend_type(&self, ty: &FnType<'tcx, Ty<'tcx>>) -> &'ll Type { - ty.llvm_type(self) - } fn fn_ptr_backend_type(&self, ty: &FnType<'tcx, Ty<'tcx>>) -> &'ll Type { ty.ptr_to_llvm_type(self) } diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs index db77074deef94..0e1885fe29ba6 100644 --- a/src/librustc_codegen_ssa/common.rs +++ b/src/librustc_codegen_ssa/common.rs @@ -1,7 +1,7 @@ #![allow(non_camel_case_types, non_snake_case)] -use rustc::ty::{self, Ty, TyCtxt}; -use syntax_pos::{DUMMY_SP, Span}; +use rustc::ty::{Ty, TyCtxt}; +use syntax_pos::Span; use rustc::hir::def_id::DefId; use rustc::middle::lang_items::LangItem; @@ -11,18 +11,6 @@ use crate::traits::*; use rustc::hir; use crate::traits::BuilderMethods; -pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) -} - -pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) -} - -pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.is_freeze(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP) -} - pub enum IntPredicate { IntEQ, IntNE, diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 442b25ce0b61d..8d7f225d9950b 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -1,38 +1,31 @@ use super::misc::MiscMethods; use super::Backend; use super::HasCodegen; -use crate::common::{self, TypeKind}; +use crate::common::TypeKind; use crate::mir::place::PlaceRef; -use rustc::ty::layout::{self, Align, Size, TyLayout}; use rustc::ty::{self, Ty}; +use rustc::ty::layout::{self, TyLayout}; use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg}; -use syntax::ast; +use syntax_pos::DUMMY_SP; // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves. pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { - fn type_void(&self) -> Self::Type; - fn type_metadata(&self) -> Self::Type; fn type_i1(&self) -> Self::Type; fn type_i8(&self) -> Self::Type; fn type_i16(&self) -> Self::Type; fn type_i32(&self) -> Self::Type; fn type_i64(&self) -> Self::Type; fn type_i128(&self) -> Self::Type; - - // Creates an integer type with the given number of bits, e.g., i24 - fn type_ix(&self, num_bits: u64) -> Self::Type; fn type_isize(&self) -> Self::Type; fn type_f32(&self) -> Self::Type; fn type_f64(&self) -> Self::Type; - fn type_x86_mmx(&self) -> Self::Type; fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; fn type_variadic_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type; fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type; - fn type_vector(&self, ty: Self::Type, len: u64) -> Self::Type; fn type_kind(&self, ty: Self::Type) -> TypeKind; fn type_ptr_to(&self, ty: Self::Type) -> Self::Type; fn element_type(&self, ty: Self::Type) -> Self::Type; @@ -40,7 +33,6 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { /// Returns the number of elements in `self` if it is a LLVM vector type. fn vector_length(&self, ty: Self::Type) -> usize; - fn func_params_types(&self, ty: Self::Type) -> Vec; fn float_width(&self, ty: Self::Type) -> usize; /// Retrieves the bit width of the integer type `self`. @@ -50,10 +42,6 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { } pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { - fn type_bool(&self) -> Self::Type { - self.type_i8() - } - fn type_i8p(&self) -> Self::Type { self.type_ptr_to(self.type_i8()) } @@ -67,35 +55,6 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { } } - fn type_int_from_ty(&self, t: ast::IntTy) -> Self::Type { - match t { - ast::IntTy::Isize => self.type_isize(), - ast::IntTy::I8 => self.type_i8(), - ast::IntTy::I16 => self.type_i16(), - ast::IntTy::I32 => self.type_i32(), - ast::IntTy::I64 => self.type_i64(), - ast::IntTy::I128 => self.type_i128(), - } - } - - fn type_uint_from_ty(&self, t: ast::UintTy) -> Self::Type { - match t { - ast::UintTy::Usize => self.type_isize(), - ast::UintTy::U8 => self.type_i8(), - ast::UintTy::U16 => self.type_i16(), - ast::UintTy::U32 => self.type_i32(), - ast::UintTy::U64 => self.type_i64(), - ast::UintTy::U128 => self.type_i128(), - } - } - - fn type_float_from_ty(&self, t: ast::FloatTy) -> Self::Type { - match t { - ast::FloatTy::F32 => self.type_f32(), - ast::FloatTy::F64 => self.type_f64(), - } - } - fn type_from_integer(&self, i: layout::Integer) -> Self::Type { use rustc::ty::layout::Integer::*; match i { @@ -107,32 +66,16 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { } } - fn type_pointee_for_align(&self, align: Align) -> Self::Type { - // FIXME(eddyb) We could find a better approximation if ity.align < align. - let ity = layout::Integer::approximate_align(self, align); - self.type_from_integer(ity) - } - - /// Return a LLVM type that has at most the required alignment, - /// and exactly the required size, as a best-effort padding array. - fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type { - let unit = layout::Integer::approximate_align(self, align); - let size = size.bytes(); - let unit_size = unit.size().bytes(); - assert_eq!(size % unit_size, 0); - self.type_array(self.type_from_integer(unit), size / unit_size) - } - fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { - common::type_needs_drop(self.tcx(), ty) + ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all()) } fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - common::type_is_sized(self.tcx(), ty) + ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) } fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - common::type_is_freeze(self.tcx(), ty) + ty.is_freeze(self.tcx(), ty::ParamEnv::reveal_all(), DUMMY_SP) } fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { @@ -155,7 +98,6 @@ impl DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscM pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> { fn backend_type(&self, layout: TyLayout<'tcx>) -> Self::Type; fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type; - fn fn_backend_type(&self, ty: &FnType<'tcx, Ty<'tcx>>) -> Self::Type; fn fn_ptr_backend_type(&self, ty: &FnType<'tcx, Ty<'tcx>>) -> Self::Type; fn reg_backend_type(&self, ty: &Reg) -> Self::Type; fn immediate_backend_type(&self, layout: TyLayout<'tcx>) -> Self::Type; From b71c429007e6ce1dcbae2f909cf5cd6d10a9901d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 8 Dec 2018 11:48:43 +0100 Subject: [PATCH 15/18] Remove type_variadic_func and typ_array from cg_ssa --- src/librustc_codegen_llvm/builder.rs | 72 +++++++++++++++------- src/librustc_codegen_llvm/type_.rs | 35 +++++------ src/librustc_codegen_ssa/mir/rvalue.rs | 29 ++------- src/librustc_codegen_ssa/traits/builder.rs | 15 ++--- src/librustc_codegen_ssa/traits/type_.rs | 2 - 5 files changed, 80 insertions(+), 73 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 8e6299a45ae03..c2da49e3ac97e 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -652,7 +652,37 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { OperandRef { val, layout: place.layout } } + fn write_operand_repeatedly( + mut self, + cg_elem: OperandRef<'tcx, &'ll Value>, + count: u64, + dest: PlaceRef<'tcx, &'ll Value>, + ) -> Self { + let zero = self.const_usize(0); + let count = self.const_usize(count); + let start = dest.project_index(&mut self, zero).llval; + let end = dest.project_index(&mut self, count).llval; + + let mut header_bx = self.build_sibling_block("repeat_loop_header"); + let mut body_bx = self.build_sibling_block("repeat_loop_body"); + let next_bx = self.build_sibling_block("repeat_loop_next"); + + self.br(header_bx.llbb()); + let current = header_bx.phi(self.val_ty(start), &[start], &[self.llbb()]); + + let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end); + header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb()); + let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size); + cg_elem.val.store(&mut body_bx, + PlaceRef::new_sized(current, cg_elem.layout, align)); + + let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]); + body_bx.br(header_bx.llbb()); + header_bx.add_incoming_to_phi(current, next, body_bx.llbb()); + + next_bx + } fn range_metadata(&mut self, load: &'ll Value, range: Range) { if self.sess().target.target.arch == "amdgpu" { @@ -873,20 +903,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } /* Miscellaneous instructions */ - fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value { - self.count_insn("addincoming"); - assert_eq!(vals.len(), bbs.len()); - let phi = unsafe { - llvm::LLVMBuildPhi(self.llbuilder, ty, noname()) - }; - unsafe { - llvm::LLVMAddIncoming(phi, vals.as_ptr(), - bbs.as_ptr(), - vals.len() as c_uint); - phi - } - } - fn inline_asm_call(&mut self, asm: &CStr, cons: &CStr, inputs: &[&'ll Value], output: &'ll Type, volatile: bool, alignstack: bool, @@ -1188,13 +1204,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn add_incoming_to_phi(&mut self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) { - self.count_insn("addincoming"); - unsafe { - llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint); - } - } - fn set_invariant_load(&mut self, load: &'ll Value) { unsafe { llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint, @@ -1526,4 +1535,25 @@ impl Builder<'a, 'll, 'tcx> { let ptr = self.pointercast(ptr, self.cx.type_i8p()); self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None); } + + fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value { + self.count_insn("addincoming"); + assert_eq!(vals.len(), bbs.len()); + let phi = unsafe { + llvm::LLVMBuildPhi(self.llbuilder, ty, noname()) + }; + unsafe { + llvm::LLVMAddIncoming(phi, vals.as_ptr(), + bbs.as_ptr(), + vals.len() as c_uint); + phi + } + } + + fn add_incoming_to_phi(&mut self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) { + self.count_insn("addincoming"); + unsafe { + llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint); + } + } } diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index bcd90aeceb647..a5ed64a66a39d 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -141,6 +141,23 @@ impl CodegenCx<'ll, 'tcx> { assert_eq!(size % unit_size, 0); self.type_array(self.type_from_integer(unit), size / unit_size) } + + crate fn type_variadic_func( + &self, + args: &[&'ll Type], + ret: &'ll Type + ) -> &'ll Type { + unsafe { + llvm::LLVMFunctionType(ret, args.as_ptr(), + args.len() as c_uint, True) + } + } + + crate fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type { + unsafe { + llvm::LLVMRustArrayType(ty, len) + } + } } impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -208,17 +225,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - fn type_variadic_func( - &self, - args: &[&'ll Type], - ret: &'ll Type - ) -> &'ll Type { - unsafe { - llvm::LLVMFunctionType(ret, args.as_ptr(), - args.len() as c_uint, True) - } - } - fn type_struct( &self, els: &[&'ll Type], @@ -231,13 +237,6 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } - - fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type { - unsafe { - llvm::LLVMRustArrayType(ty, len) - } - } - fn type_kind(&self, ty: &'ll Type) -> TypeKind { unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index c20d3f44bc528..7a31c5b3950e0 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -87,11 +87,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if dest.layout.is_zst() { return bx; } - let zero = bx.cx().const_usize(0); - let start = dest.project_index(&mut bx, zero).llval; if let OperandValue::Immediate(v) = cg_elem.val { - let size = bx.cx().const_usize(dest.layout.size.bytes()); + let zero = bx.const_usize(0); + let start = dest.project_index(&mut bx, zero).llval; + let size = bx.const_usize(dest.layout.size.bytes()); // Use llvm.memset.p0i8.* to initialize all zero arrays if bx.cx().is_const_integral(v) && bx.cx().const_to_uint(v) == 0 { @@ -108,28 +108,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - let count = bx.cx().const_usize(count); - let end = dest.project_index(&mut bx, count).llval; - - let mut header_bx = bx.build_sibling_block("repeat_loop_header"); - let mut body_bx = bx.build_sibling_block("repeat_loop_body"); - let next_bx = bx.build_sibling_block("repeat_loop_next"); - - bx.br(header_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()); - - let align = dest.align.restrict_for_offset(dest.layout.field(bx.cx(), 0).size); - cg_elem.val.store(&mut body_bx, - PlaceRef::new_sized(current, cg_elem.layout, align)); - - let next = body_bx.inbounds_gep(current, &[bx.cx().const_usize(1)]); - body_bx.br(header_bx.llbb()); - header_bx.add_incoming_to_phi(current, next, body_bx.llbb()); - - next_bx + bx.write_operand_repeatedly(cg_elem, count, dest) } mir::Rvalue::Aggregate(ref kind, ref operands) => { diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index da5da58d1674d..e121299363fda 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -116,6 +116,14 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>) -> OperandRef<'tcx, Self::Value>; + /// Called for Rvalue::Repeat when the elem is neither a ZST nor optimizable using memset. + fn write_operand_repeatedly( + self, + elem: OperandRef<'tcx, Self::Value>, + count: u64, + dest: PlaceRef<'tcx, Self::Value>, + ) -> Self; + fn range_metadata(&mut self, load: Self::Value, range: Range); fn nonnull_metadata(&mut self, load: Self::Value); @@ -156,12 +164,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; - fn phi( - &mut self, - ty: Self::Type, - vals: &[Self::Value], - bbs: &[Self::BasicBlock], - ) -> Self::Value; fn inline_asm_call( &mut self, asm: &CStr, @@ -255,7 +257,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: ) -> Self::Value; fn atomic_fence(&mut self, order: AtomicOrdering, scope: SynchronizationScope); fn add_case(&mut self, s: Self::Value, on_val: Self::Value, dest: Self::BasicBlock); - fn add_incoming_to_phi(&mut self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock); fn set_invariant_load(&mut self, load: Self::Value); /// Called for `StorageLive` diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 8d7f225d9950b..7fb2cb9d39362 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -23,9 +23,7 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { fn type_f64(&self) -> Self::Type; fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; - fn type_variadic_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type; - fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type; fn type_kind(&self, ty: Self::Type) -> TypeKind; fn type_ptr_to(&self, ty: Self::Type) -> Self::Type; fn element_type(&self, ty: Self::Type) -> Self::Type; From b2e61946fa0dd5058165ed7c36f30b42c168cc02 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 8 Dec 2018 16:07:27 +0100 Subject: [PATCH 16/18] Remove inline_asm_call from cg_ssa `count_insn` is no longer called for inline asm, because it is private to builder.rs --- src/librustc_codegen_llvm/asm.rs | 48 +++++++++++++++++++++- src/librustc_codegen_llvm/builder.rs | 42 +------------------ src/librustc_codegen_ssa/traits/builder.rs | 14 ------- 3 files changed, 47 insertions(+), 57 deletions(-) diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs index 4427308f4155d..100a896ea0c7d 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/src/librustc_codegen_llvm/asm.rs @@ -10,7 +10,7 @@ use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::mir::operand::OperandValue; -use std::ffi::CString; +use std::ffi::{CStr, CString}; use libc::{c_uint, c_char}; @@ -73,7 +73,8 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { let asm = CString::new(ia.asm.as_str().as_bytes()).unwrap(); let constraint_cstr = CString::new(all_constraints).unwrap(); - let r = self.inline_asm_call( + let r = inline_asm_call( + self, &asm, &constraint_cstr, &inputs, @@ -119,3 +120,46 @@ impl AsmMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } } + +fn inline_asm_call( + bx: &mut Builder<'a, 'll, 'tcx>, + asm: &CStr, + cons: &CStr, + inputs: &[&'ll Value], + output: &'ll llvm::Type, + volatile: bool, + alignstack: bool, + dia: ::syntax::ast::AsmDialect, +) -> Option<&'ll Value> { + let volatile = if volatile { llvm::True } + else { llvm::False }; + let alignstack = if alignstack { llvm::True } + else { llvm::False }; + + let argtys = inputs.iter().map(|v| { + debug!("Asm Input Type: {:?}", *v); + bx.cx.val_ty(*v) + }).collect::>(); + + debug!("Asm Output Type: {:?}", output); + let fty = bx.cx.type_func(&argtys[..], output); + unsafe { + // Ask LLVM to verify that the constraints are well-formed. + let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr()); + debug!("Constraint verification result: {:?}", constraints_ok); + if constraints_ok { + let v = llvm::LLVMRustInlineAsm( + fty, + asm.as_ptr(), + cons.as_ptr(), + volatile, + alignstack, + llvm::AsmDialect::from_generic(dia), + ); + Some(bx.call(v, inputs, None)) + } else { + // LLVM has detected an issue with our constraints, bail out + None + } + } +} diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index c2da49e3ac97e..f53bb6a196a99 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -1,4 +1,4 @@ -use crate::llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; +use crate::llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope}; use crate::llvm::{self, False, BasicBlock}; use crate::common::Funclet; use crate::context::CodegenCx; @@ -19,7 +19,6 @@ use rustc_codegen_ssa::base::to_immediate; use rustc_codegen_ssa::mir::operand::{OperandValue, OperandRef}; use rustc_codegen_ssa::mir::place::PlaceRef; use std::borrow::Cow; -use std::ffi::CStr; use std::ops::{Deref, Range}; use std::ptr; @@ -903,45 +902,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } /* Miscellaneous instructions */ - fn inline_asm_call(&mut self, asm: &CStr, cons: &CStr, - inputs: &[&'ll Value], output: &'ll Type, - volatile: bool, alignstack: bool, - dia: syntax::ast::AsmDialect) -> Option<&'ll Value> { - self.count_insn("inlineasm"); - - let volatile = if volatile { llvm::True } - else { llvm::False }; - let alignstack = if alignstack { llvm::True } - else { llvm::False }; - - let argtys = inputs.iter().map(|v| { - debug!("Asm Input Type: {:?}", *v); - self.cx.val_ty(*v) - }).collect::>(); - - debug!("Asm Output Type: {:?}", output); - let fty = self.type_func(&argtys[..], output); - unsafe { - // Ask LLVM to verify that the constraints are well-formed. - let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr()); - debug!("Constraint verification result: {:?}", constraints_ok); - if constraints_ok { - let v = llvm::LLVMRustInlineAsm( - fty, - asm.as_ptr(), - cons.as_ptr(), - volatile, - alignstack, - AsmDialect::from_generic(dia), - ); - Some(self.call(v, inputs, None)) - } else { - // LLVM has detected an issue with our constraints, bail out - None - } - } - } - fn memcpy(&mut self, dst: &'ll Value, dst_align: Align, src: &'ll Value, src_align: Align, size: &'ll Value, flags: MemFlags) { diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index e121299363fda..e54ae76022217 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -11,10 +11,7 @@ use crate::mir::place::PlaceRef; use crate::MemFlags; use rustc::ty::Ty; use rustc::ty::layout::{Align, Size}; -use std::ffi::CStr; - use std::ops::Range; -use syntax::ast::AsmDialect; #[derive(Copy, Clone)] pub enum OverflowOp { @@ -164,17 +161,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; - fn inline_asm_call( - &mut self, - asm: &CStr, - cons: &CStr, - inputs: &[Self::Value], - output: Self::Type, - volatile: bool, - alignstack: bool, - dia: AsmDialect, - ) -> Option; - fn memcpy( &mut self, dst: Self::Value, From 56842b2154c0c2dd243f64e864b9c6aee718a161 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 8 Dec 2018 18:42:31 +0100 Subject: [PATCH 17/18] Add a method for emiting a switch. --- src/librustc_codegen_llvm/builder.rs | 17 +++++++++-------- src/librustc_codegen_ssa/mir/block.rs | 17 +++++++---------- src/librustc_codegen_ssa/traits/builder.rs | 5 +++-- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index f53bb6a196a99..fbeb978413a92 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -170,9 +170,16 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { v: &'ll Value, else_llbb: &'ll BasicBlock, num_cases: usize, - ) -> &'ll Value { - unsafe { + cases: impl Iterator, + ) { + let switch = unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint) + }; + for (on_val, dest) in cases { + let on_val = self.const_uint_big(self.val_ty(v), on_val); + unsafe { + llvm::LLVMAddCase(switch, on_val, dest) + } } } @@ -1158,12 +1165,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn add_case(&mut self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) { - unsafe { - llvm::LLVMAddCase(s, on_val, dest) - } - } - fn set_invariant_load(&mut self, load: &'ll Value) { unsafe { llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint, diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index f0e8a18c479b1..0ce97553bea77 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -214,17 +214,14 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } else { let (otherwise, targets) = targets.split_last().unwrap(); - let switch = bx.switch(discr.immediate(), - helper.llblock(self, *otherwise), - values.len()); - let switch_llty = bx.immediate_backend_type( - bx.layout_of(switch_ty) + bx.switch( + discr.immediate(), + helper.llblock(self, *otherwise), + values.len(), + values.iter().zip(targets).map(|(&value, target)| { + (value, helper.llblock(self, *target)) + }) ); - for (&value, target) in values.iter().zip(targets) { - let llval = bx.const_uint_big(switch_llty, value); - let llbb = helper.llblock(self, *target); - bx.add_case(switch, llval, llbb) - } } } diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index e54ae76022217..3b0f047d97414 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -50,7 +50,8 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: v: Self::Value, else_llbb: Self::BasicBlock, num_cases: usize, - ) -> Self::Value; + cases: impl Iterator, + ); fn invoke( &mut self, llfn: Self::Value, @@ -60,6 +61,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: funclet: Option<&Self::Funclet>, ) -> Self::Value; fn unreachable(&mut self); + fn add(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; fn fadd_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; @@ -242,7 +244,6 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: order: AtomicOrdering, ) -> Self::Value; fn atomic_fence(&mut self, order: AtomicOrdering, scope: SynchronizationScope); - fn add_case(&mut self, s: Self::Value, on_val: Self::Value, dest: Self::BasicBlock); fn set_invariant_load(&mut self, load: Self::Value); /// Called for `StorageLive` From 35705dee7eb10783280e0be92aedfc187e019dd2 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 29 Mar 2019 17:23:52 +0100 Subject: [PATCH 18/18] Use ExactSizeIterator + TrustedLen instead of num_cases arg for switch --- src/librustc_codegen_llvm/builder.rs | 6 +++--- src/librustc_codegen_llvm/lib.rs | 1 + src/librustc_codegen_ssa/lib.rs | 1 + src/librustc_codegen_ssa/mir/block.rs | 1 - src/librustc_codegen_ssa/traits/builder.rs | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index fbeb978413a92..123fda1e215ff 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -21,6 +21,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef; use std::borrow::Cow; use std::ops::{Deref, Range}; use std::ptr; +use std::iter::TrustedLen; // All Builders must have an llfn associated with them #[must_use] @@ -169,11 +170,10 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { &mut self, v: &'ll Value, else_llbb: &'ll BasicBlock, - num_cases: usize, - cases: impl Iterator, + cases: impl ExactSizeIterator + TrustedLen, ) { let switch = unsafe { - llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint) + llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) }; for (on_val, dest) in cases { let on_val = self.const_uint_big(self.val_ty(v), on_val); diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index c95feafa29aba..0aae6b46e3def 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -20,6 +20,7 @@ #![feature(concat_idents)] #![feature(link_args)] #![feature(static_nobundle)] +#![feature(trusted_len)] #![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index fe9b88c85f009..1e898ced7a600 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -10,6 +10,7 @@ #![feature(try_blocks)] #![feature(in_band_lifetimes)] #![feature(nll)] +#![feature(trusted_len)] #![allow(unused_attributes)] #![allow(dead_code)] #![deny(rust_2018_idioms)] diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 0ce97553bea77..98da07a905e25 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -217,7 +217,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.switch( discr.immediate(), helper.llblock(self, *otherwise), - values.len(), values.iter().zip(targets).map(|(&value, target)| { (value, helper.llblock(self, *target)) }) diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 3b0f047d97414..48142fc9fa9f4 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -12,6 +12,7 @@ use crate::MemFlags; use rustc::ty::Ty; use rustc::ty::layout::{Align, Size}; use std::ops::Range; +use std::iter::TrustedLen; #[derive(Copy, Clone)] pub enum OverflowOp { @@ -49,8 +50,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: &mut self, v: Self::Value, else_llbb: Self::BasicBlock, - num_cases: usize, - cases: impl Iterator, + cases: impl ExactSizeIterator + TrustedLen, ); fn invoke( &mut self,