From 58c9a68820cdf7a6d6ff100ac2f96b7b4f1f2f68 Mon Sep 17 00:00:00 2001 From: static Date: Sun, 1 Jun 2025 12:05:24 +0000 Subject: [PATCH] HW5 (2) --- src/opt/gvn.rs | 119 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 104 insertions(+), 15 deletions(-) diff --git a/src/opt/gvn.rs b/src/opt/gvn.rs index 2c62dec..5c0fed6 100644 --- a/src/opt/gvn.rs +++ b/src/opt/gvn.rs @@ -18,7 +18,7 @@ impl Optimize for GvnInner { fn optimize(&mut self, code: &mut FunctionDefinition) -> bool { println!("hihi2352352"); let cfg = make_cfg(code); - let reverse_cfg = reverse_cfg(&cfg); + let mut reverse_cfg = reverse_cfg(&cfg); let domtree = Domtree::new(code.bid_init, &cfg, &reverse_cfg); let mut register_table = HashMap::new(); @@ -41,7 +41,7 @@ impl Optimize for GvnInner { traverse_rpo( *bid, code, - &reverse_cfg, + &mut reverse_cfg, &domtree, &mut register_table, &mut expression_table, @@ -100,6 +100,7 @@ fn get_register_number( let len = register_table.len() + expression_table.len(); let number = *register_table.entry(rid).or_insert(len); let _ = leader_table.insert(number, rid); + println!("[REG] {number}={rid:?}"); number } @@ -109,13 +110,15 @@ fn get_expression_number( expression_table: &mut HashMap, ) -> usize { let len = register_table.len() + expression_table.len(); - *expression_table.entry(expr.clone()).or_insert(len) + let number = *expression_table.entry(expr.clone()).or_insert(len); + println!("[EXPR] {number}={expr:?}"); + number } fn traverse_rpo( bid: BlockId, code: &mut FunctionDefinition, - reverse_cfg: &HashMap>, + reverse_cfg: &mut HashMap>, domtree: &Domtree, register_table: &mut HashMap, expression_table: &mut HashMap, @@ -130,16 +133,25 @@ fn traverse_rpo( .and_then(|bid_idom| leader_tables.get(bid_idom)) .cloned() .unwrap_or_default(); - let leader_table = leader_tables.entry(bid).or_insert(idom_leader_table); + // let leader_table = leader_tables.entry(bid).or_insert(idom_leader_table); + let mut leader_table = idom_leader_table; - if let Some(predecessors) = reverse_cfg.get(&bid) { + let mut predecessors = reverse_cfg.get_mut(&bid); + if let Some(ref predecessors) = predecessors { for (aid, _) in block.phinodes.iter().enumerate() { let rid = RegisterId::arg(bid, aid); + if !predecessors + .iter() + .all(|(_, arg)| arg.args[aid].get_register().is_some()) + { + continue; + } + let numbers = predecessors .iter() .filter_map(|(_, arg)| arg.args[aid].get_register()) .map(|(rid, _)| { - get_register_number(*rid, register_table, expression_table, leader_table) + get_register_number(*rid, register_table, expression_table, &mut leader_table) }) .collect::>(); if numbers.len() == 1 { @@ -147,17 +159,30 @@ fn traverse_rpo( let _ = register_table.insert(rid, number); let _ = leader_table.insert(number, rid); } else { - let _ = get_register_number(rid, register_table, expression_table, leader_table); + let _ = + get_register_number(rid, register_table, expression_table, &mut leader_table); } } } + let mut phinode_allocs = HashMap::new(); + for (i, inst) in block.instructions.iter_mut().enumerate() { let expr = match inst.deref().deref() { Instruction::BinOp { op, lhs, rhs, .. } => Expression::BinOp { op: op.clone(), - lhs: ir_operand_to_gvn_operand(lhs, register_table, expression_table, leader_table), - rhs: ir_operand_to_gvn_operand(rhs, register_table, expression_table, leader_table), + lhs: ir_operand_to_gvn_operand( + lhs, + register_table, + expression_table, + &mut leader_table, + ), + rhs: ir_operand_to_gvn_operand( + rhs, + register_table, + expression_table, + &mut leader_table, + ), }, Instruction::UnaryOp { op, operand, .. } => Expression::UnaryOp { op: op.clone(), @@ -165,7 +190,7 @@ fn traverse_rpo( operand, register_table, expression_table, - leader_table, + &mut leader_table, ), }, _ => continue, @@ -177,14 +202,72 @@ fn traverse_rpo( if let Some(leader_value) = leader_table.get(&number) { // *inst.deref_mut() = Instruction::Nop; + let _ = register_table.insert(rid, number); let _unused = replaces.insert(rid, ir::Operand::register(*leader_value, inst.dtype())); - println!("왜 않?"); + // println!("왜 않?"); } else { - let _ = leader_table.insert(number, rid); - } + if let Some(ref mut predecessors) = predecessors { + println!("하위 {predecessors:?} {leader_tables:?}"); + if predecessors.iter().all(|(bid_predecessor, _)| { + leader_tables + .get(bid_predecessor) + .and_then(|leader_table| Some(leader_table.contains_key(&number))) + .unwrap_or(false) + }) { + println!("상위"); - // TODO: Phinode insert + let phinode_index = block.phinodes.len(); + block.phinodes.push(Named::new(None, inst.dtype())); + let _ = register_table.insert(RegisterId::arg(bid, phinode_index), number); + let _ = leader_table.insert(number, RegisterId::arg(bid, phinode_index)); + let _unused = replaces.insert( + rid, + ir::Operand::register(RegisterId::arg(bid, phinode_index), inst.dtype()), + ); + + for (bid_predecessor, jump_arg) in predecessors.iter_mut() { + let new_arg = ir::Operand::register( + leader_tables[bid_predecessor][&number], + inst.dtype(), + ); + jump_arg.args.push(new_arg.clone()); + let _ = phinode_allocs + .entry(*bid_predecessor) + .or_insert_with(Vec::new) + .push(new_arg); + } + + continue; + } + } + + let _ = leader_table.insert(number, rid); + let _ = register_table.insert(rid, number); + } } + + for (p_bid, new_args) in phinode_allocs { + match &mut code.blocks.get_mut(&p_bid).unwrap().exit { + BlockExit::Jump { arg } => { + fill_jump_args(bid, arg, new_args); + } + BlockExit::ConditionalJump { + arg_then, arg_else, .. + } => { + fill_jump_args(bid, arg_then, new_args.clone()); + fill_jump_args(bid, arg_else, new_args); + } + BlockExit::Switch { default, cases, .. } => { + fill_jump_args(bid, default, new_args.clone()); + for (_, arg) in cases { + fill_jump_args(bid, arg, new_args.clone()); + } + } + _ => (), + } + } + + let _unused = leader_tables.insert(bid, leader_table); } fn ir_operand_to_gvn_operand( @@ -203,3 +286,9 @@ fn ir_operand_to_gvn_operand( _ => Operand::IrOperand(operand.clone()), } } + +fn fill_jump_args(bid: BlockId, arg: &mut JumpArg, mut new_args: Vec) { + if bid == arg.bid { + arg.args.append(&mut new_args); + } +}