Skip to content

Commit

Permalink
[IR] moving to IROperand system (eliminates all generics)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Nov 10, 2024
1 parent 43737e9 commit 6d52aaf
Show file tree
Hide file tree
Showing 38 changed files with 820 additions and 1,562 deletions.
2 changes: 1 addition & 1 deletion examples/helloworld.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
func.addBlock("entry");

let string = func.BuildAssign(&string);
func.BuildCall( &other, vec![string] );
func.BuildCall( &other, vec![IROperand::Var(string)] );

func.BuildRet( Type::Void );

Expand Down
4 changes: 2 additions & 2 deletions src/CodeGen/compilation/alloca.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::CodeGen::{MachineInstr, MachineMnemonic};
use crate::IR::{Block, TypeMetadata, Var, ir::Alloca};
use crate::IR::{Block, TypeMetadata, ir::Alloca};

use super::CompilationHelper;

impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_alloca(&mut self, node: &Alloca<Var, TypeMetadata>, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
pub fn compile_alloca(&mut self, node: &Alloca, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
let out = *self.vars.get(&node.inner1.name).unwrap();

if let Some(phi_loc) = self.phi_vars.get(&node.inner1.name) {
Expand Down
5 changes: 2 additions & 3 deletions src/CodeGen/compilation/br.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::prelude::{Block, Br, BrCond};
use crate::CodeGen::{MachineInstr, MachineMnemonic, MachineOperand};
use crate::IR::Var;

use super::CompilationHelper;

impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_br(&mut self, node: &Br<crate::IR::BlockId>, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
pub fn compile_br(&mut self, node: &Br, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
let block = node.inner1.name.to_owned();

let instr = MachineInstr::new(
Expand All @@ -17,7 +16,7 @@ impl CompilationHelper {
}

#[allow(missing_docs)]
pub fn compile_br_cond(&mut self, node: &BrCond<Var, crate::IR::BlockId, crate::IR::BlockId>, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
pub fn compile_br_cond(&mut self, node: &BrCond, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
// COMPILES TO:
// if node.inner1 == 0 {
// goto node.inner2;
Expand Down
153 changes: 91 additions & 62 deletions src/CodeGen/compilation/call.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::collections::HashMap;

use crate::{prelude::Call, CodeGen::{MachineMnemonic, MachineOperand, Reg}, Target::Arch, IR::{FuncId, TypeMetadata}};
use crate::IR::{Block, Var};
use crate::{prelude::{Call, IROperand}, CodeGen::{MachineMnemonic, MachineOperand, Reg}, Target::Arch, IR::TypeMetadata};
use crate::IR::Block;
use super::{CompilationHelper, VarLocation};
use crate::CodeGen::MachineInstr;

impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_call(&mut self, node: &Call<FuncId, Vec<Var>, Var>, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
pub fn compile_call(&mut self, node: &Call, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
let mut reg_args = 0;
let mut fp_reg_args = 0;

Expand Down Expand Up @@ -46,71 +46,100 @@ impl CompilationHelper {
let args = self.call.args(Arch::X86_64, TypeMetadata::i64);
let fp_args = self.call.args(Arch::X86_64, TypeMetadata::f64);

for arg in &node.inner2 {
let src = self.vars.get(&arg.name).expect(&format!("expected valid variable: {}", arg.name));

let arg_reg = if TypeMetadata::f32 == arg.ty || TypeMetadata::f64 == arg.ty {
fp_args.get(fp_reg_args)
} else {
args.get(reg_args)
};

let mut arg_reg = arg_reg.cloned();

if let Some(reg) = arg_reg {
arg_reg = Some(match reg {
Reg::x64(x64) => Reg::x64(x64.sub_ty(arg.ty)),
Reg::wasm(i, t) => Reg::wasm(i, t),
})
}

if let Some(reg) = arg_reg {
if !self.allocated_vars.contains(&arg.name) {
let mut instr = MachineInstr::new(MachineMnemonic::Move);
for arg in &node.args {
if let IROperand::Var(arg) = arg {
let src = self.vars.get(&arg.name).expect(&format!("expected valid variable: {}", arg.name));

let mut op = src.into();
let arg_reg = if TypeMetadata::f32 == arg.ty || TypeMetadata::f64 == arg.ty {
fp_args.get(fp_reg_args)
} else {
args.get(reg_args)
};

if let Some((save, _)) = saved.get(&arg.name) {
op = MachineOperand::Stack(save.0, save.1);
}
let mut arg_reg = arg_reg.cloned();

instr.set_out(MachineOperand::Reg(reg));
instr.add_operand(op);

instr.meta = arg.ty;

mc_sink.push( instr );
if let Some(reg) = arg_reg {
arg_reg = Some(match reg {
Reg::x64(x64) => Reg::x64(x64.sub_ty(arg.ty)),
Reg::wasm(i, t) => Reg::wasm(i, t),
})
}

if let Some(reg) = arg_reg {
if !self.allocated_vars.contains(&arg.name) {
let mut instr = MachineInstr::new(MachineMnemonic::Move);

let mut op = src.into();

if let Some((save, _)) = saved.get(&arg.name) {
op = MachineOperand::Stack(save.0, save.1);
}

instr.set_out(MachineOperand::Reg(reg));
instr.add_operand(op);

instr.meta = arg.ty;

mc_sink.push( instr );
} else {
let mut instr = MachineInstr::new(MachineMnemonic::AdrMove);

instr.set_out(MachineOperand::Reg(reg));
instr.add_operand(src.into());

instr.meta = arg.ty;

mc_sink.push( instr );
}
} else {
let mut instr = MachineInstr::new(MachineMnemonic::AdrMove);

instr.set_out(MachineOperand::Reg(reg));
instr.add_operand(src.into());

instr.meta = arg.ty;

mc_sink.push( instr );
if !self.allocated_vars.contains(&arg.name) {
let mut instr = MachineInstr::new(MachineMnemonic::Push);
instr.add_operand(src.into());
pushes.push(arg.ty);
mc_sink.push( instr );
} else {
let mut instr = MachineInstr::new(MachineMnemonic::AdrMove);

instr.set_out(MachineOperand::Reg(self.tmp_reg));
instr.add_operand(src.into());
mc_sink.push( instr );

let mut instr = MachineInstr::new(MachineMnemonic::Push);
instr.add_operand(MachineOperand::Reg(self.tmp_reg));
pushes.push(arg.ty);
mc_sink.push( instr );
}
}
} else {
if !self.allocated_vars.contains(&arg.name) {
let mut instr = MachineInstr::new(MachineMnemonic::Push);
instr.add_operand(src.into());
pushes.push(arg.ty);
mc_sink.push( instr );
} else {
let mut instr = MachineInstr::new(MachineMnemonic::AdrMove);

instr.set_out(MachineOperand::Reg(self.tmp_reg));
instr.add_operand(src.into());
mc_sink.push( instr );
let arg_reg = if arg.get_ty().float() {
fp_args.get(fp_reg_args)
} else {
args.get(reg_args)
};

let mut arg_reg = arg_reg.cloned();

if let Some(reg) = arg_reg {
arg_reg = Some(match reg {
Reg::x64(x64) => Reg::x64(x64.sub_ty(arg.get_ty())),
Reg::wasm(i, t) => Reg::wasm(i, t),
})
}

if let Some(reg) = arg_reg {
let mut instr = MachineInstr::new(MachineMnemonic::Move);
instr.set_out(MachineOperand::Reg(reg));
instr.add_operand(arg.into_mi(self));
mc_sink.push(instr);
} else {
let mut instr = MachineInstr::new(MachineMnemonic::Push);
instr.add_operand(MachineOperand::Reg(self.tmp_reg));
pushes.push(arg.ty);
instr.add_operand(arg.into_mi(self));
pushes.push(arg.get_ty());
mc_sink.push( instr );
}
}

if TypeMetadata::f32 == arg.ty || TypeMetadata::f64 == arg.ty {
if arg.get_ty().float() {
fp_reg_args += 1;
} else {
reg_args += 1;
Expand All @@ -122,7 +151,7 @@ impl CompilationHelper {
}

mc_sink.push(MachineInstr::new(
MachineMnemonic::Call(node.inner1.name.to_string())
MachineMnemonic::Call(node.func.name.to_string())
));

if !pushes.is_empty() {
Expand All @@ -147,21 +176,21 @@ impl CompilationHelper {

let mut instr = MachineInstr::new(MachineMnemonic::Move);

let loc = *self.vars.get(&node.inner3.name).unwrap();
let loc = *self.vars.get(&node.out.name).unwrap();

instr.add_operand(
MachineOperand::Reg(
self.call.return_reg(self.arch, node.inner1.ty.ret)
self.call.return_reg(self.arch, node.func.ty.ret)
)
);

instr.meta = node.inner1.ty.ret;
instr.meta = node.func.ty.ret;

instr.set_out(loc.into());

mc_sink.push(instr);

if let Some(phi_loc) = self.phi_vars.get(&node.inner1.name) {
if let Some(phi_loc) = self.phi_vars.get(&node.func.name) {
let mut instr = MachineInstr::new(MachineMnemonic::Move);
instr.set_out((*phi_loc).into());
instr.add_operand(loc.into());
Expand Down
16 changes: 7 additions & 9 deletions src/CodeGen/compilation/cast.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
use crate::prelude::Cast;
use crate::IR::{Block, TypeMetadata, Var};
use crate::IR::Block;
use super::CompilationHelper;
use crate::CodeGen::{MachineInstr, MachineMnemonic};

impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_cast(&mut self, node: &Cast<Var, TypeMetadata, Var>, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
let src1 = *self.vars.get(&node.inner1.name).expect("expected valid variable");

pub fn compile_cast(&mut self, node: &Cast, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
let out = *self.vars.get(&node.inner3.name).unwrap();

let op = {
if node.inner1.ty.float() || node.inner2.float() {
if node.inner1.get_ty().float() || node.inner2.float() {
MachineMnemonic::FCast
} else if node.inner1.ty.bitSize() < node.inner2.bitSize() {
} else if node.inner1.get_ty().bitSize() < node.inner2.bitSize() {
MachineMnemonic::Zext
} else if node.inner1.ty.bitSize() > node.inner2.bitSize(){
} else if node.inner1.get_ty().bitSize() > node.inner2.bitSize(){
MachineMnemonic::Downcast
} else {
return;
}
}(node.inner1.ty);
}(node.inner1.get_ty());

let mut instr = MachineInstr::new(op);

instr.add_operand(src1.into());
instr.add_operand(node.inner1.into_mi(self));
instr.set_out(out.into());

instr.meta = node.inner3.ty;
Expand Down
6 changes: 3 additions & 3 deletions src/CodeGen/compilation/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use super::CompilationHelper;
impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_cmp(&mut self, node: &Cmp, mc_sink: &mut Vec<MachineInstr>, _: &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 ls = node.ls.into_mi(self);
let rs = node.rs.into_mi(self);
let out = *self.vars.get(&node.out.name).unwrap();

let ls = ls.into();
Expand All @@ -21,7 +21,7 @@ impl CompilationHelper {

cmp.set_out(out);

cmp.meta = node.ls.ty;
cmp.meta = node.ls.get_ty();

mc_sink.push( cmp );

Expand Down
11 changes: 4 additions & 7 deletions src/CodeGen/compilation/load.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use crate::CodeGen::{MachineInstr, MachineMnemonic};
use crate::IR::{Block, TypeMetadata, Var, ir::Load};
use crate::IR::{Block, ir::Load};

use super::CompilationHelper;

impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_load(&mut self, node: &Load<Var, Var, TypeMetadata>, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
let ptr = *self.vars.get(&node.inner2.name).expect(&format!("expected valid variable {}", node.inner2.name));
let ptr = ptr.into();
pub fn compile_load(&mut self, node: &Load, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
let ptr = node.inner3.into_mi(self);

let out = *self.vars.get(&node.inner1.name).unwrap();
let out = out.into();
Expand All @@ -17,9 +16,7 @@ impl CompilationHelper {
instr.set_out( out );
instr.add_operand(ptr);

instr.meta = node.inner3;

instr.meta = node.inner3;
instr.meta = node.inner2;

mc_sink.push( instr );

Expand Down
Loading

0 comments on commit 6d52aaf

Please sign in to comment.