Skip to content

Commit

Permalink
[PASSES] adding simple const evalutation pass
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Jul 11, 2024
1 parent 49d2f75 commit ddd7120
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 19 deletions.
11 changes: 9 additions & 2 deletions examples/simple.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::error::Error;
use Ygen::prelude::*;
use Ygen::{prelude::*, PassManager::Passes::PreComputeValue};

pub fn main() -> Result<(), Box<dyn Error>> {
let mut module = Module();
Expand All @@ -14,11 +14,18 @@ pub fn main() -> Result<(), Box<dyn Error>> {
builder.positionAtEnd(entry);

let val = builder.BuildAdd(ty.arg(0), ty.arg(1));
let add2 = builder.BuildAdd(Type::i32(5), Type::i32(5));
let ret = builder.BuildAdd(val, add2);

builder.BuildRet( val );
builder.BuildRet( ret );

module.verify().print();

let mut passes = PassManager::new();
passes.add( PreComputeValue() );

module.runPassMngr(passes);

println!("{}",
module.dumpColored()
);
Expand Down
8 changes: 8 additions & 0 deletions src/IR/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::Block;
use super::TypeMetadata;
use super::Var;
use super::VerifyError;
use crate::prelude::PassManager;
use crate::Support::Colorize;

/// Stores the function type
Expand Down Expand Up @@ -143,6 +144,13 @@ impl Function {

Ok(())
}

/// Runs the pass manager over all blocks
pub fn runPassMngr(&mut self, mngr: &PassManager) {
for block in &mut self.blocks {
mngr.run(block);
}
}
}

/// Creates a new function type
Expand Down
115 changes: 109 additions & 6 deletions src/IR/ir.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::fmt::Debug;
use std::{any::Any, fmt::Debug, hash::Hash};
use super::{FunctionType, IRBuilder, Type, TypeMetadata, Var, VerifyError};

macro_rules! IrTypeWith3 {
Expand Down Expand Up @@ -30,10 +30,10 @@ macro_rules! IrTypeWith3 {
}
};
}
/*macro_rules! IrTypeWith2 {
macro_rules! IrTypeWith2 {
($name:tt, $param1:tt, $param2:tt) => {
/// An Ir node
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Hash)]
pub struct $name<$param1, $param2> {
/// first inner value
pub inner1: $param1,
Expand All @@ -55,11 +55,11 @@ macro_rules! IrTypeWith3 {
}
}
};
}*/
}
macro_rules! IrTypeWith1 {
($name:tt, $param1:tt) => {
/// An Ir node
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Hash)]
pub(crate) struct $name<$param1> {
/// inner value
pub(crate) inner1: $param1,
Expand All @@ -81,6 +81,7 @@ macro_rules! IrTypeWith1 {
}

IrTypeWith1!(Return, T);
IrTypeWith2!(ConstAssign, T, U);
IrTypeWith3!(Add, T, U, Z);

use crate::Support::Colorize;
Expand All @@ -90,6 +91,10 @@ impl Ir for Return<Type> {
Box::new(self.clone())
}

fn name(&self) -> String {
"RetType".into()
}

fn dump(&self) -> String {
let metadata: TypeMetadata = self.inner1.into();
format!("ret {} {}", metadata, self.inner1.val())
Expand All @@ -109,13 +114,21 @@ impl Ir for Return<Type> {

Ok(())
}

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

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

fn name(&self) -> String {
"RetVar".into()
}

fn dump(&self) -> String {
format!("ret {} {}", self.inner1.ty, self.inner1.name)
}
Expand All @@ -133,13 +146,21 @@ impl Ir for Return<Var> {

Ok(())
}

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

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

fn name(&self) -> String {
"AddTypeType".into()
}

fn dump(&self) -> String {
format!("{} = add {} {}, {}", self.inner3.name, self.inner3.ty, self.inner1.val(), self.inner2.val())
}
Expand All @@ -155,15 +176,37 @@ impl Ir for Add<Type, Type, Var> {
}

fn verify(&self, _: FunctionType) -> Result<(), VerifyError> {
let op0Ty: TypeMetadata = self.inner1.into();
let op1Ty: TypeMetadata = self.inner2.into();
let op2Ty: TypeMetadata = self.inner3.ty.into();

if !(op0Ty == op1Ty && op1Ty == op2Ty) {
if op0Ty != op1Ty {
Err(VerifyError::Op0Op1TyNoMatch(op0Ty, op1Ty))?
} else if op1Ty != op2Ty {
Err(VerifyError::Op0Op1TyNoMatch(op1Ty, op2Ty))?
} if op0Ty != op2Ty {
Err(VerifyError::Op0Op1TyNoMatch(op0Ty, op2Ty))?
} else { todo!("unknown error variant (debug: ty0 {} ty1 {} ty2 {})", op0Ty, op1Ty, op2Ty) }
}

Ok(())
}

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

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

fn name(&self) -> String {
"AddVarVar".into()
}

fn dump(&self) -> String {
format!("{} = add {} {}, {}", self.inner3.name, self.inner3.ty, self.inner1.name, self.inner2.name)
}
Expand Down Expand Up @@ -195,6 +238,48 @@ impl Ir for Add<Var, Var, Var> {

Ok(())
}

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

impl Ir for ConstAssign<Var, Type> {
fn dump(&self) -> String {
let meta: TypeMetadata = self.inner2.into();
format!("{} = {} {}", self.inner1.name, meta, self.inner2.val())
}

fn dumpColored(&self) -> String {
let meta: TypeMetadata = self.inner2.into();
format!("{} = {} {}",
self.inner1.name.magenta(),
meta.to_string().cyan(),
self.inner2.val().to_string().blue()
)
}

fn name(&self) -> String {
"AssignVarType".into()
}

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

fn verify(&self, _: FunctionType) -> Result<(), VerifyError> {
let op0Ty = self.inner1.ty;
let op1Ty = self.inner2.into();
if op0Ty != op1Ty {
Err(VerifyError::Op0Op1TyNoMatch(op0Ty, op1Ty))?
}

Ok(())
}

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

/// Trait for the return instruction
Expand Down Expand Up @@ -258,12 +343,18 @@ impl BuildAdd<Var, Var> for IRBuilder<'_> {
}

/// The ir trait
pub(crate) trait Ir: Debug {
pub(crate) trait Ir: Debug + Any {
/// Returns the ir node as his textual representation
fn dump(&self) -> String;
/// Returns the ir node as his textual representation with colors
fn dumpColored(&self) -> String;

/// Returns the name of the ir expr
fn name(&self) -> String;

/// Turns the ir node to an any
fn as_any(&self) -> &dyn Any;

fn verify(&self, FuncTy: FunctionType) -> Result<(), VerifyError>;

/// Clones the node into a box of `Box<dyn Ir>`
Expand All @@ -275,3 +366,15 @@ impl Clone for Box<dyn Ir> {
self.clone_box()
}
}

/// Used for sus workaround to replace current ir node
pub trait Replace<T> {
/// Replaces current ir node
fn replace(&mut self, other: T);
}

impl Replace<Box<dyn Ir>> for Box<dyn Ir> {
fn replace(&mut self, other: Box<dyn Ir>) {
*self = other
}
}
11 changes: 10 additions & 1 deletion src/IR/module.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::PassManager;

use super::{func::FunctionType, Function, VerifyError};
use std::collections::HashMap;

Expand Down Expand Up @@ -61,7 +63,7 @@ impl Module {
string
}

/// Verifys if every function is correct:
/// Checks if every function is correct:
/// * Checks if the return type is the actual specified return type of the function
/// * Checks all ir nodes
pub fn verify(&self) -> Result<(), VerifyError> {
Expand All @@ -71,6 +73,13 @@ impl Module {

Ok(())
}

/// Runs the pass manager over all functions
pub fn runPassMngr(&mut self, mngr: PassManager::PassManager) {
for (_, func) in &mut self.funcs {
func.runPassMngr(&mngr)
}
}
}

/// Creates a new module
Expand Down
4 changes: 2 additions & 2 deletions src/IR/typ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fmt::Display;
/// Stores a type and a value of that type
///
/// If you want an empty Type consider using `TypeMetadata`
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[allow(non_camel_case_types)]
pub enum Type {
/// Just an u16 with a value
Expand All @@ -25,7 +25,7 @@ pub enum Type {
}

/// Stores type metadata (just the type without data)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
pub enum TypeMetadata {
/// u16
Expand Down
2 changes: 1 addition & 1 deletion src/IR/var.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{Block, TypeMetadata};

/// A variable
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Var {
pub(crate) name: String,
pub(crate) ty: TypeMetadata,
Expand Down
33 changes: 33 additions & 0 deletions src/PassManager/Passes/MathEval.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use crate::{prelude::*, PassManager::Pass};

/// ## Pass InlineConstValue <br>
/// Inlines constant values
pub struct PreComputeValue {}

/// Creates a new PreComputeValue pass which is heap allocated
pub fn PreComputeValue() -> Box<PreComputeValue> {
Box::from( PreComputeValue {} )
}

impl Pass for PreComputeValue {
fn run(&self, block: &mut crate::prelude::Block) {
for node in block.nodes.iter_mut() {
if &node.name() == "AddTypeType" {
let any = node.as_any();
let add_node = any.downcast_ref::<Add<Type, Type, Var>>().unwrap().clone();
let res = add_node.inner1.val() + add_node.inner2.val();
node.replace(ConstAssign::new(add_node.inner3.clone(), {
match add_node.inner3.ty {
TypeMetadata::u16 => Type::u16(res as u16),
TypeMetadata::u32 => Type::u32(res as u32),
TypeMetadata::u64 => Type::u64(res as u64),
TypeMetadata::i16 => Type::i16(res as i16),
TypeMetadata::i32 => Type::i32(res as i32),
TypeMetadata::i64 => Type::i64(res as i64),
TypeMetadata::Void => Type::Void,
}
}))
}
}
}
}
Loading

0 comments on commit ddd7120

Please sign in to comment.