Auto merge of #98332 - oli-obk:assume, r=wesleywiser
Lower the assume intrinsic to a MIR statement This makes https://github.com/rust-lang/rust/pull/96862#issuecomment-1153739068 easier and will generally allow us to cheaply insert assume intrinsic calls in mir building. r? rust-lang/wg-mir-opt
This commit is contained in:
@@ -1362,13 +1362,7 @@ impl Debug for Statement<'_> {
|
||||
write!(fmt, "Coverage::{:?} for {:?}", kind, rgn)
|
||||
}
|
||||
Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind),
|
||||
CopyNonOverlapping(box crate::mir::CopyNonOverlapping {
|
||||
ref src,
|
||||
ref dst,
|
||||
ref count,
|
||||
}) => {
|
||||
write!(fmt, "copy_nonoverlapping(src={:?}, dst={:?}, count={:?})", src, dst, count)
|
||||
}
|
||||
Intrinsic(box ref intrinsic) => write!(fmt, "{intrinsic}"),
|
||||
Nop => write!(fmt, "nop"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str {
|
||||
Retag(..) => "Retag",
|
||||
AscribeUserType(..) => "AscribeUserType",
|
||||
Coverage(..) => "Coverage",
|
||||
CopyNonOverlapping(..) => "CopyNonOverlapping",
|
||||
Intrinsic(..) => "Intrinsic",
|
||||
Nop => "Nop",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,6 +327,34 @@ pub enum StatementKind<'tcx> {
|
||||
/// executed.
|
||||
Coverage(Box<Coverage>),
|
||||
|
||||
/// Denotes a call to an intrinsic that does not require an unwind path and always returns.
|
||||
/// This avoids adding a new block and a terminator for simple intrinsics.
|
||||
Intrinsic(Box<NonDivergingIntrinsic<'tcx>>),
|
||||
|
||||
/// No-op. Useful for deleting instructions without affecting statement indices.
|
||||
Nop,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
TyEncodable,
|
||||
TyDecodable,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Hash,
|
||||
HashStable,
|
||||
TypeFoldable,
|
||||
TypeVisitable
|
||||
)]
|
||||
pub enum NonDivergingIntrinsic<'tcx> {
|
||||
/// Denotes a call to the intrinsic function `assume`.
|
||||
///
|
||||
/// The operand must be a boolean. Optimizers may use the value of the boolean to backtrack its
|
||||
/// computation to infer information about other variables. So if the boolean came from a
|
||||
/// `x < y` operation, subsequent operations on `x` and `y` could elide various bound checks.
|
||||
/// If the argument is `false`, this operation is equivalent to `TerminatorKind::Unreachable`.
|
||||
Assume(Operand<'tcx>),
|
||||
|
||||
/// Denotes a call to the intrinsic function `copy_nonoverlapping`.
|
||||
///
|
||||
/// First, all three operands are evaluated. `src` and `dest` must each be a reference, pointer,
|
||||
@@ -340,10 +368,18 @@ pub enum StatementKind<'tcx> {
|
||||
///
|
||||
/// **Needs clarification**: Is this typed or not, ie is there a typed load and store involved?
|
||||
/// I vaguely remember Ralf saying somewhere that he thought it should not be.
|
||||
CopyNonOverlapping(Box<CopyNonOverlapping<'tcx>>),
|
||||
CopyNonOverlapping(CopyNonOverlapping<'tcx>),
|
||||
}
|
||||
|
||||
/// No-op. Useful for deleting instructions without affecting statement indices.
|
||||
Nop,
|
||||
impl std::fmt::Display for NonDivergingIntrinsic<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Assume(op) => write!(f, "assume({op:?})"),
|
||||
Self::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
|
||||
write!(f, "copy_nonoverlapping(dst = {dst:?}, src = {src:?}, count = {count:?})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes what kind of retag is to be performed.
|
||||
|
||||
@@ -425,14 +425,15 @@ macro_rules! make_mir_visitor {
|
||||
location
|
||||
)
|
||||
}
|
||||
StatementKind::CopyNonOverlapping(box crate::mir::CopyNonOverlapping{
|
||||
src,
|
||||
dst,
|
||||
count,
|
||||
}) => {
|
||||
self.visit_operand(src, location);
|
||||
self.visit_operand(dst, location);
|
||||
self.visit_operand(count, location)
|
||||
StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => {
|
||||
match intrinsic {
|
||||
NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location),
|
||||
NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
|
||||
self.visit_operand(src, location);
|
||||
self.visit_operand(dst, location);
|
||||
self.visit_operand(count, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
StatementKind::Nop => {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user