Browse Source

ISLE: Build in maximum limit for multi constructor returns (#7526)

Allows users to avoid runaway rules that match too much stuff.

No statistically significant speed up to compilation on sightglass, but good to
have as a safeguard anyways.

Fixes #7500
pull/7538/head
Nick Fitzgerald 12 months ago
committed by GitHub
parent
commit
ebfe1ccd03
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      cranelift/codegen/src/opts.rs
  2. 2
      cranelift/isle/isle/isle_examples/link/multi_constructor_main.rs
  3. 2
      cranelift/isle/isle/isle_examples/link/multi_extractor_main.rs
  4. 26
      cranelift/isle/isle/src/codegen.rs

11
cranelift/codegen/src/opts.rs

@ -23,7 +23,16 @@ pub type Range = (usize, usize);
pub type ValueArray2 = [Value; 2];
pub type ValueArray3 = [Value; 3];
pub type ConstructorVec<T> = SmallVec<[T; 8]>;
const MAX_ISLE_RETURNS: usize = 8;
pub type ConstructorVec<T> = SmallVec<[T; MAX_ISLE_RETURNS]>;
impl<T: smallvec::Array> generated_code::Length for SmallVec<T> {
#[inline]
fn len(&self) -> usize {
SmallVec::len(self)
}
}
pub(crate) mod generated_code;
use generated_code::{ContextIter, IntoContextIter};

2
cranelift/isle/isle/isle_examples/link/multi_constructor_main.rs

@ -3,6 +3,8 @@ use multi_constructor::{ContextIter, IntoContextIter};
struct Context;
const MAX_ISLE_RETURNS: usize = 100;
#[derive(Default)]
struct It {
i: u32,

2
cranelift/isle/isle/isle_examples/link/multi_extractor_main.rs

@ -2,6 +2,8 @@ mod multi_extractor;
use multi_extractor::{ContextIter, IntoContextIter};
const MAX_ISLE_RETURNS: usize = 100;
#[derive(Clone)]
pub enum A {
B,

26
cranelift/isle/isle/src/codegen.rs

@ -236,6 +236,16 @@ pub trait IntoContextIter {{
fn into_context_iter(self) -> Self::IntoIter;
}}
pub trait Length {{
fn len(&self) -> usize;
}}
impl<T> Length for std::vec::Vec<T> {{
fn len(&self) -> usize {{
std::vec::Vec::len(self)
}}
}}
pub struct ContextIterWrapper<I, C> {{
iter: I,
_ctx: std::marker::PhantomData<C>,
@ -289,6 +299,11 @@ impl<T, E: Extend<T>, C> Extend<T> for ContextIterWrapper<E, C> {{
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {{
self.iter.extend(iter);
}}
}}
impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
fn len(&self) -> usize {{
self.iter.len()
}}
}}
"#,
)
@ -406,7 +421,7 @@ impl<T, E: Extend<T>, C> Extend<T> for ContextIterWrapper<E, C> {{
if let ReturnKind::Iterator = sig.ret_kind {
writeln!(
ctx.out,
"{} returns: &mut impl Extend<{}>,",
"{} returns: &mut (impl Extend<{}> + Length),",
&ctx.indent, ret
)?;
}
@ -635,7 +650,14 @@ impl<T, E: Extend<T>, C> Extend<T> for ContextIterWrapper<E, C> {{
match ret_kind {
ReturnKind::Plain => writeln!(ctx.out, ";")?,
ReturnKind::Option => writeln!(ctx.out, ");")?,
ReturnKind::Iterator => writeln!(ctx.out, "));")?,
ReturnKind::Iterator => {
writeln!(ctx.out, "));")?;
writeln!(
ctx.out,
"{}if returns.len() >= MAX_ISLE_RETURNS {{ return; }}",
ctx.indent
)?;
}
}
}
}

Loading…
Cancel
Save