Skip to content

Commit

Permalink
[IR] moving ret to use the new operand struct
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Nov 9, 2024
1 parent 46898cb commit 3906187
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 130 deletions.
10 changes: 10 additions & 0 deletions src/CodeGen/compilation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::prelude::Ir;
use crate::Target::{Arch, CallConv};
use crate::IR::{Function, TypeMetadata, Var};

use super::MachineOperand;
use super::{calling_convention::MachineCallingConvention, reg::Reg, MCInstr, MachineInstr};

mod call;
Expand Down Expand Up @@ -171,4 +172,13 @@ impl CompilationHelper {
pub(crate) enum VarLocation {
Reg(Reg),
Mem(i64, TypeMetadata),
}

impl crate::IR::ir::IROperand {
fn into_mi(&self, compiler: &mut CompilationHelper) -> MachineOperand {
match self {
crate::prelude::IROperand::Type(ty) => MachineOperand::Imm(ty.val()),
crate::prelude::IROperand::Var(var) => (*compiler.vars.get(&var.name).unwrap()).into(),
}
}
}
20 changes: 4 additions & 16 deletions src/CodeGen/compilation/ret.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
use crate::{prelude::Return, CodeGen::{MachineInstr, MachineMnemonic, MachineOperand}, IR::{Block, Type, Var}};
use crate::{prelude::{IROperand, Return}, CodeGen::{MachineInstr, MachineMnemonic, MachineOperand}, IR::{Block, Type, Var}};

use super::CompilationHelper;

impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_ret_ty(&mut self, node: &Return<Type>, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
pub fn compile_ret(&mut self, node: &Return<IROperand>, mc_sink: &mut Vec<MachineInstr>, _: &Block, _: &mut crate::prelude::Module) {
let mut instr = MachineInstr::new(MachineMnemonic::Return);
instr.add_operand(MachineOperand::Imm(node.inner1.val()));
instr.meta = node.inner1.into();
instr.add_operand(node.inner1.into_mi(self));
instr.meta = node.inner1.get_ty();

mc_sink.push( instr );
}

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

let mut instr = MachineInstr::new(MachineMnemonic::Return);
instr.add_operand(src.into());

instr.meta = node.inner1.ty;

mc_sink.push(instr);
}
}
9 changes: 2 additions & 7 deletions src/CodeGen/ir_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,9 @@ impl IrCodeGenHelper {
ir::Load<Var, Var, TypeMetadata>
);
ir_codegen_wrap!(
compile_ret_ty,
compile_ret,
"Loweres the ret node",
ir::Return<Type>
);
ir_codegen_wrap!(
compile_ret_var,
"Loweres the ret node",
ir::Return<Var>
ir::Return<ir::IROperand>
);
ir_codegen_wrap!(
compile_store,
Expand Down
57 changes: 57 additions & 0 deletions src/IR/nodes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,4 +331,61 @@ impl Replace<Box<dyn Ir>> for Box<dyn Ir> {
fn replace(&mut self, other: Box<dyn Ir>) {
*self = other
}
}

/// an operand for ir nodes
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum IROperand {
/// A type (like i64)
Type(Type),
/// A variable (like %.)
Var(Var),
}

impl IROperand {
#[inline]
/// Returns if the operand is a type const (like 5 - a constant number)
pub fn is_type(&self) -> bool {
matches!(self, IROperand::Type(_))
}

#[inline]
/// Returns if the operand is a var
pub fn is_var(&self) -> bool {
matches!(self, IROperand::Var(_))
}

#[inline]
/// Returns the type of the operand
pub fn get_ty(&self) -> TypeMetadata {
match self {
IROperand::Type(ty) => (*ty).into(),
IROperand::Var(var) => var.ty,
}
}
}

impl std::fmt::Display for IROperand {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", match self {
IROperand::Type(ty) => match ty {
Type::u8(i) => format!("{i}"),
Type::u16(i) => format!("{i}"),
Type::u32(i) => format!("{i}"),
Type::u64(i) => format!("{i}"),

Type::i8(i) => format!("{i}"),
Type::i16(i) => format!("{i}"),
Type::i32(i) => format!("{i}"),
Type::i64(i) => format!("{i}"),

Type::ptr(adr) => format!("{adr:#04x}"),
Type::Void => format!("0"),

Type::f32(i) => format!("{i}"),
Type::f64(i) => format!("{i}"),
}
IROperand::Var(var) => var.name.to_string(),
})
}
}
96 changes: 17 additions & 79 deletions src/IR/nodes/ret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,28 @@ use std::any::TypeId;

use super::*;

impl Ir for Return<Type> {
impl Ir for Return<IROperand> {
fn clone_box(&self) -> Box<dyn Ir> {
Box::new(self.clone())
}

fn dump(&self) -> String {
let metadata: TypeMetadata = self.inner1.into();
format!("ret {} {}", metadata, self.inner1.val())
let metadata: TypeMetadata = self.inner1.get_ty();

format!("ret {} {}", metadata, self.inner1)
}

fn dumpColored(&self, profile: ColorProfile) -> String {
let metadata: TypeMetadata = self.inner1.into();
let metadata: TypeMetadata = self.inner1.get_ty();
format!("{} {} {}",
profile.markup("ret", ColorClass::Instr),
profile.markup(&metadata.to_string(), ColorClass::Ty),
profile.markup(&self.inner1.val().to_string(), ColorClass::Var),
profile.markup(&self.inner1.to_string(), ColorClass::Var),
)
}

fn verify(&self, FuncTy: FunctionType) -> Result<(), VerifyError> {
let ty: TypeMetadata = self.inner1.into();
let ty: TypeMetadata = self.inner1.get_ty();

if ty != FuncTy.ret {
Err(VerifyError::RetTyNotFnTy(ty, FuncTy.ret))?
Expand All @@ -36,11 +37,11 @@ impl Ir for Return<Type> {
}

fn compile(&self, registry: &mut TargetBackendDescr, module: &mut crate::prelude::Module) {
registry.compile_ret_ty(&self, module)
registry.compile_ret(&self, module)
}

fn compile_dir(&self, compiler: &mut crate::CodeGen::IrCodeGenHelper, block: &crate::prelude::Block, module: &mut crate::prelude::Module) {
compiler.compile_ret_ty(&self, block, module)
compiler.compile_ret(&self, block, module)
}

fn inputs(&self) -> Vec<Var> {
Expand All @@ -56,79 +57,16 @@ impl Ir for Return<Type> {
}
}

impl EvalOptVisitor for Return<Type> {
fn maybe_inline(&self, _: &HashMap<String, Type>) -> Option<Box<dyn Ir>> {
None
}

fn eval(&self) -> Option<Box<dyn Ir>> {
None
}
}

impl Ir for Return<Var> {
fn clone_box(&self) -> Box<dyn Ir> {
Box::new(self.clone())
}

fn dump(&self) -> String {
format!("ret {} {}", self.inner1.ty, self.inner1.name)
}

fn dumpColored(&self, profile: ColorProfile) -> String {
format!("{} {} {}",
profile.markup("ret", ColorClass::Instr),
profile.markup(&self.inner1.ty.to_string(), ColorClass::Ty),
profile.markup(&self.inner1.name.to_string(), ColorClass::Var),
)
}

fn verify(&self, FuncTy: FunctionType) -> Result<(), VerifyError> {
let ty: TypeMetadata = self.inner1.ty.into();

if ty != FuncTy.ret {
Err(VerifyError::RetTyNotFnTy(ty, FuncTy.ret))?
impl EvalOptVisitor for Return<IROperand> {
fn maybe_inline(&self, const_values: &HashMap<String, Type>) -> Option<Box<dyn Ir>> {
if let IROperand::Var(var) = &self.inner1 {
if let Some(constant) = const_values.get(&var.name) {
return Some( Return::new(IROperand::Type(*constant)) );
}
}

Ok(())
}

fn as_any(&self) -> &dyn Any {
self
}

fn compile(&self, registry: &mut TargetBackendDescr, module: &mut crate::prelude::Module) {
registry.compile_ret_var(&self, module)
}

fn uses(&self, var: &Var) -> bool {
if *var == self.inner1 { true }
else { false }
}

fn compile_dir(&self, compiler: &mut crate::CodeGen::IrCodeGenHelper, block: &crate::prelude::Block, module: &mut crate::prelude::Module) {
compiler.compile_ret_var(&self, &block, module)
}

fn inputs(&self) -> Vec<Var> {
vec![self.inner1.to_owned()]
}

fn inputs_mut(&mut self) -> Vec<&mut Var> {
vec![&mut self.inner1]
}

fn output(&self) -> Option<Var> {
None
}
}

impl EvalOptVisitor for Return<Var> {
fn maybe_inline(&self, const_values: &HashMap<String, Type>) -> Option<Box<dyn Ir>> {
if let Some(constant) = const_values.get(&self.inner1.name) {
Some( Return::new(*constant) )
} else { None }
}

fn eval(&self) -> Option<Box<dyn Ir>> {
None
Expand Down Expand Up @@ -169,13 +107,13 @@ pub trait BuildReturn<T> {
impl BuildReturn<Type> for Function {
fn BuildRet(&mut self, val: Type) {
self.blocks.back_mut().expect("the IRBuilder needs to have an current block\nConsider creating one")
.push_ir(Return::new(val))
.push_ir(Return::new(IROperand::Type(val)))
}
}

impl BuildReturn<Var> for Function {
fn BuildRet(&mut self, var: Var) {
self.blocks.back_mut().expect("the IRBuilder needs to have an current block\nConsider creating one")
.push_ir(Return::new(var))
.push_ir(Return::new(IROperand::Var(var)))
}
}
26 changes: 15 additions & 11 deletions src/IR/parser/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::{BTreeMap, HashMap, VecDeque};
use std::path::PathBuf;

use crate::prelude::{Alloca, Cmp, CmpMode, DebugNode, GetElemPtr, Ir, Load, Neg, Phi, Select, Store, Switch};
use crate::prelude::{Alloca, Cmp, CmpMode, DebugNode, GetElemPtr, IROperand, Ir, Load, Neg, Phi, Select, Store, Switch};
use crate::Obj::Linkage;
use crate::IR::block::BlockId;
use crate::IR::{ir, Block, Const, FnTy, Type, TypeMetadata, Var};
Expand Down Expand Up @@ -511,25 +511,29 @@ impl IrParser {
let out_ty = self.parse_type()?;
self.input.pop_front();

let ret_op = self.parse_operand(out_ty)?;

self.input.pop_front();

Ok(ir::Return::new(ret_op))
}

fn parse_operand(&mut self, ty: TypeMetadata) -> Result<IROperand, IrError> {
let curr = self.current_token()?;

let out: Result<Box<dyn Ir>, IrError> = if let TokenType::Int(numeral) = &curr.typ {
Ok(ir::Return::new(Type::from_int(out_ty, *numeral)))
if let TokenType::Int(numeral) = &curr.typ {
Ok(IROperand::Type(Type::from_int(ty, *numeral)))
} else if let TokenType::Var(var) = &curr.typ {
Ok(ir::Return::new(Var {
Ok(IROperand::Var(Var {
name: var.to_owned(),
ty: out_ty,
ty: ty,
}))
} else {
Err(IrError::UndeterminedTokenSequence {
loc: curr.loc.clone(),
expected: "ints, vars - for valid return nodes".to_owned(),
expected: "intenger, variable names - for valid constant assignments".to_owned()
})
};

self.input.pop_front();

out
}
}

fn parse_const_assing(&mut self, var: String, ty: TypeMetadata) -> Result<Box<dyn Ir>, IrError> {
Expand Down
20 changes: 3 additions & 17 deletions src/Target/target_descr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ impl TargetBackendDescr {
ir_helper.helper.alloc.stack_off = helper.alloc.stack_off;
}

if let Some(node) = node.as_any().downcast_ref::<Return<Type>>() {
ir_helper.compile_ret_ty(node, &block, module);
if let Some(node) = node.as_any().downcast_ref::<Return<IROperand>>() {
ir_helper.compile_ret(node, &block, module);

if self.epilog {
let mut epilog_instrs = vec![];
Expand All @@ -143,19 +143,6 @@ impl TargetBackendDescr {
} else { unreachable!() }

}
} else if let Some(node) = node.as_any().downcast_ref::<Return<Var>>() {
ir_helper.compile_ret_var(node, &block, module);

if self.epilog {
let mut epilog_instrs = vec![];
helper.compile_epilog(&mut epilog_instrs);

if let Some(last) = ir_helper.compiled.last_mut() {
let backup = last.compiled.clone();
last.compiled = epilog_instrs;
last.compiled.extend_from_slice(&backup);
} else { unreachable!() }
}
} else {
node.compile_dir(&mut ir_helper, &block, module);
}
Expand Down Expand Up @@ -284,8 +271,7 @@ compile_func!(compile_rem_type_type, compile_rem_type_type, Rem<Type, Type, Var>
compile_func!(compile_shl_type_type, compile_shl_type_type, Shl<Type, Type, Var>);
compile_func!(compile_shr_type_type, compile_shr_type_type, Shr<Type, Type, Var>);

compile_func!(compile_ret_ty, compile_ret_ty, Return<Type>);
compile_func!(compile_ret_var, compile_ret_var, Return<Var>);
compile_func!(compile_ret, compile_ret, Return<IROperand>);

compile_func!(compile_cast_var, compile_cast, Cast<Var, TypeMetadata, Var>);

Expand Down

0 comments on commit 3906187

Please sign in to comment.