diff --git a/src/IR/block.rs b/src/IR/block.rs index 86859a8d..fc4635f6 100644 --- a/src/IR/block.rs +++ b/src/IR/block.rs @@ -1,6 +1,6 @@ use crate::Support::{ColorProfile, Colorize}; -use super::{ir::Ir, Function, VerifyError}; +use super::{ir::Ir, Function, Var, VerifyError}; /// A basic block: stores ir of a specific area of a function #[derive(Debug, Clone, PartialEq, Eq)] @@ -70,6 +70,24 @@ impl Block { Ok(()) } + + /// Returns true if the variable is used after the ir node + pub(crate) fn isVarUsedAfterNode(&self, start: &Box, var: &Var) -> bool { + let mut used = false; + let mut started = false; + + for node in &self.nodes { + if node.uses(var) && started { + used = true; + } + + if node.is(start) { + started = true; + } + } + + used + } } /// Creates an new block diff --git a/src/Optimizations/Passes/MathInline.rs b/src/Optimizations/Passes/MathInline.rs index 2e1fad75..ab8c806b 100644 --- a/src/Optimizations/Passes/MathInline.rs +++ b/src/Optimizations/Passes/MathInline.rs @@ -1,4 +1,4 @@ -use crate::{prelude::*, PassManager::Pass}; +/*use crate::{prelude::*, Optimizations::Pass}; use std::collections::HashMap; /// ## Pass Pre compute value
@@ -14,29 +14,10 @@ pub fn InlineConstValue() -> Box { impl Pass for InlineConstValue { fn run(&self, block: &mut crate::prelude::Block) { - let mut vars: HashMap = HashMap::new(); // no use of + let mut vars: HashMap, /*already read*/bool)> = HashMap::new(); - for node in block.nodes.iter_mut() { - if &node.name() == "AddTypeType" { - let any = node.as_any(); - let add_node = any.downcast_ref::>().unwrap().clone(); - let var = add_node.inner3; - vars.insert(var.name.clone(), var.clone()); - } - - if &node.name() == "AddVarVar" { - let any = node.as_any(); - let add_node = any.downcast_ref::>().unwrap().clone(); - let op0 = add_node.inner1; - let op1 = add_node.inner2; - let res = add_node.inner3; - - if vars.contains_key(&op0.name) && vars.contains_key(&op1.name) { // not the most performant order but it's ok - node.replace(ConstAssign::new(res, )) - } else if vars.contains_key(&op0.name) || vars.contains_key(&op1.name) { - - } - } + for node in &block.nodes { + block.isVarUsedAfterNode(node, node.inn) } } -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/src/Target/x64/ir.rs b/src/Target/x64/ir.rs index bd367a85..3ef8ebb6 100644 --- a/src/Target/x64/ir.rs +++ b/src/Target/x64/ir.rs @@ -14,6 +14,7 @@ macro_rules! CompileMathVarVar { ($name:ident, $node:ident, $mnemonic:expr) => { pub(crate) fn $name(node: &$node, registry: &mut TargetBackendDescr) -> Vec { let infos = &mut registry.backend; + let block = registry.block.unwrap(); let loc1 = if let Some(loc1) = infos.varsStorage.get(&node.inner1) { loc1.clone() @@ -30,13 +31,13 @@ macro_rules! CompileMathVarVar { let boxed: Box = Box::new(node.clone()); - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &node.inner1) { + if !block.isVarUsedAfterNode(&boxed, &node.inner1) { infos.drop(&node.inner1); } - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &node.inner2) { + if !block.isVarUsedAfterNode(&boxed, &node.inner2) { infos.drop(&node.inner2); } - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &node.inner3) { + if !block.isVarUsedAfterNode(&boxed, &node.inner3) { return vec![]; // all of these calculations don't need to be done: dead code removal } @@ -109,6 +110,7 @@ macro_rules! CompileMathVarType { ($name:ident, $node:ident, $mnemonic:expr) => { pub(crate) fn $name(node: &$node, registry: &mut TargetBackendDescr) -> Vec { let infos = &mut registry.backend; + let block = registry.block.unwrap(); let loc1 = if let Some(loc1) = infos.varsStorage.get(&node.inner1) { loc1.clone() @@ -118,10 +120,10 @@ macro_rules! CompileMathVarType { let boxed: Box = Box::new(node.clone()); - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &node.inner1) { + if !block.isVarUsedAfterNode(&boxed, &node.inner1) { infos.drop(&node.inner1); } - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &node.inner3) { + if !block.isVarUsedAfterNode(&boxed, &node.inner3) { return vec![]; // all of these calculations don't need to be done: dead code removal } @@ -190,10 +192,11 @@ macro_rules! CompileMathTyTy { ($name:ident, $node:ident, $op:tt) => { pub(crate) fn $name(node: &$node, registry: &mut TargetBackendDescr) -> Vec { let val = node.inner1.val() $op node.inner2.val(); + let block = registry.block.unwrap(); let boxed: Box = Box::new(node.clone()); - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &node.inner3) { + if !block.isVarUsedAfterNode(&boxed, &node.inner3) { return vec![]; // all of these calculations don't need to be done: dead code removal } @@ -233,12 +236,13 @@ CompileMathTyTy!(CompileAndTyTy, And, &); pub(crate) fn CompileConstAssign(assign: &ConstAssign, registry: &mut TargetBackendDescr) -> Vec { let infos = &mut registry.backend; + let block = registry.block.unwrap(); let ty = &assign.inner1.ty; let boxed: Box = Box::new(assign.clone()); - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &assign.inner1) { + if !block.isVarUsedAfterNode(&boxed, &assign.inner1) { return vec![]; // all of these calculations don't need to be done: dead code removal } @@ -272,6 +276,7 @@ pub(crate) fn CompileConstAssign(assign: &ConstAssign, registry: &mut pub(crate) fn CompileConstAssignVar(assign: &ConstAssign, registry: &mut TargetBackendDescr) -> Vec { let infos = &mut registry.backend; + let block = registry.block.unwrap(); let loc = if let Some(loc) = infos.varsStorage.get_key_value(&assign.inner2) { loc.1.clone() @@ -282,11 +287,11 @@ pub(crate) fn CompileConstAssignVar(assign: &ConstAssign, registry: &m let ty = &assign.inner1.ty; let boxed: Box = Box::new(assign.clone()); - - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &assign.inner2) { + + if !block.isVarUsedAfterNode(&boxed, &assign.inner2) { infos.drop(&assign.inner2); } - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &assign.inner1) { + if !block.isVarUsedAfterNode(&boxed, &assign.inner1) { return vec![]; // all of these calculations don't need to be done: dead code removal } @@ -330,6 +335,8 @@ pub(crate) fn CompileConstAssignVar(assign: &ConstAssign, registry: &m } pub(crate) fn CompileConstAssignConst(assign: &ConstAssign, registry: &mut TargetBackendDescr) -> Vec { + let block = registry.block.unwrap(); + registry.backend.stackSafe = true; let infos = &mut registry.backend; @@ -338,7 +345,7 @@ pub(crate) fn CompileConstAssignConst(assign: &ConstAssign, registry let boxed: Box = Box::new(assign.clone()); - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &assign.inner1) { + if !block.isVarUsedAfterNode(&boxed, &assign.inner1) { return vec![]; // all of these calculations don't need to be done: dead code removal } @@ -416,6 +423,7 @@ pub(crate) fn CompileRetVar(ret: &Return, registry: &mut TargetBackendDescr pub(crate) fn CompileCast(cast: &Cast, registry: &mut TargetBackendDescr) -> Vec { let boxed: Box = Box::new(cast.clone()); + let block = registry.block.unwrap(); let loc = if let Some(loc) = registry.backend.varsStorage.get(&cast.inner1) { loc.clone() @@ -423,10 +431,10 @@ pub(crate) fn CompileCast(cast: &Cast, registry: &mut Ta panic!("unknown variable: {:?}", cast.inner1) }; - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &cast.inner1) { + if block.isVarUsedAfterNode(&boxed, &cast.inner1) { registry.backend.drop(&cast.inner1); } - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &cast.inner3) { + if block.isVarUsedAfterNode(&boxed, &cast.inner3) { return vec![]; } @@ -488,6 +496,7 @@ pub(crate) fn CompileCast(cast: &Cast, registry: &mut Ta pub(crate) fn CompileCall(call: &Call, Var>, registry: &mut TargetBackendDescr) -> Vec { let boxed: Box = Box::new(call.clone()); + let block = registry.block.unwrap(); let mut asm = vec![]; @@ -496,9 +505,7 @@ pub(crate) fn CompileCall(call: &Call, Var>, registry: &mut T let var = registry.backend.getVarByReg(reg.boxed()).cloned(); if let Some(var) = var { - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &var) { - registry.backend.drop(&var); - } else { + if block.isVarUsedAfterNode(&boxed, &var) { asm.push(Instr::with1(Mnemonic::Push, Operand::Reg(reg.boxed()))); } } @@ -545,8 +552,7 @@ pub(crate) fn CompileCall(call: &Call, Var>, registry: &mut T } }, } - - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, arg) { + if !block.isVarUsedAfterNode(&boxed, arg) { registry.backend.drop(arg); } } @@ -591,16 +597,13 @@ pub(crate) fn CompileCall(call: &Call, Var>, registry: &mut T registry.backend.insertVar(call.inner3.clone(), store); } - for reg in vec![x64Reg::Rcx, x64Reg::Rdx, x64Reg::Rsi, x64Reg::Rdi, x64Reg::Rsi] { // getback mutable registers if !registry.backend.openUsableRegisters64.contains(®.boxed()) { let var = registry.backend.getVarByReg(reg.boxed()).cloned(); if let Some(var) = var { - if !BlockX86FuncisVarUsedAfterNode(registry.block.unwrap(), &boxed, &var) { - registry.backend.drop(&var); - } else { + if block.isVarUsedAfterNode(&boxed, &var) { asm.push(Instr::with1(Mnemonic::Pop, Operand::Reg(reg.boxed()))); } } @@ -710,21 +713,4 @@ pub(crate) fn buildAsmX86<'a>(block: &'a Block, func: &Function, call: &CallConv Vec::from(out) -} - -pub(crate) fn BlockX86FuncisVarUsedAfterNode(block: &Block, startingNode: &Box, var: &Var) -> bool { - let mut used = false; - let mut started = false; - - for node in &block.nodes { - if node.uses(var) && started { - used = true; - } - - if node.is(startingNode) { - started = true; - } - } - - used } \ No newline at end of file