Always run intrinsics lowering pass
Move intrinsics lowering pass from the optimization phase (where it would not run if -Zmir-opt-level=0), to the drop lowering phase where it runs unconditionally. The implementation of those intrinsics in code generation and interpreter is unnecessary. Remove it.
This commit is contained in:
parent
e15ec667ce
commit
a9ff4bd838
9 changed files with 38 additions and 39 deletions
|
@ -83,9 +83,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::unreachable => {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sym::va_start => bx.va_start(args[0].immediate()),
|
sym::va_start => bx.va_start(args[0].immediate()),
|
||||||
sym::va_end => bx.va_end(args[0].immediate()),
|
sym::va_end => bx.va_end(args[0].immediate()),
|
||||||
sym::size_of_val => {
|
sym::size_of_val => {
|
||||||
|
@ -106,8 +103,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes())
|
bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sym::size_of
|
sym::pref_align_of
|
||||||
| sym::pref_align_of
|
|
||||||
| sym::min_align_of
|
| sym::min_align_of
|
||||||
| sym::needs_drop
|
| sym::needs_drop
|
||||||
| sym::type_id
|
| sym::type_id
|
||||||
|
@ -119,10 +115,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
|
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
|
||||||
}
|
}
|
||||||
// Effectively no-op
|
|
||||||
sym::forget => {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sym::offset => {
|
sym::offset => {
|
||||||
let ptr = args[0].immediate();
|
let ptr = args[0].immediate();
|
||||||
let offset = args[1].immediate();
|
let offset = args[1].immediate();
|
||||||
|
@ -218,9 +210,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
sym::add_with_overflow
|
sym::add_with_overflow
|
||||||
| sym::sub_with_overflow
|
| sym::sub_with_overflow
|
||||||
| sym::mul_with_overflow
|
| sym::mul_with_overflow
|
||||||
| sym::wrapping_add
|
|
||||||
| sym::wrapping_sub
|
|
||||||
| sym::wrapping_mul
|
|
||||||
| sym::unchecked_div
|
| sym::unchecked_div
|
||||||
| sym::unchecked_rem
|
| sym::unchecked_rem
|
||||||
| sym::unchecked_shl
|
| sym::unchecked_shl
|
||||||
|
@ -254,9 +243,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sym::wrapping_add => bx.add(args[0].immediate(), args[1].immediate()),
|
|
||||||
sym::wrapping_sub => bx.sub(args[0].immediate(), args[1].immediate()),
|
|
||||||
sym::wrapping_mul => bx.mul(args[0].immediate(), args[1].immediate()),
|
|
||||||
sym::exact_div => {
|
sym::exact_div => {
|
||||||
if signed {
|
if signed {
|
||||||
bx.exactsdiv(args[0].immediate(), args[1].immediate())
|
bx.exactsdiv(args[0].immediate(), args[1].immediate())
|
||||||
|
|
|
@ -61,12 +61,11 @@ crate fn eval_nullary_intrinsic<'tcx>(
|
||||||
ConstValue::Slice { data: alloc, start: 0, end: alloc.len() }
|
ConstValue::Slice { data: alloc, start: 0, end: alloc.len() }
|
||||||
}
|
}
|
||||||
sym::needs_drop => ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)),
|
sym::needs_drop => ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)),
|
||||||
sym::size_of | sym::min_align_of | sym::pref_align_of => {
|
sym::min_align_of | sym::pref_align_of => {
|
||||||
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?;
|
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?;
|
||||||
let n = match name {
|
let n = match name {
|
||||||
sym::pref_align_of => layout.align.pref.bytes(),
|
sym::pref_align_of => layout.align.pref.bytes(),
|
||||||
sym::min_align_of => layout.align.abi.bytes(),
|
sym::min_align_of => layout.align.abi.bytes(),
|
||||||
sym::size_of => layout.size.bytes(),
|
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
ConstValue::from_machine_usize(n, &tcx)
|
ConstValue::from_machine_usize(n, &tcx)
|
||||||
|
@ -125,7 +124,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let (dest, ret) = match ret {
|
let (dest, ret) = match ret {
|
||||||
None => match intrinsic_name {
|
None => match intrinsic_name {
|
||||||
sym::transmute => throw_ub_format!("transmuting to uninhabited type"),
|
sym::transmute => throw_ub_format!("transmuting to uninhabited type"),
|
||||||
sym::unreachable => throw_ub!(Unreachable),
|
|
||||||
sym::abort => M::abort(self, "the program aborted execution".to_owned())?,
|
sym::abort => M::abort(self, "the program aborted execution".to_owned())?,
|
||||||
// Unsupported diverging intrinsic.
|
// Unsupported diverging intrinsic.
|
||||||
_ => return Ok(false),
|
_ => return Ok(false),
|
||||||
|
@ -160,13 +158,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
sym::min_align_of
|
sym::min_align_of
|
||||||
| sym::pref_align_of
|
| sym::pref_align_of
|
||||||
| sym::needs_drop
|
| sym::needs_drop
|
||||||
| sym::size_of
|
|
||||||
| sym::type_id
|
| sym::type_id
|
||||||
| sym::type_name
|
| sym::type_name
|
||||||
| sym::variant_count => {
|
| sym::variant_count => {
|
||||||
let gid = GlobalId { instance, promoted: None };
|
let gid = GlobalId { instance, promoted: None };
|
||||||
let ty = match intrinsic_name {
|
let ty = match intrinsic_name {
|
||||||
sym::min_align_of | sym::pref_align_of | sym::size_of | sym::variant_count => {
|
sym::min_align_of | sym::pref_align_of | sym::variant_count => {
|
||||||
self.tcx.types.usize
|
self.tcx.types.usize
|
||||||
}
|
}
|
||||||
sym::needs_drop => self.tcx.types.bool,
|
sym::needs_drop => self.tcx.types.bool,
|
||||||
|
@ -212,29 +209,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let out_val = numeric_intrinsic(intrinsic_name, bits, kind)?;
|
let out_val = numeric_intrinsic(intrinsic_name, bits, kind)?;
|
||||||
self.write_scalar(out_val, dest)?;
|
self.write_scalar(out_val, dest)?;
|
||||||
}
|
}
|
||||||
sym::wrapping_add
|
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
|
||||||
| sym::wrapping_sub
|
|
||||||
| sym::wrapping_mul
|
|
||||||
| sym::add_with_overflow
|
|
||||||
| sym::sub_with_overflow
|
|
||||||
| sym::mul_with_overflow => {
|
|
||||||
let lhs = self.read_immediate(args[0])?;
|
let lhs = self.read_immediate(args[0])?;
|
||||||
let rhs = self.read_immediate(args[1])?;
|
let rhs = self.read_immediate(args[1])?;
|
||||||
let (bin_op, ignore_overflow) = match intrinsic_name {
|
let bin_op = match intrinsic_name {
|
||||||
sym::wrapping_add => (BinOp::Add, true),
|
sym::add_with_overflow => BinOp::Add,
|
||||||
sym::wrapping_sub => (BinOp::Sub, true),
|
sym::sub_with_overflow => BinOp::Sub,
|
||||||
sym::wrapping_mul => (BinOp::Mul, true),
|
sym::mul_with_overflow => BinOp::Mul,
|
||||||
sym::add_with_overflow => (BinOp::Add, false),
|
|
||||||
sym::sub_with_overflow => (BinOp::Sub, false),
|
|
||||||
sym::mul_with_overflow => (BinOp::Mul, false),
|
|
||||||
_ => bug!("Already checked for int ops"),
|
_ => bug!("Already checked for int ops"),
|
||||||
};
|
};
|
||||||
if ignore_overflow {
|
|
||||||
self.binop_ignore_overflow(bin_op, lhs, rhs, dest)?;
|
|
||||||
} else {
|
|
||||||
self.binop_with_overflow(bin_op, lhs, rhs, dest)?;
|
self.binop_with_overflow(bin_op, lhs, rhs, dest)?;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
sym::saturating_add | sym::saturating_sub => {
|
sym::saturating_add | sym::saturating_sub => {
|
||||||
let l = self.read_immediate(args[0])?;
|
let l = self.read_immediate(args[0])?;
|
||||||
let r = self.read_immediate(args[1])?;
|
let r = self.read_immediate(args[1])?;
|
||||||
|
|
|
@ -364,6 +364,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
|
||||||
// `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
|
// `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
|
||||||
// but before optimizations begin.
|
// but before optimizations begin.
|
||||||
&add_retag::AddRetag,
|
&add_retag::AddRetag,
|
||||||
|
&lower_intrinsics::LowerIntrinsics,
|
||||||
&simplify::SimplifyCfg::new("elaborate-drops"),
|
&simplify::SimplifyCfg::new("elaborate-drops"),
|
||||||
// `Deaggregator` is conceptually part of MIR building, some backends rely on it happening
|
// `Deaggregator` is conceptually part of MIR building, some backends rely on it happening
|
||||||
// and it can help optimizations.
|
// and it can help optimizations.
|
||||||
|
@ -392,7 +393,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
|
|
||||||
// The main optimizations that we do on MIR.
|
// The main optimizations that we do on MIR.
|
||||||
let optimizations: &[&dyn MirPass<'tcx>] = &[
|
let optimizations: &[&dyn MirPass<'tcx>] = &[
|
||||||
&lower_intrinsics::LowerIntrinsics,
|
|
||||||
&remove_unneeded_drops::RemoveUnneededDrops,
|
&remove_unneeded_drops::RemoveUnneededDrops,
|
||||||
&match_branches::MatchBranchSimplification,
|
&match_branches::MatchBranchSimplification,
|
||||||
// inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
|
// inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
|
||||||
|
|
|
@ -120,5 +120,9 @@
|
||||||
bb5: {
|
bb5: {
|
||||||
return; // scope 0 at $DIR/lower_intrinsics.rs:73:2: 73:2
|
return; // scope 0 at $DIR/lower_intrinsics.rs:73:2: 73:2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb6 (cleanup): {
|
||||||
|
resume; // scope 0 at $DIR/lower_intrinsics.rs:68:1: 73:2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,15 @@
|
||||||
StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:19:40: 19:41
|
StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:19:40: 19:41
|
||||||
StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:19:43: 19:44
|
StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:19:43: 19:44
|
||||||
_0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:18:24: 20:2
|
_0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:18:24: 20:2
|
||||||
|
goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:20:1: 20:2
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
return; // scope 0 at $DIR/lower_intrinsics.rs:20:2: 20:2
|
return; // scope 0 at $DIR/lower_intrinsics.rs:20:2: 20:2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb3 (cleanup): {
|
||||||
|
resume; // scope 0 at $DIR/lower_intrinsics.rs:18:1: 20:2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,9 @@
|
||||||
StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:59:1: 59:2
|
StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:59:1: 59:2
|
||||||
return; // scope 0 at $DIR/lower_intrinsics.rs:59:2: 59:2
|
return; // scope 0 at $DIR/lower_intrinsics.rs:59:2: 59:2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb2 (cleanup): {
|
||||||
|
resume; // scope 0 at $DIR/lower_intrinsics.rs:55:1: 59:2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,5 +16,9 @@
|
||||||
bb1: {
|
bb1: {
|
||||||
return; // scope 0 at $DIR/lower_intrinsics.rs:15:2: 15:2
|
return; // scope 0 at $DIR/lower_intrinsics.rs:15:2: 15:2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb2 (cleanup): {
|
||||||
|
resume; // scope 0 at $DIR/lower_intrinsics.rs:13:1: 15:2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,5 +18,9 @@
|
||||||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(Scalar(<ZST>)) }
|
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(Scalar(<ZST>)) }
|
||||||
+ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:24:14: 24:45
|
+ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:24:14: 24:45
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb1 (cleanup): {
|
||||||
|
resume; // scope 0 at $DIR/lower_intrinsics.rs:23:1: 25:2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,5 +79,9 @@
|
||||||
StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:10:1: 10:2
|
StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:10:1: 10:2
|
||||||
return; // scope 0 at $DIR/lower_intrinsics.rs:10:2: 10:2
|
return; // scope 0 at $DIR/lower_intrinsics.rs:10:2: 10:2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb4 (cleanup): {
|
||||||
|
resume; // scope 0 at $DIR/lower_intrinsics.rs:6:1: 10:2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue