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:
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user