Skip to content

Commit

Permalink
Fix build for backend
Browse files Browse the repository at this point in the history
  • Loading branch information
julian-hartl committed Jul 7, 2024
1 parent bce65f5 commit cabd924
Show file tree
Hide file tree
Showing 16 changed files with 318 additions and 218 deletions.
1 change: 0 additions & 1 deletion ir/crates/back/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ daggy = "0.8.0"
log = "0.4.20"
natrix_middle = { path = "../middle" }
unicorn-engine = "2.0.1"
cranelift-entity = "0.105.2"
slotmap = "1.0.7"
anyhow = "1.0.81"

12 changes: 9 additions & 3 deletions ir/crates/back/src/codegen/machine/function/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,17 @@ impl<TM: TargetMachine> FunctionBuilder<TM> {
.find(|(_, mbb)| **mbb == mbb_id)
.unwrap()
.0;
debug!("Building machine basic block for basic block {}", bb);
debug!(
"Building machine basic block for basic block {}",
bb.display(&function.cfg)
);
let dag = sel_dag.get_bb_dag(bb);
dag.save_graphviz("out").unwrap();
dag.save_graphviz("out", &function.cfg).unwrap();
let mut node_list = Vec::with_capacity(dag.node_count());
debug!("Determining traversal order for basic block {}", bb);
debug!(
"Determining traversal order for basic block {}",
bb.display(&function.cfg)
);
let bfs = Bfs::new(dag.graph(), dag.term_node());
for n in bfs.iter(dag.graph()) {
node_list.push(n);
Expand Down
50 changes: 25 additions & 25 deletions ir/crates/back/src/codegen/machine/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ pub use cfg::{
BasicBlockId,
Cfg,
};
use cranelift_entity::{
entity_impl,
PrimaryMap,
};
use daggy::Walker;
use index_vec::IndexVec;
use iter_tools::Itertools;
use slotmap::{
new_key_type,
SlotMap,
};
use smallvec::{
smallvec,
SmallVec,
Expand All @@ -33,30 +33,29 @@ use crate::codegen::machine::{
PseudoInstr,
},
isa::PhysicalRegister,
reg::VRegInfo,
reg::VReg,
Instr,
InstrId,
MachInstr,
Register,
Size,
TargetMachine,
VReg,
VRegRef,
};

pub mod builder;
pub mod cfg;

#[derive(Copy, Clone, Eq, PartialEq)]
pub struct FunctionId(u32);

entity_impl!(FunctionId, "fun");
new_key_type! {
pub struct FunctionId;
}

#[derive(Debug, Clone)]
pub struct Function<TM: TargetMachine> {
pub name: String,
pub basic_blocks: IndexVec<BasicBlockId, BasicBlock<TM>>,
pub(crate) vregs: PrimaryMap<VReg, VRegInfo<TM>>,
pub(crate) params: SmallVec<[VReg; 2]>,
pub(crate) vregs: SlotMap<VRegRef, VReg<TM>>,
pub(crate) params: SmallVec<[VRegRef; 2]>,
pub(crate) return_ty_size: Size,
cfg: Option<Cfg>,
}
Expand All @@ -66,31 +65,32 @@ impl<TM: TargetMachine> Function<TM> {
Self {
name,
basic_blocks: IndexVec::default(),
vregs: PrimaryMap::new(),
vregs: SlotMap::with_key(),
cfg: None,
params: SmallVec::new(),
return_ty_size: Size::Byte,
}
}

pub fn alloc_vreg(&mut self, size: Size) -> VReg {
self.vregs.push(VRegInfo {
pub fn alloc_vreg(&mut self, size: Size, symbol: String) -> VRegRef {
self.vregs.insert(VReg {
size,
tied_to: None,
fixed: None,
symbol,
})
}

pub fn get_vreg(&self, vreg: VReg) -> &VRegInfo<TM> {
pub fn get_vreg(&self, vreg: VRegRef) -> &VReg<TM> {
&self.vregs[vreg]
}
pub fn tie_vreg(&mut self, vreg: VReg, to: VReg) {
debug!("Tying {vreg} to {to}");
pub fn tie_vreg(&mut self, vreg: VRegRef, to: VRegRef) {
// debug!("Tying {vreg} to {to}");
self.vregs[vreg].tied_to = Some(to);
}

pub fn fix_vreg(&mut self, vreg: VReg, to: TM::Reg) {
debug!("Fixing {vreg} to {}", to.name());
pub fn fix_vreg(&mut self, vreg: VRegRef, to: TM::Reg) {
// debug!("Fixing {vreg} to {}", to.name());
self.vregs[vreg].fixed = Some(to);
}

Expand Down Expand Up @@ -240,9 +240,9 @@ impl<TM: TargetMachine> Display for Function<TM> {
let bb = &self.basic_blocks[bb_id];
writeln!(f, "{bb_id}: ")?;
for (dest, operands) in &bb.phis {
write!(f, " {dest} = phi ")?;
write!(f, " {} = phi ", dest.display(self))?;
for (i, (reg, bb)) in operands.iter().enumerate() {
write!(f, "{reg}:{bb}")?;
write!(f, "{}:{bb}", reg.display(self))?;
if i < operands.len() - 1 {
write!(f, ", ")?;
}
Expand All @@ -252,13 +252,13 @@ impl<TM: TargetMachine> Display for Function<TM> {
for instr in &bb.instructions {
write!(f, " ")?;
if let Some(out) = instr.writes() {
write!(f, "{out} = ")?;
write!(f, "{} = ", out.display(self))?;
}
write!(f, "{}", instr.name())?;
let operands = instr.operands();
let operands_len = operands.len();
for (i, operand) in operands.into_iter().enumerate() {
write!(f, " {operand}")?;
write!(f, " {}", operand.display(self))?;
if i < operands_len - 1 {
write!(f, ",")?;
}
Expand All @@ -268,7 +268,7 @@ impl<TM: TargetMachine> Display for Function<TM> {
if !reads_impl.is_empty() {
write!(f, " {{implicit reads: ")?;
for (i, reg) in reads_impl.into_iter().enumerate() {
write!(f, "{reg}")?;
write!(f, "{}", reg.display(self))?;
if i < reads_impl_len - 1 {
write!(f, ", ")?;
}
Expand Down
24 changes: 19 additions & 5 deletions ir/crates/back/src/codegen/machine/instr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::codegen::{
machine::{
function::BasicBlockId,
isa::MachInstr as MInstr,
Function,
Register,
TargetMachine,
},
Expand Down Expand Up @@ -108,19 +109,32 @@ pub enum InstrOperand<TM: TargetMachine> {
Label(BasicBlockId),
}

impl<TM: TargetMachine> InstrOperand<TM> {
pub fn display<'func>(&self, func: &'func Function<TM>) -> InstrOperandDisplay<'func, '_, TM> {
InstrOperandDisplay {
operand: self,
func,
}
}
}
#[derive(Debug)]
pub enum InstrOperandMut<'a, TM: TargetMachine> {
Reg(&'a mut Register<TM>),
Imm(&'a mut Immediate),
Label(&'a mut BasicBlockId),
}

impl<TM: TargetMachine> Display for InstrOperand<TM> {
pub struct InstrOperandDisplay<'func, 'op, TM: TargetMachine> {
operand: &'op InstrOperand<TM>,
func: &'func Function<TM>,
}

impl<TM: TargetMachine> Display for InstrOperandDisplay<'_, '_, TM> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Reg(reg) => write!(f, "{}", reg),
Self::Imm(imm) => write!(f, "{}", imm),
Self::Label(label) => write!(f, "{}", label),
match self.operand {
InstrOperand::Reg(reg) => write!(f, "{}", reg.display(self.func)),
InstrOperand::Imm(imm) => write!(f, "{}", imm),
InstrOperand::Label(label) => write!(f, "{}", label),
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions ir/crates/back/src/codegen/machine/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::fmt::Debug;

pub use backend::Backend;
pub use cranelift_entity::EntityRef;
pub use function::{
Function,
FunctionId,
Expand All @@ -18,7 +17,7 @@ pub use module::Module;
use natrix_middle::ty::Type;
pub use reg::{
Register,
VReg,
VRegRef,
};

use crate::codegen::machine::{
Expand Down
2 changes: 1 addition & 1 deletion ir/crates/back/src/codegen/machine/module/asm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::ops::Range;

use cranelift_entity::SecondaryMap;
use slotmap::SecondaryMap;

use crate::codegen::machine::{
FunctionId,
Expand Down
2 changes: 1 addition & 1 deletion ir/crates/back/src/codegen/machine/module/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl<'module, TM: TargetMachine> Builder<'module, TM> {
pub fn build(mut self) -> Module<TM> {
for (_, function) in &mut self.module.functions {
let builder = FunctionBuilder::<TM>::new();
self.mtbb.functions.push(builder.build(function));
self.mtbb.functions.insert(builder.build(function));
}
self.mtbb
}
Expand Down
8 changes: 4 additions & 4 deletions ir/crates/back/src/codegen/machine/module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use asm::{
FunctionSymbolTableEntry,
};
pub use builder::Builder;
use cranelift_entity::PrimaryMap;
use slotmap::SlotMap;
use tracing::{
debug,
info,
Expand All @@ -28,20 +28,20 @@ mod builder;

#[derive(Debug, Clone)]
pub struct Module<TM: TargetMachine> {
pub(crate) functions: PrimaryMap<FunctionId, Function<TM>>,
pub(crate) functions: SlotMap<FunctionId, Function<TM>>,
}

impl<TM: TargetMachine> Default for Module<TM> {
fn default() -> Self {
Self {
functions: PrimaryMap::new(),
functions: SlotMap::with_key(),
}
}
}

impl<TM: TargetMachine> Module<TM> {
pub fn add_function(&mut self, function: Function<TM>) -> FunctionId {
self.functions.push(function)
self.functions.insert(function)
}

pub fn functions(&self) -> impl ExactSizeIterator<Item = (FunctionId, &Function<TM>)> {
Expand Down
53 changes: 35 additions & 18 deletions ir/crates/back/src/codegen/machine/reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fmt::{
Formatter,
};

use cranelift_entity::entity_impl;
use slotmap::new_key_type;

use crate::codegen::machine::{
function::Function,
Expand All @@ -14,25 +14,25 @@ use crate::codegen::machine::{

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Register<TM: TargetMachine> {
Virtual(VReg),
Virtual(VRegRef),
Physical(TM::Reg),
}

impl<TM: TargetMachine> From<VReg> for Register<TM> {
fn from(vreg: VReg) -> Self {
impl<TM: TargetMachine> From<VRegRef> for Register<TM> {
fn from(vreg: VRegRef) -> Self {
Self::Virtual(vreg)
}
}

impl<TM: TargetMachine> Register<TM> {
pub fn try_as_virtual(&self) -> Option<VReg> {
pub fn try_as_virtual(&self) -> Option<VRegRef> {
match self {
Register::Virtual(virt_reg) => Some(*virt_reg),
Register::Physical(_) => None,
}
}

pub fn try_as_virtual_mut(&mut self) -> Option<&mut VReg> {
pub fn try_as_virtual_mut(&mut self) -> Option<&mut VRegRef> {
match self {
Register::Virtual(virt_reg) => Some(virt_reg),
Register::Physical(_) => None,
Expand All @@ -52,35 +52,52 @@ impl<TM: TargetMachine> Register<TM> {
Register::Physical(phys_reg) => phys_reg.size(),
}
}

pub fn display<'func>(&self, func: &'func Function<TM>) -> RegisterDisplay<'func, TM> {
RegisterDisplay { func, reg: *self }
}
}

// impl<TM: TargetMachine> Copy for Register<TM> {}
pub struct RegisterDisplay<'func, TM: TargetMachine> {
func: &'func Function<TM>,
reg: Register<TM>,
}

impl<TM: TargetMachine> Display for Register<TM> {
impl<TM: TargetMachine> Display for RegisterDisplay<'_, TM> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Register::Virtual(virt_reg) => write!(f, "{}", virt_reg),
match self.reg {
Register::Virtual(virt_reg) => write!(f, "{}", self.func.vregs[virt_reg]),
Register::Physical(phys_reg) => write!(f, "${}", phys_reg.name()),
}
}
}

#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct VReg(u32);
new_key_type! {
pub struct VRegRef;
}

impl VReg {
impl VRegRef {
pub fn size<TM: TargetMachine>(self, func: &Function<TM>) -> Size {
func.get_vreg(self).size
}
}

entity_impl!(VReg, "v");
pub fn display<TM: TargetMachine>(self, func: &Function<TM>) -> String {
func.get_vreg(self).symbol.clone()
}
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct VRegInfo<TM: TargetMachine> {
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct VReg<TM: TargetMachine> {
pub size: Size,
/// If set, the vreg will be placed in the same location as tied_to
pub tied_to: Option<VReg>,
pub tied_to: Option<VRegRef>,
/// If set, the vreg is ensured to be placed in the same location as fixed
pub fixed: Option<TM::Reg>,
pub symbol: String,
}

impl<TM: TargetMachine> Display for VReg<TM> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.symbol)
}
}
Loading

0 comments on commit cabd924

Please sign in to comment.