moved crates in lib/ to src/, renamed crates, modified some files' text (#660)
moved crates in lib/ to src/, renamed crates, modified some files' text (#660)
This commit is contained in:
161
cranelift/codegen/src/ir/valueloc.rs
Normal file
161
cranelift/codegen/src/ir/valueloc.rs
Normal file
@@ -0,0 +1,161 @@
|
||||
//! Value locations.
|
||||
//!
|
||||
//! The register allocator assigns every SSA value to either a register or a stack slot. This
|
||||
//! assignment is represented by a `ValueLoc` object.
|
||||
|
||||
use crate::ir::StackSlot;
|
||||
use crate::isa::{RegInfo, RegUnit};
|
||||
use core::fmt;
|
||||
|
||||
/// Value location.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum ValueLoc {
|
||||
/// This value has not been assigned to a location yet.
|
||||
Unassigned,
|
||||
/// Value is assigned to a register.
|
||||
Reg(RegUnit),
|
||||
/// Value is assigned to a stack slot.
|
||||
Stack(StackSlot),
|
||||
}
|
||||
|
||||
impl Default for ValueLoc {
|
||||
fn default() -> Self {
|
||||
ValueLoc::Unassigned
|
||||
}
|
||||
}
|
||||
|
||||
impl ValueLoc {
|
||||
/// Is this an assigned location? (That is, not `Unassigned`).
|
||||
pub fn is_assigned(self) -> bool {
|
||||
match self {
|
||||
ValueLoc::Unassigned => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the register unit of this location, or panic.
|
||||
pub fn unwrap_reg(self) -> RegUnit {
|
||||
match self {
|
||||
ValueLoc::Reg(ru) => ru,
|
||||
_ => panic!("Expected register: {:?}", self),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the stack slot of this location, or panic.
|
||||
pub fn unwrap_stack(self) -> StackSlot {
|
||||
match self {
|
||||
ValueLoc::Stack(ss) => ss,
|
||||
_ => panic!("Expected stack slot: {:?}", self),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an object that can display this value location, using the register info from the
|
||||
/// target ISA.
|
||||
pub fn display<'a, R: Into<Option<&'a RegInfo>>>(self, regs: R) -> DisplayValueLoc<'a> {
|
||||
DisplayValueLoc(self, regs.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Displaying a `ValueLoc` correctly requires the associated `RegInfo` from the target ISA.
|
||||
/// Without the register info, register units are simply show as numbers.
|
||||
///
|
||||
/// The `DisplayValueLoc` type can display the contained `ValueLoc`.
|
||||
pub struct DisplayValueLoc<'a>(ValueLoc, Option<&'a RegInfo>);
|
||||
|
||||
impl<'a> fmt::Display for DisplayValueLoc<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {
|
||||
ValueLoc::Unassigned => write!(f, "-"),
|
||||
ValueLoc::Reg(ru) => match self.1 {
|
||||
Some(regs) => write!(f, "{}", regs.display_regunit(ru)),
|
||||
None => write!(f, "%{}", ru),
|
||||
},
|
||||
ValueLoc::Stack(ss) => write!(f, "{}", ss),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Function argument location.
|
||||
///
|
||||
/// The ABI specifies how arguments are passed to a function, and where return values appear after
|
||||
/// the call. Just like a `ValueLoc`, function arguments can be passed in registers or on the
|
||||
/// stack.
|
||||
///
|
||||
/// Function arguments on the stack are accessed differently for the incoming arguments to the
|
||||
/// current function and the outgoing arguments to a called external function. For this reason,
|
||||
/// the location of stack arguments is described as an offset into the array of function arguments
|
||||
/// on the stack.
|
||||
///
|
||||
/// An `ArgumentLoc` can be translated to a `ValueLoc` only when we know if we're talking about an
|
||||
/// incoming argument or an outgoing argument.
|
||||
///
|
||||
/// - For stack arguments, different `StackSlot` entities are used to represent incoming and
|
||||
/// outgoing arguments.
|
||||
/// - For register arguments, there is usually no difference, but if we ever add support for a
|
||||
/// register-window ISA like SPARC, register arguments would also need to be translated.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum ArgumentLoc {
|
||||
/// This argument has not been assigned to a location yet.
|
||||
Unassigned,
|
||||
/// Argument is passed in a register.
|
||||
Reg(RegUnit),
|
||||
/// Argument is passed on the stack, at the given byte offset into the argument array.
|
||||
Stack(i32),
|
||||
}
|
||||
|
||||
impl Default for ArgumentLoc {
|
||||
fn default() -> Self {
|
||||
ArgumentLoc::Unassigned
|
||||
}
|
||||
}
|
||||
|
||||
impl ArgumentLoc {
|
||||
/// Is this an assigned location? (That is, not `Unassigned`).
|
||||
pub fn is_assigned(self) -> bool {
|
||||
match self {
|
||||
ArgumentLoc::Unassigned => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this a register location?
|
||||
pub fn is_reg(self) -> bool {
|
||||
match self {
|
||||
ArgumentLoc::Reg(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this a stack location?
|
||||
pub fn is_stack(self) -> bool {
|
||||
match self {
|
||||
ArgumentLoc::Stack(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an object that can display this argument location, using the register info from the
|
||||
/// target ISA.
|
||||
pub fn display<'a, R: Into<Option<&'a RegInfo>>>(self, regs: R) -> DisplayArgumentLoc<'a> {
|
||||
DisplayArgumentLoc(self, regs.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Displaying a `ArgumentLoc` correctly requires the associated `RegInfo` from the target ISA.
|
||||
/// Without the register info, register units are simply show as numbers.
|
||||
///
|
||||
/// The `DisplayArgumentLoc` type can display the contained `ArgumentLoc`.
|
||||
pub struct DisplayArgumentLoc<'a>(ArgumentLoc, Option<&'a RegInfo>);
|
||||
|
||||
impl<'a> fmt::Display for DisplayArgumentLoc<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.0 {
|
||||
ArgumentLoc::Unassigned => write!(f, "-"),
|
||||
ArgumentLoc::Reg(ru) => match self.1 {
|
||||
Some(regs) => write!(f, "{}", regs.display_regunit(ru)),
|
||||
None => write!(f, "%{}", ru),
|
||||
},
|
||||
ArgumentLoc::Stack(offset) => write!(f, "{}", offset),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user