diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index bdd48b344749..cc09a0b20cfd 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -367,34 +367,6 @@ language_item_table! { DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait; - // A lang item for each of the 128-bit operators we can optionally lower. - I128AddFnLangItem, "i128_add", i128_add_fn, Target::Fn; - U128AddFnLangItem, "u128_add", u128_add_fn, Target::Fn; - I128SubFnLangItem, "i128_sub", i128_sub_fn, Target::Fn; - U128SubFnLangItem, "u128_sub", u128_sub_fn, Target::Fn; - I128MulFnLangItem, "i128_mul", i128_mul_fn, Target::Fn; - U128MulFnLangItem, "u128_mul", u128_mul_fn, Target::Fn; - I128DivFnLangItem, "i128_div", i128_div_fn, Target::Fn; - U128DivFnLangItem, "u128_div", u128_div_fn, Target::Fn; - I128RemFnLangItem, "i128_rem", i128_rem_fn, Target::Fn; - U128RemFnLangItem, "u128_rem", u128_rem_fn, Target::Fn; - I128ShlFnLangItem, "i128_shl", i128_shl_fn, Target::Fn; - U128ShlFnLangItem, "u128_shl", u128_shl_fn, Target::Fn; - I128ShrFnLangItem, "i128_shr", i128_shr_fn, Target::Fn; - U128ShrFnLangItem, "u128_shr", u128_shr_fn, Target::Fn; - // And overflow versions for the operators that are checkable. - // While MIR calls these Checked*, they return (T,bool), not Option. - I128AddoFnLangItem, "i128_addo", i128_addo_fn, Target::Fn; - U128AddoFnLangItem, "u128_addo", u128_addo_fn, Target::Fn; - I128SuboFnLangItem, "i128_subo", i128_subo_fn, Target::Fn; - U128SuboFnLangItem, "u128_subo", u128_subo_fn, Target::Fn; - I128MuloFnLangItem, "i128_mulo", i128_mulo_fn, Target::Fn; - U128MuloFnLangItem, "u128_mulo", u128_mulo_fn, Target::Fn; - I128ShloFnLangItem, "i128_shlo", i128_shlo_fn, Target::Fn; - U128ShloFnLangItem, "u128_shlo", u128_shlo_fn, Target::Fn; - I128ShroFnLangItem, "i128_shro", i128_shro_fn, Target::Fn; - U128ShroFnLangItem, "u128_shro", u128_shro_fn, Target::Fn; - // Align offset for stride != 1, must not panic. AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index db8e2f64e306..54d28b32accd 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1406,10 +1406,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, saturating_float_casts: bool = (false, parse_bool, [TRACKED], "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ the max/min integer respectively, and NaN is mapped to 0"), - lower_128bit_ops: Option = (None, parse_opt_bool, [TRACKED], - "rewrite operators on i128 and u128 into lang item calls (typically provided \ - by compiler-builtins) so codegen doesn't need to support them, - overriding the default for the current target"), human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], "generate human-readable, predictable names for codegen units"), dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 16fc46b66d9f..9746f46dbacc 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata; use crate::middle::lang_items; use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use crate::middle::stability; -use crate::mir::{self, Body, interpret, ProjectionKind}; +use crate::mir::{Body, interpret, ProjectionKind}; use crate::mir::interpret::{ConstValue, Allocation, Scalar}; use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst}; use crate::ty::ReprOptions; @@ -1297,40 +1297,6 @@ impl<'tcx> TyCtxt<'tcx> { self.get_lang_items(LOCAL_CRATE) } - /// Due to missing llvm support for lowering 128 bit math to software emulation - /// (on some targets), the lowering can be done in MIR. - /// - /// This function only exists until said support is implemented. - pub fn is_binop_lang_item(&self, def_id: DefId) -> Option<(mir::BinOp, bool)> { - let items = self.lang_items(); - let def_id = Some(def_id); - if items.i128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } - else if items.u128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } - else if items.i128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) } - else if items.u128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) } - else if items.i128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) } - else if items.u128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) } - else if items.i128_div_fn() == def_id { Some((mir::BinOp::Div, false)) } - else if items.u128_div_fn() == def_id { Some((mir::BinOp::Div, false)) } - else if items.i128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) } - else if items.u128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) } - else if items.i128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) } - else if items.u128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) } - else if items.i128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) } - else if items.u128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) } - else if items.i128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) } - else if items.u128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) } - else if items.i128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) } - else if items.u128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) } - else if items.i128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) } - else if items.u128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) } - else if items.i128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) } - else if items.u128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) } - else if items.i128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) } - else if items.u128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) } - else { None } - } - pub fn stability(self) -> &'tcx stability::Index<'tcx> { self.stability_index(LOCAL_CRATE) } diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index cf36c10a614e..097bc3fabd15 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -230,21 +230,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &mut self, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, M::PointerTag>], - dest: Option>, + _dest: Option>, ) -> InterpResult<'tcx, bool> { let def_id = instance.def_id(); - // Some fn calls are actually BinOp intrinsics - if let Some((op, oflo)) = self.tcx.is_binop_lang_item(def_id) { - let dest = dest.expect("128 lowerings can't diverge"); - let l = self.read_immediate(args[0])?; - let r = self.read_immediate(args[1])?; - if oflo { - self.binop_with_overflow(op, l, r, dest)?; - } else { - self.binop_ignore_overflow(op, l, r, dest)?; - } - return Ok(true); - } else if Some(def_id) == self.tcx.lang_items().panic_fn() { + if Some(def_id) == self.tcx.lang_items().panic_fn() { assert!(args.len() == 1); // &(&'static str, &'static str, u32, u32) let place = self.deref_operand(args[0])?; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 04ee14f5f59b..61685f445c8d 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -232,13 +232,6 @@ impl Inliner<'tcx> { return false; } - // Do not inline {u,i}128 lang items, codegen const eval depends - // on detecting calls to these lang items and intercepting them - if tcx.is_binop_lang_item(callsite.callee).is_some() { - debug!(" not inlining 128bit integer lang item"); - return false; - } - let codegen_fn_attrs = tcx.codegen_fn_attrs(callsite.callee); let hinted = match codegen_fn_attrs.inline { diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs deleted file mode 100644 index f09a77d486c7..000000000000 --- a/src/librustc_mir/transform/lower_128bit.rs +++ /dev/null @@ -1,230 +0,0 @@ -//! Replaces 128-bit operators with lang item calls - -use rustc::hir::def_id::DefId; -use rustc::middle::lang_items::LangItem; -use rustc::mir::*; -use rustc::ty::{self, List, Ty, TyCtxt}; -use rustc_data_structures::indexed_vec::{Idx}; -use crate::transform::{MirPass, MirSource}; - -pub struct Lower128Bit; - -impl MirPass for Lower128Bit { - fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { - let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops; - let target_default = tcx.sess.host.options.i128_lowering; - if !debugging_override.unwrap_or(target_default) { - return - } - - self.lower_128bit_ops(tcx, body); -} -} - -impl Lower128Bit { - fn lower_128bit_ops<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut new_blocks = Vec::new(); - let cur_len = body.basic_blocks().len(); - - let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); - for block in basic_blocks.iter_mut() { - for i in (0..block.statements.len()).rev() { - let (lang_item, rhs_kind) = - if let Some((lang_item, rhs_kind)) = - lower_to(&block.statements[i], local_decls, tcx) - { - (lang_item, rhs_kind) - } else { - continue; - }; - - let rhs_override_ty = rhs_kind.ty(tcx); - let cast_local = - match rhs_override_ty { - None => None, - Some(ty) => { - let local_decl = LocalDecl::new_internal( - ty, block.statements[i].source_info.span); - Some(local_decls.push(local_decl)) - }, - }; - - let storage_dead = cast_local.map(|local| { - Statement { - source_info: block.statements[i].source_info, - kind: StatementKind::StorageDead(local), - } - }); - let after_call = BasicBlockData { - statements: storage_dead.into_iter() - .chain(block.statements.drain((i+1)..)).collect(), - is_cleanup: block.is_cleanup, - terminator: block.terminator.take(), - }; - - let bin_statement = block.statements.pop().unwrap(); - let source_info = bin_statement.source_info; - let (place, lhs, mut rhs) = match bin_statement.kind { - StatementKind::Assign(place, box rvalue) => { - match rvalue { - Rvalue::BinaryOp(_, lhs, rhs) - | Rvalue::CheckedBinaryOp(_, lhs, rhs) => (place, lhs, rhs), - _ => bug!(), - } - } - _ => bug!() - }; - - if let Some(local) = cast_local { - block.statements.push(Statement { - source_info: source_info, - kind: StatementKind::StorageLive(local), - }); - block.statements.push(Statement { - source_info: source_info, - kind: StatementKind::Assign( - Place::from(local), - box Rvalue::Cast( - CastKind::Misc, - rhs, - rhs_override_ty.unwrap())), - }); - rhs = Operand::Move(Place::from(local)); - } - - let call_did = check_lang_item_type( - lang_item, &place, &lhs, &rhs, local_decls, tcx); - - let bb = BasicBlock::new(cur_len + new_blocks.len()); - new_blocks.push(after_call); - - block.terminator = - Some(Terminator { - source_info, - kind: TerminatorKind::Call { - func: Operand::function_handle(tcx, call_did, - List::empty(), source_info.span), - args: vec![lhs, rhs], - destination: Some((place, bb)), - cleanup: None, - from_hir_call: false, - }, - }); - } - } - - basic_blocks.extend(new_blocks); - } -} - -fn check_lang_item_type<'tcx, D>( - lang_item: LangItem, - place: &Place<'tcx>, - lhs: &Operand<'tcx>, - rhs: &Operand<'tcx>, - local_decls: &D, - tcx: TyCtxt<'tcx>, -) -> DefId -where - D: HasLocalDecls<'tcx>, -{ - let did = tcx.require_lang_item(lang_item); - let poly_sig = tcx.fn_sig(did); - let sig = poly_sig.no_bound_vars().unwrap(); - let lhs_ty = lhs.ty(local_decls, tcx); - let rhs_ty = rhs.ty(local_decls, tcx); - let place_ty = place.ty(local_decls, tcx).ty; - let expected = [lhs_ty, rhs_ty, place_ty]; - assert_eq!(sig.inputs_and_output[..], expected, - "lang item `{}`", tcx.def_path_str(did)); - did -} - -fn lower_to<'tcx, D>( - statement: &Statement<'tcx>, - local_decls: &D, - tcx: TyCtxt<'tcx>, -) -> Option<(LangItem, RhsKind)> -where - D: HasLocalDecls<'tcx>, -{ - match statement.kind { - StatementKind::Assign(_, box Rvalue::BinaryOp(bin_op, ref lhs, _)) => { - let ty = lhs.ty(local_decls, tcx); - if let Some(is_signed) = sign_of_128bit(ty) { - return item_for_op(bin_op, is_signed); - } - }, - StatementKind::Assign(_, box Rvalue::CheckedBinaryOp(bin_op, ref lhs, _)) => { - let ty = lhs.ty(local_decls, tcx); - if let Some(is_signed) = sign_of_128bit(ty) { - return item_for_checked_op(bin_op, is_signed); - } - }, - _ => {}, - } - None -} - -#[derive(Copy, Clone)] -enum RhsKind { - Unchanged, - ForceU128, - ForceU32, -} - -impl RhsKind { - fn ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option> { - match *self { - RhsKind::Unchanged => None, - RhsKind::ForceU128 => Some(tcx.types.u128), - RhsKind::ForceU32 => Some(tcx.types.u32), - } - } -} - -fn sign_of_128bit(ty: Ty<'_>) -> Option { - match ty.sty { - ty::Int(syntax::ast::IntTy::I128) => Some(true), - ty::Uint(syntax::ast::UintTy::U128) => Some(false), - _ => None, - } -} - -fn item_for_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { - let i = match (bin_op, is_signed) { - (BinOp::Add, true) => (LangItem::I128AddFnLangItem, RhsKind::Unchanged), - (BinOp::Add, false) => (LangItem::U128AddFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, true) => (LangItem::I128SubFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, false) => (LangItem::U128SubFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, true) => (LangItem::I128MulFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, false) => (LangItem::U128MulFnLangItem, RhsKind::Unchanged), - (BinOp::Div, true) => (LangItem::I128DivFnLangItem, RhsKind::Unchanged), - (BinOp::Div, false) => (LangItem::U128DivFnLangItem, RhsKind::Unchanged), - (BinOp::Rem, true) => (LangItem::I128RemFnLangItem, RhsKind::Unchanged), - (BinOp::Rem, false) => (LangItem::U128RemFnLangItem, RhsKind::Unchanged), - (BinOp::Shl, true) => (LangItem::I128ShlFnLangItem, RhsKind::ForceU32), - (BinOp::Shl, false) => (LangItem::U128ShlFnLangItem, RhsKind::ForceU32), - (BinOp::Shr, true) => (LangItem::I128ShrFnLangItem, RhsKind::ForceU32), - (BinOp::Shr, false) => (LangItem::U128ShrFnLangItem, RhsKind::ForceU32), - _ => return None, - }; - Some(i) -} - -fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { - let i = match (bin_op, is_signed) { - (BinOp::Add, true) => (LangItem::I128AddoFnLangItem, RhsKind::Unchanged), - (BinOp::Add, false) => (LangItem::U128AddoFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, true) => (LangItem::I128SuboFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, false) => (LangItem::U128SuboFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, true) => (LangItem::I128MuloFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, false) => (LangItem::U128MuloFnLangItem, RhsKind::Unchanged), - (BinOp::Shl, true) => (LangItem::I128ShloFnLangItem, RhsKind::ForceU128), - (BinOp::Shl, false) => (LangItem::U128ShloFnLangItem, RhsKind::ForceU128), - (BinOp::Shr, true) => (LangItem::I128ShroFnLangItem, RhsKind::ForceU128), - (BinOp::Shr, false) => (LangItem::U128ShroFnLangItem, RhsKind::ForceU128), - _ => bug!("That should be all the checked ones?"), - }; - Some(i) -} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 9e23d0614533..c7e6eed1d9a2 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -34,7 +34,6 @@ pub mod copy_prop; pub mod const_prop; pub mod generator; pub mod inline; -pub mod lower_128bit; pub mod uniform_array_move_out; pub(crate) fn provide(providers: &mut Providers<'_>) { @@ -272,8 +271,6 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> { // From here on out, regions are gone. &erase_regions::EraseRegions, - &lower_128bit::Lower128Bit, - // Optimizations begin. &uniform_array_move_out::RestoreSubsliceArrayMoveOut, diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1fdc9b015ba3..e78fda61a439 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -731,10 +731,6 @@ pub struct TargetOptions { /// for this target unconditionally. pub no_builtins: bool, - /// Whether to lower 128-bit operations to compiler_builtins calls. Use if - /// your backend only supports 64-bit and smaller math. - pub i128_lowering: bool, - /// The codegen backend to use for this target, typically "llvm" pub codegen_backend: String, @@ -850,7 +846,6 @@ impl Default for TargetOptions { requires_lto: false, singlethread: false, no_builtins: false, - i128_lowering: false, codegen_backend: "llvm".to_string(), default_hidden_visibility: false, embed_bitcode: false,