ISLE: Resolve overlap in prelude.isle and x64/inst.isle (#4941)

Resolve overlap in the ISLE prelude and the x64 inst module by introducing new types that allow better sharing of extractor resuls, or falling back on priorities.
This commit is contained in:
Trevor Elliott
2022-09-28 10:54:39 -07:00
committed by GitHub
parent 2ba604e406
commit faf31f6216
5 changed files with 184 additions and 182 deletions

View File

@@ -32,12 +32,23 @@ pub type InstOutputBuilder = Cell<InstOutput>;
pub type BoxExternalName = Box<ExternalName>;
pub type Range = (usize, usize);
pub enum RangeView {
Empty,
NonEmpty { index: usize, rest: Range },
}
/// Helper macro to define methods in `prelude.isle` within `impl Context for
/// ...` for each backend. These methods are shared amongst all backends.
#[macro_export]
#[doc(hidden)]
macro_rules! isle_prelude_methods {
() => {
/// We don't have a way of making a `()` value in isle directly.
#[inline]
fn unit(&mut self) -> Unit {
()
}
#[inline]
fn same_value(&mut self, a: Value, b: Value) -> Option<Value> {
if a == b {
@@ -122,32 +133,18 @@ macro_rules! isle_prelude_methods {
value_regs.only_reg().unwrap()
}
#[inline]
fn is_valid_reg(&mut self, reg: Reg) -> bool {
use crate::machinst::valueregs::InvalidSentinel;
!reg.is_invalid_sentinel()
}
#[inline]
fn invalid_reg(&mut self) -> Reg {
use crate::machinst::valueregs::InvalidSentinel;
Reg::invalid_sentinel()
}
#[inline]
fn invalid_reg_etor(&mut self, reg: Reg) -> Option<()> {
use crate::machinst::valueregs::InvalidSentinel;
if reg.is_invalid_sentinel() {
Some(())
} else {
None
}
}
#[inline]
fn valid_reg(&mut self, reg: Reg) -> Option<()> {
use crate::machinst::valueregs::InvalidSentinel;
if !reg.is_invalid_sentinel() {
Some(())
} else {
None
}
}
#[inline]
fn mark_value_used(&mut self, val: Value) {
self.lower_ctx.increment_lowered_uses(val);
@@ -218,6 +215,11 @@ macro_rules! isle_prelude_methods {
Some(x & y)
}
#[inline]
fn u64_is_zero(&mut self, value: u64) -> bool {
0 == value
}
#[inline]
fn ty_bits(&mut self, ty: Type) -> Option<u8> {
use std::convert::TryInto;
@@ -910,27 +912,14 @@ macro_rules! isle_prelude_methods {
(start, end)
}
fn range_empty(&mut self, r: Range) -> Option<()> {
if r.0 >= r.1 {
Some(())
fn range_view(&mut self, (start, end): Range) -> RangeView {
if start >= end {
RangeView::Empty
} else {
None
}
}
fn range_singleton(&mut self, r: Range) -> Option<usize> {
if r.0 + 1 == r.1 {
Some(r.0)
} else {
None
}
}
fn range_unwrap(&mut self, r: Range) -> Option<(usize, Range)> {
if r.0 < r.1 {
Some((r.0, (r.0 + 1, r.1)))
} else {
None
RangeView::NonEmpty {
index: start,
rest: (start + 1, end),
}
}
}