From 9f9670eebb8d2484447a24fdccd752b7b954311b Mon Sep 17 00:00:00 2001 From: Cr0a3 Date: Sun, 27 Oct 2024 10:54:31 +0100 Subject: [PATCH] [CODE GEN] adding type size hint --- src/CodeGen/compilation/assign.rs | 36 +++++++------------- src/CodeGen/compilation/br.rs | 6 +--- src/CodeGen/compilation/call.rs | 15 ++++----- src/CodeGen/compilation/cast.rs | 15 +++------ src/CodeGen/compilation/cmp.rs | 19 +++-------- src/CodeGen/compilation/load.rs | 12 ++----- src/CodeGen/compilation/math.rs | 55 +++++++++++++------------------ src/CodeGen/compilation/mod.rs | 2 +- src/CodeGen/compilation/store.rs | 18 +++------- src/CodeGen/instr.rs | 8 ++--- src/CodeGen/reg_alloc/mod.rs | 12 +++---- src/Target/wasm/lower.rs | 4 +-- src/Target/x64/asm/instr.rs | 2 +- src/Target/x64/lower.rs | 2 +- src/Target/x64/lower/downcast.rs | 2 +- 15 files changed, 73 insertions(+), 135 deletions(-) diff --git a/src/CodeGen/compilation/assign.rs b/src/CodeGen/compilation/assign.rs index 7bbc6300..41717ffc 100644 --- a/src/CodeGen/compilation/assign.rs +++ b/src/CodeGen/compilation/assign.rs @@ -1,19 +1,15 @@ use crate::prelude::Assign; use crate::IR::{Block, Const, Type, Var}; -use super::{CompilationHelper, VarLocation}; +use super::CompilationHelper; use crate::CodeGen::{MachineInstr, MachineMnemonic, MachineOperand}; impl CompilationHelper { #[allow(missing_docs)] pub fn compile_assign_var_type(&mut self, node: &Assign, mc_sink: &mut Vec, _: &Block, _: &mut crate::prelude::Module) { - let location = *self.vars.get(&node.inner1.name).unwrap(); - + let out = *self.vars.get(&node.inner1.name).unwrap(); let mut instr = MachineInstr::new(MachineMnemonic::Move); - match location { - VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.set_out( MachineOperand::Stack(stack) ), - } + instr.set_out(out.into()); instr.add_operand(MachineOperand::Imm(node.inner2.val())); @@ -24,7 +20,7 @@ impl CompilationHelper { if let Some(phi_loc) = self.alloc.phi_vars.get(&node.inner1.name) { let mut instr = MachineInstr::new(MachineMnemonic::Move); instr.set_out((*phi_loc).into()); - instr.add_operand(location.into()); + instr.add_operand(out.into()); mc_sink.push(instr); } @@ -34,20 +30,13 @@ impl CompilationHelper { #[allow(missing_docs)] pub fn compile_assign_var_var(&mut self, node: &Assign, mc_sink: &mut Vec, _: &Block, _: &mut crate::prelude::Module) { let src1 = *self.vars.get(&node.inner2.name).expect(&format!("{} has no variable location", node.inner2)); - - let location = *self.vars.get(&node.inner1.name).unwrap(); + let out = *self.vars.get(&node.inner1.name).unwrap(); let mut instr = MachineInstr::new(MachineMnemonic::Move); - match location { - VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.set_out( MachineOperand::Stack(stack) ), - } + instr.set_out(out.into()); - match src1 { - VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.add_operand( MachineOperand::Stack(stack) ), - } + instr.add_operand(src1.into()); instr.meta = node.inner1.ty; @@ -56,7 +45,7 @@ impl CompilationHelper { if let Some(phi_loc) = self.alloc.phi_vars.get(&node.inner1.name) { let mut instr = MachineInstr::new(MachineMnemonic::Move); instr.set_out((*phi_loc).into()); - instr.add_operand(location.into()); + instr.add_operand(out.into()); mc_sink.push(instr); } @@ -64,16 +53,13 @@ impl CompilationHelper { #[allow(missing_docs)] pub fn compile_assign_var_const(&mut self, node: &Assign, mc_sink: &mut Vec, _: &Block, _: &mut crate::prelude::Module) { - let location = *self.vars.get(&node.inner1.name).unwrap(); + let out = *self.vars.get(&node.inner1.name).unwrap(); let mut instr = MachineInstr::new( MachineMnemonic::AdressLoad(node.inner2.name.to_string()) ); - match location { - VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.set_out( MachineOperand::Stack(stack) ), - } + instr.set_out(out.into()); instr.meta = node.inner1.ty; // is a pointer but i just wrote it here @@ -83,7 +69,7 @@ impl CompilationHelper { if let Some(phi_loc) = self.alloc.phi_vars.get(&node.inner1.name) { let mut instr = MachineInstr::new(MachineMnemonic::Move); instr.set_out((*phi_loc).into()); - instr.add_operand(location.into()); + instr.add_operand(out.into()); mc_sink.push(instr); } } diff --git a/src/CodeGen/compilation/br.rs b/src/CodeGen/compilation/br.rs index 36020b4c..c0f686d8 100644 --- a/src/CodeGen/compilation/br.rs +++ b/src/CodeGen/compilation/br.rs @@ -29,11 +29,7 @@ impl CompilationHelper { let iffalse = node.inner3.name.to_owned(); let src = *self.vars.get(&node.inner1.name).expect("expected valid variable"); - - let src = match src { - super::VarLocation::Reg(reg) => MachineOperand::Reg(reg), - super::VarLocation::Mem(stack) => MachineOperand::Stack(stack), - }; + let src = src.into(); let mut cmp = MachineInstr::new( MachineMnemonic::BrCond(iftrue, iffalse) diff --git a/src/CodeGen/compilation/call.rs b/src/CodeGen/compilation/call.rs index 730cc28e..bdbb8cfe 100644 --- a/src/CodeGen/compilation/call.rs +++ b/src/CodeGen/compilation/call.rs @@ -26,18 +26,18 @@ impl CompilationHelper { let mut save = MachineInstr::new( MachineMnemonic::Move ); let off = match self.alloc.alloc_stack(typ) { - VarLocation::Mem(off) => off, + VarLocation::Mem(off, ty) => (off, ty), _ => unreachable!(), }; saved.insert(name.to_owned(), (off, loc)); - save.set_out(MachineOperand::Stack(off)); + save.set_out(MachineOperand::Stack(off.0, off.1)); save.add_operand(loc.into()); mc_sink.push(save); } }, - VarLocation::Mem(_) => {}, + VarLocation::Mem(_, _) => {}, } } @@ -67,7 +67,7 @@ impl CompilationHelper { let mut op = src.into(); if let Some((save, _)) = saved.get(&arg.name) { - op = MachineOperand::Stack(*save); + op = MachineOperand::Stack(save.0, save.1); } instr.set_out(MachineOperand::Reg(reg)); @@ -129,7 +129,7 @@ impl CompilationHelper { let mut restore = MachineInstr::new( MachineMnemonic::Move); restore.set_out(original.into()); - restore.add_operand(MachineOperand::Stack(stack)); + restore.add_operand(MachineOperand::Stack(stack.0, stack.1)); mc_sink.push( restore ); } @@ -153,10 +153,7 @@ impl CompilationHelper { instr.meta = node.inner1.ty.ret; - match loc { - VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.set_out( MachineOperand::Stack(stack) ), - } + instr.set_out(loc.into()); mc_sink.push(instr); diff --git a/src/CodeGen/compilation/cast.rs b/src/CodeGen/compilation/cast.rs index 79507a75..94fc7808 100644 --- a/src/CodeGen/compilation/cast.rs +++ b/src/CodeGen/compilation/cast.rs @@ -1,7 +1,7 @@ use crate::prelude::Cast; use crate::IR::{Block, TypeMetadata, Var}; -use super::{CompilationHelper, VarLocation}; -use crate::CodeGen::{MachineInstr, MachineMnemonic, MachineOperand}; +use super::CompilationHelper; +use crate::CodeGen::{MachineInstr, MachineMnemonic}; impl CompilationHelper { #[allow(missing_docs)] @@ -24,15 +24,8 @@ impl CompilationHelper { let mut instr = MachineInstr::new(op); - match src1 { - VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.add_operand( MachineOperand::Stack(stack) ), - } - - match out { - VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.add_operand( MachineOperand::Stack(stack) ), - } + instr.add_operand(src1.into()); + instr.set_out(out.into()); instr.meta = node.inner3.ty; diff --git a/src/CodeGen/compilation/cmp.rs b/src/CodeGen/compilation/cmp.rs index 10470d67..892750d1 100644 --- a/src/CodeGen/compilation/cmp.rs +++ b/src/CodeGen/compilation/cmp.rs @@ -1,4 +1,4 @@ -use crate::{prelude::Cmp, CodeGen::{MachineInstr, MachineMnemonic, MachineOperand}, IR::{Block, TypeMetadata}}; +use crate::{prelude::Cmp, CodeGen::{MachineInstr, MachineMnemonic}, IR::{Block, TypeMetadata}}; use super::CompilationHelper; @@ -7,21 +7,12 @@ impl CompilationHelper { pub fn compile_cmp(&mut self, node: &Cmp, mc_sink: &mut Vec, _: &Block, _: &mut crate::prelude::Module) { let ls = *self.vars.get(&node.ls.name).expect("expected valid variable"); let rs = *self.vars.get(&node.rs.name).expect("expected valid variable"); + let out = *self.vars.get(&node.out.name).unwrap(); - let ls = match ls { - super::VarLocation::Reg(reg) => MachineOperand::Reg(reg), - super::VarLocation::Mem(stack) => MachineOperand::Stack(stack), - }; + let ls = ls.into(); + let rs = rs.into(); - let rs = match rs { - super::VarLocation::Reg(reg) => MachineOperand::Reg(reg), - super::VarLocation::Mem(stack) => MachineOperand::Stack(stack), - }; - - let out = match *self.vars.get(&node.out.name).unwrap() { - super::VarLocation::Reg(reg) => MachineOperand::Reg(reg), - super::VarLocation::Mem(stack) => MachineOperand::Stack(stack), - }; + let out = out.into(); let mut cmp = MachineInstr::new(MachineMnemonic::Compare(node.mode) ); diff --git a/src/CodeGen/compilation/load.rs b/src/CodeGen/compilation/load.rs index c7debad1..a6532308 100644 --- a/src/CodeGen/compilation/load.rs +++ b/src/CodeGen/compilation/load.rs @@ -1,4 +1,4 @@ -use crate::CodeGen::{MachineInstr, MachineMnemonic, MachineOperand}; +use crate::CodeGen::{MachineInstr, MachineMnemonic}; use crate::IR::{Block, TypeMetadata, Var, ir::Load}; use super::CompilationHelper; @@ -7,16 +7,10 @@ impl CompilationHelper { #[allow(missing_docs)] pub fn compile_load(&mut self, node: &Load, mc_sink: &mut Vec, _: &Block, _: &mut crate::prelude::Module) { let ptr = *self.vars.get(&node.inner2.name).expect("expected valid variable"); - let ptr = match ptr { - super::VarLocation::Reg(reg) => MachineOperand::Reg(reg), - super::VarLocation::Mem(mem) => MachineOperand::Stack(mem), - }; + let ptr = ptr.into(); let out = *self.vars.get(&node.inner1.name).unwrap(); - let out = match out { - super::VarLocation::Reg(reg) => MachineOperand::Reg(reg), - super::VarLocation::Mem(mem) => MachineOperand::Stack(mem), - }; + let out = out.into(); let mut instr = MachineInstr::new(MachineMnemonic::Load); diff --git a/src/CodeGen/compilation/math.rs b/src/CodeGen/compilation/math.rs index 7ec3099f..a4e78d1f 100644 --- a/src/CodeGen/compilation/math.rs +++ b/src/CodeGen/compilation/math.rs @@ -1,7 +1,7 @@ use crate::CodeGen::instr::{MachineMnemonic, MachineOperand, MachineInstr}; use crate::IR::ir::*; use crate::prelude::{Var, Block, Type}; -use super::{CompilationHelper, VarLocation}; +use super::CompilationHelper; macro_rules! MathVarVar { ($func:ident, $node:ident, $mnemonic:expr) => { @@ -15,21 +15,10 @@ macro_rules! MathVarVar { let mut instr = MachineInstr::new($mnemonic); - match src1 { - VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.add_operand( MachineOperand::Stack(stack) ), - } - - match src2 { - VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.add_operand( MachineOperand::Stack(stack) ), - } + instr.add_operand(src1.into()); + instr.add_operand(src2.into()); + instr.set_out(out.into()); - match out { - VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.set_out( MachineOperand::Stack(stack) ), - } - instr.meta = node.inner3.ty; mc_sink.push(instr); @@ -67,22 +56,21 @@ macro_rules! MathVarType { let mut instr = MachineInstr::new($mnemonic); - match src1 { - VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.add_operand( MachineOperand::Stack(stack) ), - } - + + instr.add_operand(src1.into()); instr.add_operand(MachineOperand::Imm(node.inner2.val())); - - match out { - VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.set_out( MachineOperand::Stack(stack) ), - } - + instr.set_out(out.into()); instr.meta = node.inner3.ty; mc_sink.push(instr); + + if let Some(phi_loc) = self.alloc.phi_vars.get(&node.inner3.name) { + let mut instr = MachineInstr::new(MachineMnemonic::Move); + instr.set_out((*phi_loc).into()); + instr.add_operand(out.into()); + mc_sink.push(instr); + } } } }; @@ -109,17 +97,20 @@ macro_rules! MathTypeType { let mut instr = MachineInstr::new($mnemonic); instr.add_operand(MachineOperand::Imm(node.inner1.val())); - instr.add_operand(MachineOperand::Imm(node.inner2.val())); - - match out { - VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)), - VarLocation::Mem(stack) => instr.set_out( MachineOperand::Stack(stack) ), - } + + instr.set_out(out.into()); instr.meta = node.inner3.ty; mc_sink.push(instr); + + if let Some(phi_loc) = self.alloc.phi_vars.get(&node.inner3.name) { + let mut instr = MachineInstr::new(MachineMnemonic::Move); + instr.set_out((*phi_loc).into()); + instr.add_operand(out.into()); + mc_sink.push(instr); + } } } }; diff --git a/src/CodeGen/compilation/mod.rs b/src/CodeGen/compilation/mod.rs index 8f79361a..f2feba2a 100644 --- a/src/CodeGen/compilation/mod.rs +++ b/src/CodeGen/compilation/mod.rs @@ -108,5 +108,5 @@ impl CompilationHelper { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum VarLocation { Reg(Reg), - Mem(i64), + Mem(i64, TypeMetadata), } \ No newline at end of file diff --git a/src/CodeGen/compilation/store.rs b/src/CodeGen/compilation/store.rs index fb5fd2d0..4138c3fc 100644 --- a/src/CodeGen/compilation/store.rs +++ b/src/CodeGen/compilation/store.rs @@ -1,6 +1,5 @@ use crate::prelude::{Store, Var, Type, Block}; use crate::CodeGen::{MachineInstr, MachineMnemonic, MachineOperand}; -use crate::IR::TypeMetadata; use super::CompilationHelper; @@ -8,16 +7,10 @@ impl CompilationHelper { #[allow(missing_docs)] pub fn compile_store(&mut self, node: &Store, mc_sink: &mut Vec, _: &Block, _: &mut crate::prelude::Module) { let in_var = self.vars.get(&node.inner2.name).expect("expected valid variable"); - let in_var = match in_var { - super::VarLocation::Reg(reg) => MachineOperand::Reg(*reg), - super::VarLocation::Mem(mem) => MachineOperand::Stack(*mem), - }; + let in_var = (*in_var).into(); let ptr = self.vars.get(&node.inner1.name).expect("expected valid variable"); - let ptr = match ptr { - super::VarLocation::Reg(reg) => MachineOperand::Reg(*reg), - super::VarLocation::Mem(mem) => MachineOperand::Stack(*mem), - }; + let ptr = (*ptr).into(); let mut instr = MachineInstr::new(MachineMnemonic::Store); @@ -32,17 +25,14 @@ impl CompilationHelper { #[allow(missing_docs)] pub fn compile_store_ty(&mut self, node: &Store, mc_sink: &mut Vec, _: &Block, _: &mut crate::prelude::Module) { let ptr = self.vars.get(&node.inner1.name).expect("expected valid variable"); - let ptr = match ptr { - super::VarLocation::Reg(reg) => MachineOperand::Reg(*reg), - super::VarLocation::Mem(mem) => MachineOperand::Stack(*mem), - }; + let ptr = (*ptr).into(); let mut instr = MachineInstr::new(MachineMnemonic::Store); instr.set_out( ptr ); instr.add_operand(MachineOperand::Imm(node.inner2.val())); - instr.meta = TypeMetadata::ptr; + instr.meta = node.inner2.into(); mc_sink.push( instr ); } diff --git a/src/CodeGen/instr.rs b/src/CodeGen/instr.rs index 7e26c69d..8cb1418b 100644 --- a/src/CodeGen/instr.rs +++ b/src/CodeGen/instr.rs @@ -156,7 +156,7 @@ pub enum MachineOperand { /// a register Reg(Reg), /// stack offset - Stack(i64), + Stack(i64, TypeMetadata), } impl PartialEq for MachineOperand { @@ -164,7 +164,7 @@ impl PartialEq for MachineOperand { match (self, other) { (Self::Imm(l0), Self::Imm(r0)) => l0 == r0, (Self::Reg(l0), Self::Reg(r0)) => l0 == r0, - (Self::Stack(l0), Self::Stack(r0)) => l0 == r0, + (Self::Stack(l0, l1), Self::Stack(r0, r1)) => l0 == r0 && l1 == r1, _ => false, } } @@ -183,7 +183,7 @@ impl Display for MachineOperand { write!(f, "{}", match self { MachineOperand::Imm(imm) => format!("{:#x?}", imm), MachineOperand::Reg(reg) => format!("{:?}", reg), - MachineOperand::Stack(off) => format!("sp - {:#x?}", off), + MachineOperand::Stack(off, size) => format!("{size} sp - {:#x?}", off), }) } } @@ -192,7 +192,7 @@ impl From for MachineOperand { fn from(location: VarLocation) -> Self { match location { VarLocation::Reg(reg) => MachineOperand::Reg(reg), - VarLocation::Mem(mem) => MachineOperand::Stack(mem), + VarLocation::Mem(mem, size) => MachineOperand::Stack(mem, size), } } } diff --git a/src/CodeGen/reg_alloc/mod.rs b/src/CodeGen/reg_alloc/mod.rs index 86fe45af..9a5dc7c7 100644 --- a/src/CodeGen/reg_alloc/mod.rs +++ b/src/CodeGen/reg_alloc/mod.rs @@ -313,17 +313,17 @@ impl RegAlloc { } } - pub(crate) fn alloc_stack(&mut self, _: TypeMetadata) -> VarLocation { + pub(crate) fn alloc_stack(&mut self, ty: TypeMetadata) -> VarLocation { if self.just_vars { if let Some(var) = self.jvars.pop() { - return VarLocation::Mem(var as i64); + return VarLocation::Mem(var as i64, ty); } else { self.curr_index += 1; - return VarLocation::Mem((self.curr_index - 1) as i64); + return VarLocation::Mem((self.curr_index - 1) as i64, ty); } } - let ret = VarLocation::Mem(self.stack_off); + let ret = VarLocation::Mem(self.stack_off, ty); self.stack_off += self.call.align(self.arch); @@ -355,7 +355,7 @@ impl RegAlloc { Reg::wasm(num, _) => num, _ => panic!("expected wasm register") }, - VarLocation::Mem(_) => panic!("jvars only work with registers"), + VarLocation::Mem(_, _) => panic!("jvars only work with registers"), }); } @@ -367,7 +367,7 @@ impl RegAlloc { self.free_registers.push(self.arch, reg); } }, - VarLocation::Mem(_) => { + VarLocation::Mem(_, _) => { // TODO: Add freeing abilitys }, } diff --git a/src/Target/wasm/lower.rs b/src/Target/wasm/lower.rs index 571a8292..ba7d61c0 100644 --- a/src/Target/wasm/lower.rs +++ b/src/Target/wasm/lower.rs @@ -103,7 +103,7 @@ pub(crate) fn wasm_construct_local_types(instrs: Vec) -> HashMap panic!("wasm functions expect wasm registers") }, - MachineOperand::Stack(_) => todo!("wasm type detection does not support memory references currently"), + MachineOperand::Stack(_, _) => todo!("wasm type detection does not support memory references currently"), } } } @@ -119,7 +119,7 @@ impl Into for MachineOperand { crate::CodeGen::Reg::wasm(var, _) => WasmOperand::Var(var), _ => panic!("the wasm backend expects that only wasm registers are used"), }, - MachineOperand::Stack(var) => WasmOperand::Var(var as i32), + MachineOperand::Stack(var, _) => WasmOperand::Var(var as i32), } } } diff --git a/src/Target/x64/asm/instr.rs b/src/Target/x64/asm/instr.rs index 5428380b..5a04d1ed 100644 --- a/src/Target/x64/asm/instr.rs +++ b/src/Target/x64/asm/instr.rs @@ -639,7 +639,7 @@ impl X64MCInstr { Instruction::with_branch(Code::Call_rel32_64, *op1 as u64)? } } else if let Some(Operand::LinkDestination(..)) = &self.op1 { - Instruction::with_branch(Code::Call_rel32_64, 0)? + Instruction::with_branch(Code::Call_rel32_64, 5)? } else { todo!("{}", self) } }, Mnemonic::Jmp => { diff --git a/src/Target/x64/lower.rs b/src/Target/x64/lower.rs index 2a384940..7071ce89 100644 --- a/src/Target/x64/lower.rs +++ b/src/Target/x64/lower.rs @@ -122,7 +122,7 @@ pub(crate) fn x64_lower(conv: CallConv, instrs: Vec) -> Vec for Operand { fn from(value: MachineOperand) -> Self { match value { - MachineOperand::Stack(stack) => x64_stack!(stack as u32), + MachineOperand::Stack(stack, _) => x64_stack!(stack as u32), MachineOperand::Imm(imm) => Operand::Imm(imm as i64), MachineOperand::Reg(reg) => match reg { crate::CodeGen::Reg::x64(x64_reg) => Operand::Reg(x64_reg), diff --git a/src/Target/x64/lower/downcast.rs b/src/Target/x64/lower/downcast.rs index 52919aeb..4ed6d8c5 100644 --- a/src/Target/x64/lower/downcast.rs +++ b/src/Target/x64/lower/downcast.rs @@ -11,7 +11,7 @@ pub(crate) fn x64_lower_downcast(sink: &mut Vec, instr: &MachineInst crate::CodeGen::Reg::x64(reg) => Operand::Reg(reg.sub_ty(instr.meta)), _ => panic!("x64 backend expects x64 registers") } - crate::CodeGen::MachineOperand::Stack(off) => Operand::Mem(X64Reg::Rbp - *off as u32), + crate::CodeGen::MachineOperand::Stack(off, _) => Operand::Mem(X64Reg::Rbp - *off as u32), }; sink.extend_from_slice(&[