diff options
| author | bors <bors@rust-lang.org> | 2018-12-02 18:02:20 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-12-02 18:02:20 +0000 |
| commit | 21f26849506c141a6760532ca5bdfd8345247fdb (patch) | |
| tree | a9a9bbcf59c5b72c1d90d5e1ae9d8003b659deb7 /src/librustc_codegen_ssa | |
| parent | 8660eba2b9bec5b0fe971b7281f79e79c2df2fae (diff) | |
| parent | d108a913c79660ab375aff33ea9caa2885ba3051 (diff) | |
| download | rust-21f26849506c141a6760532ca5bdfd8345247fdb.tar.gz rust-21f26849506c141a6760532ca5bdfd8345247fdb.zip | |
Auto merge of #56198 - bjorn3:cg_ssa_refactor, r=eddyb
Refactor rustc_codegen_ssa cc #56108 (not all things are done yet) This removes an unsafe method from cg_ssa. r? @eddyb cc @sunfishcode
Diffstat (limited to 'src/librustc_codegen_ssa')
24 files changed, 187 insertions, 276 deletions
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 856bb9533c8..266f78996b3 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -192,7 +192,7 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>( (_, &ty::Dynamic(ref data, ..)) => { let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target)) .field(cx, FAT_PTR_EXTRA); - cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()), + cx.const_ptrcast(meth::get_vtable(cx, source, data.principal()), cx.backend_type(vtable_ptr)) } _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", @@ -366,14 +366,6 @@ pub fn wants_msvc_seh(sess: &Session) -> bool { sess.target.target.options.is_like_msvc } -pub fn call_assume<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( - bx: &mut Bx, - val: Bx::Value -) { - let assume_intrinsic = bx.cx().get_intrinsic("llvm.assume"); - bx.call(assume_intrinsic, &[val], None); -} - pub fn from_immediate<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, val: Bx::Value diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs index 6259318a3c9..8c53129abc3 100644 --- a/src/librustc_codegen_ssa/common.rs +++ b/src/librustc_codegen_ssa/common.rs @@ -194,7 +194,7 @@ fn shift_mask_rhs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, rhs: Bx::Value ) -> Bx::Value { - let rhs_llty = bx.cx().val_ty(rhs); + let rhs_llty = bx.val_ty(rhs); let shift_val = shift_mask_val(bx, rhs_llty, rhs_llty, false); bx.and(rhs, shift_val) } @@ -205,25 +205,25 @@ pub fn shift_mask_val<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( mask_llty: Bx::Type, invert: bool ) -> Bx::Value { - let kind = bx.cx().type_kind(llty); + let kind = bx.type_kind(llty); match kind { TypeKind::Integer => { // i8/u8 can shift by at most 7, i16/u16 by at most 15, etc. - let val = bx.cx().int_width(llty) - 1; + let val = bx.int_width(llty) - 1; if invert { - bx.cx().const_int(mask_llty, !val as i64) + bx.const_int(mask_llty, !val as i64) } else { - bx.cx().const_uint(mask_llty, val) + bx.const_uint(mask_llty, val) } }, TypeKind::Vector => { let mask = shift_mask_val( bx, - bx.cx().element_type(llty), - bx.cx().element_type(mask_llty), + bx.element_type(llty), + bx.element_type(mask_llty), invert ); - bx.vector_splat(bx.cx().vector_length(mask_llty), mask) + bx.vector_splat(bx.vector_length(mask_llty), mask) }, _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind), } diff --git a/src/librustc_codegen_ssa/debuginfo.rs b/src/librustc_codegen_ssa/debuginfo.rs index 0fc61422bb3..bcf6d7b6bf8 100644 --- a/src/librustc_codegen_ssa/debuginfo.rs +++ b/src/librustc_codegen_ssa/debuginfo.rs @@ -23,22 +23,21 @@ impl<D> FunctionDebugContext<D> { match *self { FunctionDebugContext::RegularContext(ref data) => data, FunctionDebugContext::DebugInfoDisabled => { - span_bug!(span, "{}", FunctionDebugContext::<D>::debuginfo_disabled_message()); + span_bug!( + span, + "debuginfo: Error trying to access FunctionDebugContext \ + although debug info is disabled!", + ); } FunctionDebugContext::FunctionWithoutDebugInfo => { - span_bug!(span, "{}", FunctionDebugContext::<D>::should_be_ignored_message()); + span_bug!( + span, + "debuginfo: Error trying to access FunctionDebugContext \ + for function that should be ignored by debug info!", + ); } } } - - fn debuginfo_disabled_message() -> &'static str { - "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!" - } - - fn should_be_ignored_message() -> &'static str { - "debuginfo: Error trying to access FunctionDebugContext for function that should be \ - ignored by debug info!" - } } /// Enables emitting source locations for the given functions. diff --git a/src/librustc_codegen_ssa/glue.rs b/src/librustc_codegen_ssa/glue.rs index bb28ea74dc0..b3257dbc36b 100644 --- a/src/librustc_codegen_ssa/glue.rs +++ b/src/librustc_codegen_ssa/glue.rs @@ -16,7 +16,6 @@ use std; use common::IntPredicate; use meth; -use rustc::ty::layout::LayoutOf; use rustc::ty::{self, Ty}; use traits::*; @@ -25,12 +24,12 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( t: Ty<'tcx>, info: Option<Bx::Value> ) -> (Bx::Value, Bx::Value) { - let layout = bx.cx().layout_of(t); + let layout = bx.layout_of(t); debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout); if !layout.is_unsized() { - let size = bx.cx().const_usize(layout.size.bytes()); - let align = bx.cx().const_usize(layout.align.abi.bytes()); + let size = bx.const_usize(layout.size.bytes()); + let align = bx.const_usize(layout.align.abi.bytes()); return (size, align); } match t.sty { @@ -40,11 +39,11 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( (meth::SIZE.get_usize(bx, vtable), meth::ALIGN.get_usize(bx, vtable)) } ty::Slice(_) | ty::Str => { - let unit = layout.field(bx.cx(), 0); + let unit = layout.field(bx, 0); // The info in this case is the length of the str, so the size is that // times the unit size. - (bx.mul(info.unwrap(), bx.cx().const_usize(unit.size.bytes())), - bx.cx().const_usize(unit.align.abi.bytes())) + (bx.mul(info.unwrap(), bx.const_usize(unit.size.bytes())), + bx.const_usize(unit.align.abi.bytes())) } _ => { // First get the size of all statically known fields. @@ -58,12 +57,12 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let sized_align = layout.align.abi.bytes(); debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align); - let sized_size = bx.cx().const_usize(sized_size); - let sized_align = bx.cx().const_usize(sized_align); + let sized_size = bx.const_usize(sized_size); + let sized_align = bx.const_usize(sized_align); // Recurse to get the size of the dynamically sized field (must be // the last field). - let field_ty = layout.field(bx.cx(), i).ty; + let field_ty = layout.field(bx, i).ty; let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info); // FIXME (#26403, #27023): We should be adding padding @@ -85,12 +84,12 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Choose max of two known alignments (combined value must // be aligned according to more restrictive of the two). - let align = match (bx.cx().const_to_opt_u128(sized_align, false), - bx.cx().const_to_opt_u128(unsized_align, false)) { + let align = match (bx.const_to_opt_u128(sized_align, false), + bx.const_to_opt_u128(unsized_align, false)) { (Some(sized_align), Some(unsized_align)) => { // If both alignments are constant, (the sized_align should always be), then // pick the correct alignment statically. - bx.cx().const_usize(std::cmp::max(sized_align, unsized_align) as u64) + bx.const_usize(std::cmp::max(sized_align, unsized_align) as u64) } _ => { let cmp = bx.icmp(IntPredicate::IntUGT, sized_align, unsized_align); @@ -108,7 +107,7 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // emulated via the semi-standard fast bit trick: // // `(size + (align-1)) & -align` - let one = bx.cx().const_usize(1); + let one = bx.const_usize(1); let addend = bx.sub(align, one); let add = bx.add(size, addend); let neg = bx.neg(align); diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index d70fcf60fdf..3880935f0f4 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -39,10 +39,10 @@ impl<'a, 'tcx: 'a> VirtualIndex { let llvtable = bx.pointercast( llvtable, - bx.cx().type_ptr_to(bx.cx().fn_ptr_backend_type(fn_ty)) + bx.type_ptr_to(bx.fn_ptr_backend_type(fn_ty)) ); let ptr_align = bx.tcx().data_layout.pointer_align.abi; - let gep = bx.inbounds_gep(llvtable, &[bx.cx().const_usize(self.0)]); + let gep = bx.inbounds_gep(llvtable, &[bx.const_usize(self.0)]); let ptr = bx.load(gep, ptr_align); bx.nonnull_metadata(ptr); // Vtable loads are invariant @@ -58,9 +58,9 @@ impl<'a, 'tcx: 'a> VirtualIndex { // Load the data pointer from the object. debug!("get_int({:?}, {:?})", llvtable, self); - let llvtable = bx.pointercast(llvtable, bx.cx().type_ptr_to(bx.cx().type_isize())); + let llvtable = bx.pointercast(llvtable, bx.type_ptr_to(bx.type_isize())); let usize_align = bx.tcx().data_layout.pointer_align.abi; - let gep = bx.inbounds_gep(llvtable, &[bx.cx().const_usize(self.0)]); + let gep = bx.inbounds_gep(llvtable, &[bx.const_usize(self.0)]); let ptr = bx.load(gep, usize_align); // Vtable loads are invariant bx.set_invariant_load(ptr); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 75a6f07124a..a3bfbc2211c 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -182,22 +182,20 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let lp1 = bx.load_operand(lp1).immediate(); slot.storage_dead(&mut bx); - if !bx.cx().sess().target.target.options.custom_unwind_resume { - let mut lp = bx.cx().const_undef(self.landing_pad_type()); + if !bx.sess().target.target.options.custom_unwind_resume { + let mut lp = bx.const_undef(self.landing_pad_type()); lp = bx.insert_value(lp, lp0, 0); lp = bx.insert_value(lp, lp1, 1); bx.resume(lp); } else { - bx.call(bx.cx().eh_unwind_resume(), &[lp0], funclet(self)); + bx.call(bx.eh_unwind_resume(), &[lp0], funclet(self)); bx.unreachable(); } } } mir::TerminatorKind::Abort => { - // Call core::intrinsics::abort() - let fnname = bx.cx().get_intrinsic(&("llvm.trap")); - bx.call(fnname, &[], None); + bx.abort(); bx.unreachable(); } @@ -220,10 +218,10 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.cond_br(discr.immediate(), lltrue, llfalse); } } else { - let switch_llty = bx.cx().immediate_backend_type( - bx.cx().layout_of(switch_ty) + let switch_llty = bx.immediate_backend_type( + bx.layout_of(switch_ty) ); - let llval = bx.cx().const_uint_big(switch_llty, values[0]); + let llval = bx.const_uint_big(switch_llty, values[0]); let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval); bx.cond_br(cmp, lltrue, llfalse); } @@ -232,11 +230,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let switch = bx.switch(discr.immediate(), llblock(self, *otherwise), values.len()); - let switch_llty = bx.cx().immediate_backend_type( - bx.cx().layout_of(switch_ty) + let switch_llty = bx.immediate_backend_type( + bx.layout_of(switch_ty) ); for (&value, target) in values.iter().zip(targets) { - let llval = bx.cx().const_uint_big(switch_llty, value); + let llval = bx.const_uint_big(switch_llty, value); let llbb = llblock(self, *target); bx.add_case(switch, llval, llbb) } @@ -285,8 +283,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llval } }; - let addr = bx.pointercast(llslot, bx.cx().type_ptr_to( - bx.cx().cast_backend_type(&cast_ty) + let addr = bx.pointercast(llslot, bx.type_ptr_to( + bx.cast_backend_type(&cast_ty) )); bx.load(addr, self.fn_ty.ret.layout.align.abi) } @@ -301,7 +299,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::TerminatorKind::Drop { ref location, target, unwind } => { let ty = location.ty(self.mir, bx.tcx()).to_ty(bx.tcx()); let ty = self.monomorphize(&ty); - let drop_fn = monomorphize::resolve_drop_in_place(bx.cx().tcx(), ty); + let drop_fn = monomorphize::resolve_drop_in_place(bx.tcx(), ty); if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def { // we don't actually need to drop anything. @@ -325,14 +323,14 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ty::ParamEnv::reveal_all(), &sig, ); - let fn_ty = bx.cx().new_vtable(sig, &[]); + let fn_ty = bx.new_vtable(sig, &[]); let vtable = args[1]; args = &args[..1]; (meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_ty), fn_ty) } _ => { - (bx.cx().get_fn(drop_fn), - bx.cx().fn_type_of_instance(&drop_fn)) + (bx.get_fn(drop_fn), + bx.fn_type_of_instance(&drop_fn)) } }; do_call(self, &mut bx, fn_ty, drop_fn, args, @@ -342,7 +340,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => { let cond = self.codegen_operand(&mut bx, cond).immediate(); - let mut const_cond = bx.cx().const_to_opt_u128(cond, false).map(|c| c == 1); + let mut const_cond = bx.const_to_opt_u128(cond, false).map(|c| c == 1); // This case can currently arise only from functions marked // with #[rustc_inherit_overflow_checks] and inlined from @@ -351,7 +349,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // NOTE: Unlike binops, negation doesn't have its own // checked operation, just a comparison with the minimum // value, so we have to check for the assert message. - if !bx.cx().check_overflow() { + if !bx.check_overflow() { if let mir::interpret::EvalErrorKind::OverflowNeg = *msg { const_cond = Some(expected); } @@ -364,8 +362,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } // Pass the condition through llvm.expect for branch hinting. - let expect = bx.cx().get_intrinsic(&"llvm.expect.i1"); - let cond = bx.call(expect, &[cond, bx.cx().const_bool(expected)], None); + let cond = bx.expect(cond, expected); // Create the failure block and the conditional branch to it. let lltarget = llblock(self, target); @@ -381,11 +378,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(&mut bx, terminator.source_info); // Get the location information. - let loc = bx.cx().sess().source_map().lookup_char_pos(span.lo()); + 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.cx().const_str_slice(filename); - let line = bx.cx().const_u32(loc.line as u32); - let col = bx.cx().const_u32(loc.col.to_usize() as u32 + 1); + 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 = tcx.data_layout.aggregate_align.abi .max(tcx.data_layout.i32_align.abi) .max(tcx.data_layout.pointer_align.abi); @@ -396,8 +393,8 @@ 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.cx().const_struct(&[filename, line, col], false); - let file_line_col = bx.cx().static_addr_of( + 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") @@ -408,12 +405,12 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => { let str = msg.description(); let msg_str = Symbol::intern(str).as_str(); - let msg_str = bx.cx().const_str_slice(msg_str); - let msg_file_line_col = bx.cx().const_struct( + 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.cx().static_addr_of( + let msg_file_line_col = bx.static_addr_of( msg_file_line_col, align, Some("panic_loc") @@ -426,8 +423,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Obtain the panic entry point. let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item); let instance = ty::Instance::mono(bx.tcx(), def_id); - let fn_ty = bx.cx().fn_type_of_instance(&instance); - let llfn = bx.cx().get_fn(instance); + let fn_ty = bx.fn_type_of_instance(&instance); + let llfn = bx.get_fn(instance); // Codegen the actual panic invoke/call. do_call(self, &mut bx, fn_ty, llfn, &args, None, cleanup); @@ -449,7 +446,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (instance, mut llfn) = match callee.layout.ty.sty { ty::FnDef(def_id, substs) => { - (Some(ty::Instance::resolve(bx.cx().tcx(), + (Some(ty::Instance::resolve(bx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs).unwrap()), @@ -488,7 +485,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // we can do what we like. Here, we declare that transmuting // into an uninhabited type is impossible, so anything following // it must be unreachable. - assert_eq!(bx.cx().layout_of(sig.output()).abi, layout::Abi::Uninhabited); + assert_eq!(bx.layout_of(sig.output()).abi, layout::Abi::Uninhabited); bx.unreachable(); } return; @@ -502,7 +499,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_ty = match def { Some(ty::InstanceDef::Virtual(..)) => { - bx.cx().new_vtable(sig, &extra_args) + bx.new_vtable(sig, &extra_args) } Some(ty::InstanceDef::DropGlue(_, None)) => { // empty drop glue - a nop. @@ -510,18 +507,18 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { funclet_br(self, &mut bx, target); return; } - _ => bx.cx().new_fn_type(sig, &extra_args) + _ => bx.new_fn_type(sig, &extra_args) }; // emit a panic instead of instantiating an uninhabited type if (intrinsic == Some("init") || intrinsic == Some("uninit")) && fn_ty.ret.layout.abi.is_uninhabited() { - let loc = bx.cx().sess().source_map().lookup_char_pos(span.lo()); + 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.cx().const_str_slice(filename); - let line = bx.cx().const_u32(loc.line as u32); - let col = bx.cx().const_u32(loc.col.to_usize() as u32 + 1); + 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 = tcx.data_layout.aggregate_align.abi .max(tcx.data_layout.i32_align.abi) .max(tcx.data_layout.pointer_align.abi); @@ -532,12 +529,12 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if intrinsic == Some("init") { "zeroed" } else { "uninitialized" } ); let msg_str = Symbol::intern(&str).as_str(); - let msg_str = bx.cx().const_str_slice(msg_str); - let msg_file_line_col = bx.cx().const_struct( + 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.cx().static_addr_of( + let msg_file_line_col = bx.static_addr_of( msg_file_line_col, align, Some("panic_loc"), @@ -547,8 +544,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let def_id = common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem); let instance = ty::Instance::mono(bx.tcx(), def_id); - let fn_ty = bx.cx().fn_type_of_instance(&instance); - let llfn = bx.cx().get_fn(instance); + let fn_ty = bx.fn_type_of_instance(&instance); + let llfn = bx.get_fn(instance); // Codegen the actual panic invoke/call. do_call( @@ -580,7 +577,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let dest = match ret_dest { _ if fn_ty.ret.is_indirect() => llargs[0], ReturnDest::Nothing => { - bx.cx().const_undef(bx.cx().type_ptr_to(bx.memory_ty(&fn_ty.ret))) + bx.const_undef(bx.type_ptr_to(bx.memory_ty(&fn_ty.ret))) } ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.llval, @@ -614,7 +611,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); return OperandRef { val: Immediate(llval), - layout: bx.cx().layout_of(ty), + layout: bx.layout_of(ty), }; }, @@ -632,7 +629,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); return OperandRef { val: Immediate(llval), - layout: bx.cx().layout_of(ty) + layout: bx.layout_of(ty) }; } } @@ -642,7 +639,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }).collect(); - let callee_ty = instance.as_ref().unwrap().ty(bx.cx().tcx()); + let callee_ty = instance.as_ref().unwrap().ty(bx.tcx()); bx.codegen_intrinsic_call(callee_ty, &fn_ty, &args, dest, terminator.source_info.span); @@ -739,7 +736,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_ptr = match (llfn, instance) { (Some(llfn), _) => llfn, - (None, Some(instance)) => bx.cx().get_fn(instance), + (None, Some(instance)) => bx.get_fn(instance), _ => span_bug!(span, "no llfn for call"), }; @@ -763,7 +760,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) { // Fill padding with undef value, where applicable. if let Some(ty) = arg.pad { - llargs.push(bx.cx().const_undef(bx.cx().reg_backend_type(&ty))) + llargs.push(bx.const_undef(bx.reg_backend_type(&ty))) } if arg.is_ignore() { @@ -823,8 +820,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if by_ref && !arg.is_indirect() { // Have to load the argument, maybe while casting it. if let PassMode::Cast(ty) = arg.mode { - let addr = bx.pointercast(llval, bx.cx().type_ptr_to( - bx.cx().cast_backend_type(&ty)) + let addr = bx.pointercast(llval, bx.type_ptr_to( + bx.cast_backend_type(&ty)) ); llval = bx.load(addr, align.min(arg.layout.align.abi)); } else { @@ -1033,7 +1030,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place), LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"), LocalRef::Operand(None) => { - let dst_layout = bx.cx().layout_of(self.monomorphized_place_ty(dst)); + let dst_layout = bx.layout_of(self.monomorphized_place_ty(dst)); assert!(!dst_layout.ty.has_erasable_regions()); let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp"); place.storage_live(bx); @@ -1060,8 +1057,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { dst: PlaceRef<'tcx, Bx::Value> ) { let src = self.codegen_operand(bx, src); - let llty = bx.cx().backend_type(src.layout); - let cast_ptr = bx.pointercast(dst.llval, bx.cx().type_ptr_to(llty)); + let llty = bx.backend_type(src.layout); + let cast_ptr = bx.pointercast(dst.llval, bx.type_ptr_to(llty)); let align = src.layout.align.abi.min(dst.align); src.val.store(bx, PlaceRef::new_sized(cast_ptr, src.layout, align)); } diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 568e1f0b38a..c03fff78063 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -14,7 +14,7 @@ use rustc::mir; use rustc_data_structures::indexed_vec::Idx; use rustc::mir::interpret::{GlobalId, ConstValue}; use rustc::ty::{self, Ty}; -use rustc::ty::layout::{self, LayoutOf}; +use rustc::ty::layout; use syntax::source_map::Span; use traits::*; @@ -75,20 +75,20 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { c, )?; if let Some(prim) = field.val.try_to_scalar() { - let layout = bx.cx().layout_of(field_ty); + let layout = bx.layout_of(field_ty); let scalar = match layout.abi { layout::Abi::Scalar(ref x) => x, _ => bug!("from_const: invalid ByVal layout: {:#?}", layout) }; - Ok(bx.cx().scalar_to_backend( + Ok(bx.scalar_to_backend( prim, scalar, - bx.cx().immediate_backend_type(layout), + bx.immediate_backend_type(layout), )) } else { bug!("simd shuffle field {:?}", field) } }).collect(); - let llval = bx.cx().const_struct(&values?, false); + let llval = bx.const_struct(&values?, false); Ok((llval, c.ty)) }) .unwrap_or_else(|_| { @@ -98,8 +98,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); // We've errored, so we don't have to produce working code. let ty = self.monomorphize(&ty); - let llty = bx.cx().backend_type(bx.cx().layout_of(ty)); - (bx.cx().const_undef(llty), ty) + let llty = bx.backend_type(bx.layout_of(ty)); + (bx.const_undef(llty), ty) }) } } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index fdc9a37a9eb..a992364959e 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -10,7 +10,7 @@ use libc::c_uint; use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts}; -use rustc::ty::layout::{LayoutOf, TyLayout, HasTyCtxt}; +use rustc::ty::layout::{TyLayout, HasTyCtxt}; use rustc::mir::{self, Mir}; use rustc::ty::subst::Substs; use rustc::session::config::DebugInfo; @@ -266,14 +266,14 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let mut allocate_local = |local| { let decl = &mir.local_decls[local]; - let layout = bx.cx().layout_of(fx.monomorphize(&decl.ty)); + let layout = bx.layout_of(fx.monomorphize(&decl.ty)); assert!(!layout.ty.has_erasable_regions()); if let Some(name) = decl.name { // User variable let debug_scope = fx.scopes[decl.visibility_scope]; let dbg = debug_scope.is_valid() && - bx.cx().sess().opts.debuginfo == DebugInfo::Full; + bx.sess().opts.debuginfo == DebugInfo::Full; if !memory_locals.contains(local) && !dbg { debug!("alloc: {:?} ({}) -> operand", local, name); @@ -376,7 +376,7 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( { block_bxs.iter_enumerated().zip(cleanup_kinds).map(|((bb, &llbb), cleanup_kind)| { match *cleanup_kind { - CleanupKind::Funclet if base::wants_msvc_seh(bx.cx().sess()) => {} + CleanupKind::Funclet if base::wants_msvc_seh(bx.sess()) => {} _ => return (None, None) } @@ -415,8 +415,8 @@ fn create_funclets<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // C++ personality function, but `catch (...)` has no type so // it's null. The 64 here is actually a bitfield which // represents that this is a catch-all block. - let null = bx.cx().const_null(bx.cx().type_i8p()); - let sixty_four = bx.cx().const_i32(64); + let null = bx.const_null(bx.type_i8p()); + let sixty_four = bx.const_i32(64); funclet = cp_bx.catch_pad(cs, &[null, sixty_four, null]); cp_bx.br(llbb); } @@ -451,7 +451,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Get the argument scope, if it exists and if we need it. let arg_scope = scopes[mir::OUTERMOST_SOURCE_SCOPE]; - let arg_scope = if bx.cx().sess().opts.debuginfo == DebugInfo::Full { + let arg_scope = if bx.sess().opts.debuginfo == DebugInfo::Full { arg_scope.scope_metadata } else { None @@ -478,7 +478,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( _ => bug!("spread argument isn't a tuple?!") }; - let place = PlaceRef::alloca(bx, bx.cx().layout_of(arg_ty), &name); + let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty), &name); for i in 0..tupled_arg_tys.len() { let arg = &fx.fn_ty.args[idx]; idx += 1; @@ -524,18 +524,18 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( return local(OperandRef::new_zst(bx.cx(), arg.layout)); } PassMode::Direct(_) => { - let llarg = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint); + let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint); 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.cx().get_param(bx.llfn(), llarg_idx as c_uint); + let a = bx.get_param(bx.llfn(), llarg_idx as c_uint); bx.set_value_name(a, &(name.clone() + ".0")); llarg_idx += 1; - let b = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint); + let b = bx.get_param(bx.llfn(), llarg_idx as c_uint); bx.set_value_name(b, &(name + ".1")); llarg_idx += 1; @@ -552,16 +552,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.cx().get_param(bx.llfn(), llarg_idx as c_uint); + let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint); 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.cx().get_param(bx.llfn(), llarg_idx as c_uint); + let llarg = bx.get_param(bx.llfn(), llarg_idx as c_uint); llarg_idx += 1; - let llextra = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint); + let llextra = bx.get_param(bx.llfn(), llarg_idx as c_uint); llarg_idx += 1; let indirect_operand = OperandValue::Pair(llarg, llextra); @@ -599,7 +599,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // Or is it the closure environment? let (closure_layout, env_ref) = match arg.layout.ty.sty { ty::RawPtr(ty::TypeAndMut { ty, .. }) | - ty::Ref(_, ty, _) => (bx.cx().layout_of(ty), true), + ty::Ref(_, ty, _) => (bx.layout_of(ty), true), _ => (arg.layout, false) }; @@ -618,10 +618,10 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // doesn't actually strip the offset when splitting the closure // environment into its components so it ends up out of bounds. // (cuviper) It seems to be fine without the alloca on LLVM 6 and later. - let env_alloca = !env_ref && bx.cx().closure_env_needs_indirect_debuginfo(); + let env_alloca = !env_ref && bx.closure_env_needs_indirect_debuginfo(); let env_ptr = if env_alloca { let scratch = PlaceRef::alloca(bx, - bx.cx().layout_of(tcx.mk_mut_ptr(arg.layout.ty)), + bx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)), "__debuginfo_env_ptr"); bx.store(place.llval, scratch.llval, scratch.align); scratch.llval @@ -632,7 +632,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( for (i, (decl, ty)) in mir.upvar_decls.iter().zip(upvar_tys).enumerate() { let byte_offset_of_var_in_env = closure_layout.fields.offset(i).bytes(); - let ops = bx.cx().debuginfo_upvar_decls_ops_sequence(byte_offset_of_var_in_env); + let ops = bx.debuginfo_upvar_decls_ops_sequence(byte_offset_of_var_in_env); // The environment and the capture can each be indirect. diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index fefbc14e497..a85e75936de 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -484,8 +484,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } // Allow RalfJ to sleep soundly knowing that even refactorings that remove // the above error (or silence it under some conditions) will not cause UB - let fnname = bx.cx().get_intrinsic(&("llvm.trap")); - bx.call(fnname, &[], None); + bx.abort(); // We've errored, so we don't have to produce working code. let layout = bx.cx().layout_of(ty); bx.load_operand(PlaceRef::new_sized( diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index e6fd6dfca73..1aba53255e7 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -413,8 +413,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // and compile-time agree on values // With floats that won't always be true // so we generate an abort - let fnname = bx.cx().get_intrinsic(&("llvm.trap")); - bx.call(fnname, &[], None); + bx.abort(); let llval = bx.cx().const_undef( bx.cx().type_ptr_to(bx.cx().backend_type(layout)) ); @@ -424,7 +423,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Place::Static(box mir::Static { def_id, ty }) => { let layout = cx.layout_of(self.monomorphize(&ty)); - PlaceRef::new_sized(cx.get_static(def_id), layout, layout.align.abi) + PlaceRef::new_sized(bx.get_static(def_id), layout, layout.align.abi) }, mir::Place::Projection(box mir::Projection { ref base, diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 805c1a343d0..dc7b1ec37b2 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -337,7 +337,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llval, ll_t_in_const ); - base::call_assume(&mut bx, cmp); + bx.assume(cmp); } } } @@ -693,11 +693,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::BinOp::Mul => OverflowOp::Mul, _ => unreachable!() }; - let intrinsic = get_overflow_intrinsic(oop, bx, input_ty); - let res = bx.call(intrinsic, &[lhs, rhs], None); - - (bx.extract_value(res, 0), - bx.extract_value(res, 1)) + bx.checked_binop(oop, input_ty, lhs, rhs) } mir::BinOp::Shl | mir::BinOp::Shr => { let lhs_llty = bx.cx().val_ty(lhs); @@ -744,80 +740,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } -#[derive(Copy, Clone)] -enum OverflowOp { - Add, Sub, Mul -} - -fn get_overflow_intrinsic<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( - oop: OverflowOp, - bx: &mut Bx, - ty: Ty -) -> Bx::Value { - use syntax::ast::IntTy::*; - use syntax::ast::UintTy::*; - use rustc::ty::{Int, Uint}; - - let tcx = bx.tcx(); - - let new_sty = match ty.sty { - Int(Isize) => Int(tcx.sess.target.isize_ty), - Uint(Usize) => Uint(tcx.sess.target.usize_ty), - ref t @ Uint(_) | ref t @ Int(_) => t.clone(), - _ => panic!("tried to get overflow intrinsic for op applied to non-int type") - }; - - let name = match oop { - OverflowOp::Add => match new_sty { - Int(I8) => "llvm.sadd.with.overflow.i8", - Int(I16) => "llvm.sadd.with.overflow.i16", - Int(I32) => "llvm.sadd.with.overflow.i32", - Int(I64) => "llvm.sadd.with.overflow.i64", - Int(I128) => "llvm.sadd.with.overflow.i128", - - Uint(U8) => "llvm.uadd.with.overflow.i8", - Uint(U16) => "llvm.uadd.with.overflow.i16", - Uint(U32) => "llvm.uadd.with.overflow.i32", - Uint(U64) => "llvm.uadd.with.overflow.i64", - Uint(U128) => "llvm.uadd.with.overflow.i128", - - _ => unreachable!(), - }, - OverflowOp::Sub => match new_sty { - Int(I8) => "llvm.ssub.with.overflow.i8", - Int(I16) => "llvm.ssub.with.overflow.i16", - Int(I32) => "llvm.ssub.with.overflow.i32", - Int(I64) => "llvm.ssub.with.overflow.i64", - Int(I128) => "llvm.ssub.with.overflow.i128", - - Uint(U8) => "llvm.usub.with.overflow.i8", - Uint(U16) => "llvm.usub.with.overflow.i16", - Uint(U32) => "llvm.usub.with.overflow.i32", - Uint(U64) => "llvm.usub.with.overflow.i64", - Uint(U128) => "llvm.usub.with.overflow.i128", - - _ => unreachable!(), - }, - OverflowOp::Mul => match new_sty { - Int(I8) => "llvm.smul.with.overflow.i8", - Int(I16) => "llvm.smul.with.overflow.i16", - Int(I32) => "llvm.smul.with.overflow.i32", - Int(I64) => "llvm.smul.with.overflow.i64", - Int(I128) => "llvm.smul.with.overflow.i128", - - Uint(U8) => "llvm.umul.with.overflow.i8", - Uint(U16) => "llvm.umul.with.overflow.i16", - Uint(U32) => "llvm.umul.with.overflow.i32", - Uint(U64) => "llvm.umul.with.overflow.i64", - Uint(U128) => "llvm.umul.with.overflow.i128", - - _ => unreachable!(), - }, - }; - - bx.cx().get_intrinsic(&name) -} - fn cast_int_to_float<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, signed: bool, diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs index 0d058c85f33..568a7e7e160 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/src/librustc_codegen_ssa/mir/statement.rs @@ -89,7 +89,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let OperandValue::Immediate(_) = op.val { acc.push(op.immediate()); } else { - span_err!(bx.cx().sess(), span.to_owned(), E0669, + span_err!(bx.sess(), span.to_owned(), E0669, "invalid value for constraint in inline assembly"); } acc @@ -98,7 +98,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if input_vals.len() == inputs.len() { let res = bx.codegen_inline_asm(asm, outputs, input_vals); if !res { - span_err!(bx.cx().sess(), statement.source_info.span, E0668, + span_err!(bx.sess(), statement.source_info.span, E0668, "malformed inline assembly"); } } diff --git a/src/librustc_codegen_ssa/traits/abi.rs b/src/librustc_codegen_ssa/traits/abi.rs index f35eb84813f..c659a99e1c9 100644 --- a/src/librustc_codegen_ssa/traits/abi.rs +++ b/src/librustc_codegen_ssa/traits/abi.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::HasCodegen; +use super::BackendTypes; use rustc::ty::{FnSig, Instance, Ty}; use rustc_target::abi::call::FnType; @@ -18,6 +18,6 @@ pub trait AbiMethods<'tcx> { fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>>; } -pub trait AbiBuilderMethods<'tcx>: HasCodegen<'tcx> { +pub trait AbiBuilderMethods<'tcx>: BackendTypes { fn apply_attrs_callsite(&mut self, ty: &FnType<'tcx, Ty<'tcx>>, callsite: Self::Value); } diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/src/librustc_codegen_ssa/traits/asm.rs index 93e4869e937..0e56fe46a31 100644 --- a/src/librustc_codegen_ssa/traits/asm.rs +++ b/src/librustc_codegen_ssa/traits/asm.rs @@ -8,13 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::Backend; -use super::HasCodegen; +use super::BackendTypes; use mir::place::PlaceRef; use rustc::hir::{GlobalAsm, InlineAsm}; -pub trait AsmBuilderMethods<'tcx>: HasCodegen<'tcx> { - // Take an inline assembly expression and splat it out via LLVM +pub trait AsmBuilderMethods<'tcx>: BackendTypes { + /// Take an inline assembly expression and splat it out via LLVM fn codegen_inline_asm( &mut self, ia: &InlineAsm, @@ -23,6 +22,6 @@ pub trait AsmBuilderMethods<'tcx>: HasCodegen<'tcx> { ) -> bool; } -pub trait AsmMethods<'tcx>: Backend<'tcx> { +pub trait AsmMethods<'tcx> { fn codegen_global_asm(&self, ga: &GlobalAsm); } diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index b4d376cf5f0..b59f970ae06 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -26,7 +26,6 @@ pub trait BackendTypes { type Value: CodegenObject; type BasicBlock: Copy; type Type: CodegenObject; - type Context; type Funclet; type DIScope: Copy; @@ -39,7 +38,8 @@ pub trait Backend<'tcx>: impl<'tcx, T> Backend<'tcx> for T where Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>> -{} +{ +} pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send { fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Module; diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 0b3066f561c..c1349329c17 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -13,10 +13,11 @@ use super::asm::AsmBuilderMethods; use super::debuginfo::DebugInfoBuilderMethods; use super::intrinsic::IntrinsicCallMethods; use super::type_::ArgTypeMethods; -use super::HasCodegen; +use super::{HasCodegen, StaticBuilderMethods}; use common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope}; use mir::operand::OperandRef; use mir::place::PlaceRef; +use rustc::ty::Ty; use rustc::ty::layout::{Align, Size}; use std::ffi::CStr; use MemFlags; @@ -25,6 +26,13 @@ use std::borrow::Cow; use std::ops::Range; use syntax::ast::AsmDialect; +#[derive(Copy, Clone)] +pub enum OverflowOp { + Add, + Sub, + Mul, +} + pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen<'tcx> + DebugInfoBuilderMethods<'tcx> @@ -32,6 +40,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: + AbiBuilderMethods<'tcx> + IntrinsicCallMethods<'tcx> + AsmBuilderMethods<'tcx> + + StaticBuilderMethods<'tcx> { fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self; fn with_cx(cx: &'a Self::CodegenCx) -> Self; @@ -97,6 +106,14 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: fn fneg(&mut self, v: Self::Value) -> Self::Value; fn not(&mut self, v: Self::Value) -> Self::Value; + fn checked_binop( + &mut self, + oop: OverflowOp, + ty: Ty, + lhs: Self::Value, + rhs: Self::Value, + ) -> (Self::Value, Self::Value); + fn alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value; fn dynamic_alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value; fn array_alloca( @@ -297,18 +314,12 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: ) -> Cow<'b, [Self::Value]> where [Self::Value]: ToOwned; + + /// Called for `StorageLive` fn lifetime_start(&mut self, ptr: Self::Value, size: Size); - fn lifetime_end(&mut self, ptr: Self::Value, size: Size); - /// If LLVM lifetime intrinsic support is enabled (i.e. optimizations - /// on), and `ptr` is nonzero-sized, then extracts the size of `ptr` - /// and the intrinsic for `lt` and passes them to `emit`, which is in - /// charge of generating code to call the passed intrinsic on whatever - /// block of generated code is targeted for the intrinsic. - /// - /// If LLVM lifetime intrinsic support is disabled (i.e. optimizations - /// off) or `ptr` is zero-sized, then no-op (does not call `emit`). - fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: Self::Value, size: Size); + /// Called for `StorageDead` + fn lifetime_end(&mut self, ptr: Self::Value, size: Size); fn call( &mut self, diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index c0a54452195..af49410794e 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/src/librustc_codegen_ssa/traits/consts.rs @@ -8,16 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::Backend; +use super::BackendTypes; use 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>: Backend<'tcx> { +pub trait ConstMethods<'tcx>: BackendTypes { // Constant constructors - fn const_null(&self, t: Self::Type) -> Self::Value; fn const_undef(&self, t: Self::Type) -> Self::Value; fn const_int(&self, t: Self::Type, i: i64) -> Self::Value; @@ -61,4 +60,6 @@ pub trait ConstMethods<'tcx>: Backend<'tcx> { alloc: &Allocation, offset: layout::Size, ) -> PlaceRef<'tcx, Self::Value>; + + fn const_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; } diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index 643776fcd64..c4becf37059 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::Backend; -use super::HasCodegen; +use super::BackendTypes; use debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, VariableKind}; use rustc::hir::def_id::CrateNum; use rustc::mir; @@ -19,7 +18,7 @@ use rustc_mir::monomorphize::Instance; use syntax::ast::Name; use syntax_pos::{SourceFile, Span}; -pub trait DebugInfoMethods<'tcx>: Backend<'tcx> { +pub trait DebugInfoMethods<'tcx>: BackendTypes { fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value); /// Creates the function-specific debug context. @@ -51,7 +50,7 @@ pub trait DebugInfoMethods<'tcx>: Backend<'tcx> { fn debuginfo_upvar_decls_ops_sequence(&self, byte_offset_of_var_in_env: u64) -> [i64; 4]; } -pub trait DebugInfoBuilderMethods<'tcx>: HasCodegen<'tcx> { +pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes { fn declare_local( &mut self, dbg_context: &FunctionDebugContext<Self::DIScope>, diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs index 38ef52e3c8e..f9a29652843 100644 --- a/src/librustc_codegen_ssa/traits/declare.rs +++ b/src/librustc_codegen_ssa/traits/declare.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::Backend; +use super::BackendTypes; use rustc::hir::def_id::DefId; use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty; use rustc_mir::monomorphize::Instance; -pub trait DeclareMethods<'tcx>: Backend<'tcx> { +pub trait DeclareMethods<'tcx>: BackendTypes { /// Declare a global value. /// /// If there’s a value with the same name already declared, the function will @@ -71,7 +71,7 @@ pub trait DeclareMethods<'tcx>: Backend<'tcx> { fn get_defined_value(&self, name: &str) -> Option<Self::Value>; } -pub trait PreDefineMethods<'tcx>: Backend<'tcx> { +pub trait PreDefineMethods<'tcx>: BackendTypes { fn predefine_static( &self, def_id: DefId, diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/src/librustc_codegen_ssa/traits/intrinsic.rs index 53a7878796b..abc118e7708 100644 --- a/src/librustc_codegen_ssa/traits/intrinsic.rs +++ b/src/librustc_codegen_ssa/traits/intrinsic.rs @@ -8,14 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::Backend; -use super::HasCodegen; +use super::BackendTypes; use mir::operand::OperandRef; use rustc::ty::Ty; use rustc_target::abi::call::FnType; use syntax_pos::Span; -pub trait IntrinsicCallMethods<'tcx>: HasCodegen<'tcx> { +pub trait IntrinsicCallMethods<'tcx>: BackendTypes { /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs, /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, /// add them to librustc_codegen_llvm/context.rs @@ -27,11 +26,8 @@ pub trait IntrinsicCallMethods<'tcx>: HasCodegen<'tcx> { llresult: Self::Value, span: Span, ); -} - -pub trait IntrinsicDeclarationMethods<'tcx>: Backend<'tcx> { - fn get_intrinsic(&self, key: &str) -> Self::Value; - /// Declare any llvm intrinsics that you might need - fn declare_intrinsic(&self, key: &str) -> Option<Self::Value>; + fn abort(&mut self); + fn assume(&mut self, val: Self::Value); + fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value; } diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs index 0425b8e8e23..d8871dd3a58 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/src/librustc_codegen_ssa/traits/misc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::Backend; +use super::BackendTypes; use libc::c_uint; use rustc::mir::mono::Stats; use rustc::session::Session; @@ -18,7 +18,7 @@ use rustc_mir::monomorphize::partitioning::CodegenUnit; use std::cell::RefCell; use std::sync::Arc; -pub trait MiscMethods<'tcx>: Backend<'tcx> { +pub trait MiscMethods<'tcx>: BackendTypes { fn vtables( &self, ) -> &RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>), Self::Value>>; @@ -32,7 +32,6 @@ pub trait MiscMethods<'tcx>: Backend<'tcx> { fn stats(&self) -> &RefCell<Stats>; fn consume_stats(self) -> RefCell<Stats>; fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>; - fn statics_to_rauw(&self) -> &RefCell<Vec<(Self::Value, Self::Value)>>; fn closure_env_needs_indirect_debuginfo(&self) -> bool; fn used_statics(&self) -> &RefCell<Vec<Self::Value>>; fn set_frame_pointer_elimination(&self, llfn: Self::Value); diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index 5cff31e17b5..6251fc3d3f3 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -40,13 +40,13 @@ mod write; pub use self::abi::{AbiBuilderMethods, AbiMethods}; pub use self::asm::{AsmBuilderMethods, AsmMethods}; pub use self::backend::{Backend, BackendTypes, ExtraBackendMethods}; -pub use self::builder::BuilderMethods; +pub use self::builder::{BuilderMethods, OverflowOp}; pub use self::consts::ConstMethods; pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods}; pub use self::declare::{DeclareMethods, PreDefineMethods}; -pub use self::intrinsic::{IntrinsicCallMethods, IntrinsicDeclarationMethods}; +pub use self::intrinsic::IntrinsicCallMethods; pub use self::misc::MiscMethods; -pub use self::statics::StaticMethods; +pub use self::statics::{StaticMethods, StaticBuilderMethods}; pub use self::type_::{ ArgTypeMethods, BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMethods, }; @@ -62,10 +62,9 @@ pub trait CodegenMethods<'tcx>: + TypeMethods<'tcx> + MiscMethods<'tcx> + ConstMethods<'tcx> - + StaticMethods<'tcx> + + StaticMethods + DebugInfoMethods<'tcx> + AbiMethods<'tcx> - + IntrinsicDeclarationMethods<'tcx> + DeclareMethods<'tcx> + AsmMethods<'tcx> + PreDefineMethods<'tcx> @@ -77,22 +76,23 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where + TypeMethods<'tcx> + MiscMethods<'tcx> + ConstMethods<'tcx> - + StaticMethods<'tcx> + + StaticMethods + DebugInfoMethods<'tcx> + AbiMethods<'tcx> - + IntrinsicDeclarationMethods<'tcx> + DeclareMethods<'tcx> + AsmMethods<'tcx> + PreDefineMethods<'tcx> -{} +{ +} -pub trait HasCodegen<'tcx>: Backend<'tcx> { +pub trait HasCodegen<'tcx>: + Backend<'tcx> + ::std::ops::Deref<Target = <Self as HasCodegen<'tcx>>::CodegenCx> +{ type CodegenCx: CodegenMethods<'tcx> + BackendTypes< Value = Self::Value, BasicBlock = Self::BasicBlock, Type = Self::Type, - Context = Self::Context, Funclet = Self::Funclet, DIScope = Self::DIScope, >; diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs index 172c48f8a85..0e665fc29fc 100644 --- a/src/librustc_codegen_ssa/traits/statics.rs +++ b/src/librustc_codegen_ssa/traits/statics.rs @@ -8,16 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::Backend; +use super::BackendTypes; use rustc::hir::def_id::DefId; use rustc::ty::layout::Align; -pub trait StaticMethods<'tcx>: Backend<'tcx> { - fn static_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; - fn static_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; - fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; +pub trait StaticMethods: BackendTypes { fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; - fn get_static(&self, def_id: DefId) -> Self::Value; fn codegen_static(&self, def_id: DefId, is_mutable: bool); - unsafe fn static_replace_all_uses(&self, old_g: Self::Value, new_g: Self::Value); +} + +pub trait StaticBuilderMethods<'tcx>: BackendTypes { + fn get_static(&self, def_id: DefId) -> Self::Value; } diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 15976ac516d..1d31bdfa9f0 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -20,6 +20,8 @@ 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 +// `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; @@ -41,11 +43,9 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { 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_named_struct(&self, name: &str) -> 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 set_struct_body(&self, ty: Self::Type, els: &[Self::Type], packed: bool); fn type_ptr_to(&self, ty: Self::Type) -> Self::Type; fn element_type(&self, ty: Self::Type) -> Self::Type; |
