exit early from range checking

This commit is contained in:
Folkert 2022-05-21 18:28:11 +02:00
parent e3b6a38394
commit b46721e43b
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
2 changed files with 80 additions and 37 deletions

View file

@ -267,47 +267,53 @@ pub trait TypedNumericBound {
fn bounded_range(&self) -> Vec<Variable>;
}
const fn int_width_to_variable(w: IntWidth) -> Variable {
match w {
IntWidth::U8 => Variable::U8,
IntWidth::U16 => Variable::U16,
IntWidth::U32 => Variable::U32,
IntWidth::U64 => Variable::U64,
IntWidth::U128 => Variable::U128,
IntWidth::I8 => Variable::I8,
IntWidth::I16 => Variable::I16,
IntWidth::I32 => Variable::I32,
IntWidth::I64 => Variable::I64,
IntWidth::I128 => Variable::I128,
IntWidth::Nat => Variable::NAT,
}
}
const NO_DEMAND_INT_VARIABLES: &[(IntWidth, Variable)] = &[
(IntWidth::I8, Variable::I8),
(IntWidth::U8, Variable::U8),
(IntWidth::I16, Variable::I16),
(IntWidth::U16, Variable::U16),
(IntWidth::I32, Variable::I32),
(IntWidth::U32, Variable::U32),
(IntWidth::I64, Variable::I64),
(IntWidth::Nat, Variable::NAT), // FIXME: Nat's order here depends on the platform!
(IntWidth::U64, Variable::U64),
(IntWidth::I128, Variable::I128),
(IntWidth::U128, Variable::U128),
];
const SIGNED_INT_VARIABLES: &[(IntWidth, Variable)] = &[
(IntWidth::I8, Variable::I8),
(IntWidth::I16, Variable::I16),
(IntWidth::I32, Variable::I32),
(IntWidth::I64, Variable::I64),
(IntWidth::I128, Variable::I128),
];
impl TypedNumericBound for IntBound {
fn bounded_range(&self) -> Vec<Variable> {
match self {
IntBound::None => vec![],
IntBound::Exact(w) => vec![match w {
IntWidth::U8 => Variable::U8,
IntWidth::U16 => Variable::U16,
IntWidth::U32 => Variable::U32,
IntWidth::U64 => Variable::U64,
IntWidth::U128 => Variable::U128,
IntWidth::I8 => Variable::I8,
IntWidth::I16 => Variable::I16,
IntWidth::I32 => Variable::I32,
IntWidth::I64 => Variable::I64,
IntWidth::I128 => Variable::I128,
IntWidth::Nat => Variable::NAT,
}],
IntBound::Exact(w) => vec![int_width_to_variable(*w)],
IntBound::AtLeast { sign, width } => {
let whole_range: &[(IntWidth, Variable)] = match sign {
SignDemand::NoDemand => {
&[
(IntWidth::I8, Variable::I8),
(IntWidth::U8, Variable::U8),
(IntWidth::I16, Variable::I16),
(IntWidth::U16, Variable::U16),
(IntWidth::I32, Variable::I32),
(IntWidth::U32, Variable::U32),
(IntWidth::I64, Variable::I64),
(IntWidth::Nat, Variable::NAT), // FIXME: Nat's order here depends on the platform!
(IntWidth::U64, Variable::U64),
(IntWidth::I128, Variable::I128),
(IntWidth::U128, Variable::U128),
]
}
SignDemand::Signed => &[
(IntWidth::I8, Variable::I8),
(IntWidth::I16, Variable::I16),
(IntWidth::I32, Variable::I32),
(IntWidth::I64, Variable::I64),
(IntWidth::I128, Variable::I128),
],
SignDemand::NoDemand => NO_DEMAND_INT_VARIABLES,
SignDemand::Signed => SIGNED_INT_VARIABLES,
};
whole_range
.iter()

View file

@ -454,9 +454,46 @@ fn check_valid_range(
range: VariableSubsSlice,
mode: Mode,
) -> Outcome {
let slice = subs.get_subs_slice(range).to_vec();
let slice = subs.get_subs_slice(range);
let content = subs.get_content_without_compacting(var);
let mut it = slice.iter().peekable();
macro_rules! is_in_range {
($var:expr) => {
if slice.contains(&$var) {
return Outcome::default();
}
};
}
if let Content::Alias(symbol, _, _, _) = content {
match *symbol {
Symbol::NUM_I8 => is_in_range!(Variable::I8),
Symbol::NUM_U8 => is_in_range!(Variable::U8),
Symbol::NUM_I16 => is_in_range!(Variable::I16),
Symbol::NUM_U16 => is_in_range!(Variable::U16),
Symbol::NUM_I32 => is_in_range!(Variable::I32),
Symbol::NUM_U32 => is_in_range!(Variable::U32),
Symbol::NUM_I64 => is_in_range!(Variable::I64),
Symbol::NUM_NAT => is_in_range!(Variable::NAT),
Symbol::NUM_U64 => is_in_range!(Variable::U64),
Symbol::NUM_I128 => is_in_range!(Variable::I128),
Symbol::NUM_U128 => is_in_range!(Variable::U128),
Symbol::NUM_DEC => is_in_range!(Variable::DEC),
Symbol::NUM_F32 => is_in_range!(Variable::F32),
Symbol::NUM_F64 => is_in_range!(Variable::F64),
Symbol::NUM_NUM | Symbol::NUM_INT | Symbol::NUM_FRAC => {
// these satisfy any range that they are given
return Outcome::default();
}
_ => {}
}
}
let vec = slice.to_vec();
let mut it = vec.iter().peekable();
while let Some(&possible_var) = it.next() {
let snapshot = subs.snapshot();
let old_pool = pool.clone();