Enum cranelift_codegen::ir::pcc::Fact

source ·
pub enum Fact {
    Range {
        bit_width: u16,
        min: u64,
        max: u64,
    },
    DynamicRange {
        bit_width: u16,
        min: Expr,
        max: Expr,
    },
    Mem {
        ty: MemoryType,
        min_offset: u64,
        max_offset: u64,
        nullable: bool,
    },
    DynamicMem {
        ty: MemoryType,
        min: Expr,
        max: Expr,
        nullable: bool,
    },
    Def {
        value: Value,
    },
    Compare {
        kind: IntCC,
        lhs: Expr,
        rhs: Expr,
    },
    Conflict,
}
Expand description

A fact on a value.

Variants§

§

Range

A bitslice of a value (up to a bitwidth) is within the given integer range.

The slicing behavior is needed because this fact can describe both an SSA Value, whose entire value is well-defined, and a VReg in VCode, whose bits beyond the type stored in that register are don’t-care (undefined).

Fields

§bit_width: u16

The bitwidth of bits we care about, from the LSB upward.

§min: u64

The minimum value that the bitslice can take (inclusive). The range is unsigned: the specified bits of the actual value will be greater than or equal to this value, as evaluated by an unsigned integer comparison.

§max: u64

The maximum value that the bitslice can take (inclusive). The range is unsigned: the specified bits of the actual value will be less than or equal to this value, as evaluated by an unsigned integer comparison.

§

DynamicRange

A value bounded by a global value.

The range is in (min_GV + min_offset)..(max_GV + max_offset), inclusive on the lower and upper bound.

Fields

§bit_width: u16

The bitwidth of bits we care about, from the LSB upward.

§min: Expr

The lower bound, inclusive.

§max: Expr

The upper bound, inclusive.

§

Mem

A pointer to a memory type.

Fields

§ty: MemoryType

The memory type.

§min_offset: u64

The minimum offset into the memory type, inclusive.

§max_offset: u64

The maximum offset into the memory type, inclusive.

§nullable: bool

This pointer can also be null.

§

DynamicMem

A pointer to a memory type, dynamically bounded. The pointer is within (GV_min+offset_min)..(GV_max+offset_max) (inclusive on both ends) in the memory type.

Fields

§ty: MemoryType

The memory type.

§min: Expr

The lower bound, inclusive.

§max: Expr

The upper bound, inclusive.

§nullable: bool

This pointer can also be null.

§

Def

A definition of a value to be used as a symbol in BaseExprs. There can only be one of these per value number.

Note that this differs from a DynamicRange specifying that some value in the program is the same as value. A def(v1) fact is propagated to machine code and serves as a source of truth: the value or location labeled with this fact defines what v1 is, and any dynamic_range(64, v1, v1)-labeled values elsewhere are claiming to be equal to this value.

This is necessary because we don’t propagate SSA value labels down to machine code otherwise; so when referring symbolically to addresses and expressions derived from addresses, we need to introduce the symbol first.

Fields

§value: Value

The SSA value this value defines.

§

Compare

A comparison result between two dynamic values with a comparison of a certain kind.

Fields

§kind: IntCC

The kind of comparison.

§lhs: Expr

The left-hand side of the comparison.

§rhs: Expr

The right-hand side of the comparison.

§

Conflict

A “conflict fact”: this fact results from merging two other facts, and it can never be satisfied – checking any value against this fact will fail.

Implementations§

source§

impl Fact

source

pub fn constant(bit_width: u16, value: u64) -> Self

Create a range fact that specifies a single known constant value.

source

pub fn dynamic_base_ptr(ty: MemoryType) -> Self

Create a dynamic range fact that points to the base of a dynamic memory.

source

pub fn value(bit_width: u16, value: Value) -> Self

Create a fact that specifies the value is exactly an SSA value.

Note that this differs from a def fact: it is not defining a symbol to have the value that this fact is attached to; rather it is claiming that this value is the same as whatever that symbol is. (In other words, the def should be elsewhere, and we are tying ourselves to it.)

source

pub fn value_offset(bit_width: u16, value: Value, offset: i64) -> Self

Create a fact that specifies the value is exactly an SSA value plus some offset.

source

pub fn global_value(bit_width: u16, gv: GlobalValue) -> Self

Create a fact that specifies the value is exactly the value of a GV.

source

pub fn global_value_offset(bit_width: u16, gv: GlobalValue, offset: i64) -> Self

Create a fact that specifies the value is exactly the value of a GV plus some offset.

source

pub const fn max_range_for_width(bit_width: u16) -> Self

Create a range fact that specifies the maximum range for a value of the given bit-width.

source

pub const fn max_range_for_width_extended( from_width: u16, to_width: u16, ) -> Self

Create a range fact that specifies the maximum range for a value of the given bit-width, zero-extended into a wider width.

source

pub fn infer_from_type(ty: Type) -> Option<&'static Self>

Try to infer a minimal fact for a value of the given IR type.

source

pub fn propagates(&self) -> bool

Does this fact “propagate” automatically, i.e., cause instructions that process it to infer their own output facts? Not all facts propagate automatically; otherwise, verification would be much slower.

source

pub fn as_const(&self, bits: u16) -> Option<u64>

Is this a constant value of the given bitwidth? Return it as a Some(value) if so.

source

pub fn as_symbol(&self) -> Option<&Expr>

Is this fact a single-value range with a symbolic Expr?

source

pub fn intersect(a: &Fact, b: &Fact) -> Fact

Merge two facts. We take the intersection: that is, we know both facts to be true, so we can intersect ranges. (This differs from the usual static analysis approach, where we are merging multiple possibilities into a generalized / widened fact. We want to narrow here.)

Trait Implementations§

source§

impl Clone for Fact

source§

fn clone(&self) -> Fact

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Fact

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Fact

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Hash for Fact

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Fact

source§

fn eq(&self, other: &Fact) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Eq for Fact

source§

impl StructuralPartialEq for Fact

Auto Trait Implementations§

§

impl Freeze for Fact

§

impl RefUnwindSafe for Fact

§

impl Send for Fact

§

impl Sync for Fact

§

impl Unpin for Fact

§

impl UnwindSafe for Fact

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.