Make SSA aggregates without needing an alloca

This commit is contained in:
Scott McMurray
2024-04-14 00:51:49 -07:00
parent 7448c24e02
commit c38f75c21f
5 changed files with 203 additions and 28 deletions

View File

@@ -14,6 +14,9 @@ use rustc_target::abi::{self, Abi, Align, Size};
use std::fmt;
use arrayvec::ArrayVec;
use either::Either;
/// The representation of a Rust value. The enum variant is in fact
/// uniquely determined by the value's type, but is kept as a
/// safety check.
@@ -58,6 +61,33 @@ pub enum OperandValue<V> {
ZeroSized,
}
impl<V> OperandValue<V> {
/// If this is ZeroSized/Immediate/Pair, return an array of the 0/1/2 values.
/// If this is Ref, return the place.
#[inline]
pub fn immediates_or_place(self) -> Either<ArrayVec<V, 2>, PlaceValue<V>> {
match self {
OperandValue::ZeroSized => Either::Left(ArrayVec::new()),
OperandValue::Immediate(a) => Either::Left(ArrayVec::from_iter([a])),
OperandValue::Pair(a, b) => Either::Left([a, b].into()),
OperandValue::Ref(p) => Either::Right(p),
}
}
/// Given an array of 0/1/2 immediate values, return ZeroSized/Immediate/Pair.
#[inline]
pub fn from_immediates(immediates: ArrayVec<V, 2>) -> Self {
let mut it = immediates.into_iter();
let Some(a) = it.next() else {
return OperandValue::ZeroSized;
};
let Some(b) = it.next() else {
return OperandValue::Immediate(a);
};
OperandValue::Pair(a, b)
}
}
/// An `OperandRef` is an "SSA" reference to a Rust value, along with
/// its type.
///