This commit is contained in:
static
2025-06-01 12:05:24 +00:00
parent 9d8e510138
commit 58c9a68820

View File

@@ -18,7 +18,7 @@ impl Optimize<FunctionDefinition> for GvnInner {
fn optimize(&mut self, code: &mut FunctionDefinition) -> bool { fn optimize(&mut self, code: &mut FunctionDefinition) -> bool {
println!("hihi2352352"); println!("hihi2352352");
let cfg = make_cfg(code); 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 domtree = Domtree::new(code.bid_init, &cfg, &reverse_cfg);
let mut register_table = HashMap::new(); let mut register_table = HashMap::new();
@@ -41,7 +41,7 @@ impl Optimize<FunctionDefinition> for GvnInner {
traverse_rpo( traverse_rpo(
*bid, *bid,
code, code,
&reverse_cfg, &mut reverse_cfg,
&domtree, &domtree,
&mut register_table, &mut register_table,
&mut expression_table, &mut expression_table,
@@ -100,6 +100,7 @@ fn get_register_number(
let len = register_table.len() + expression_table.len(); let len = register_table.len() + expression_table.len();
let number = *register_table.entry(rid).or_insert(len); let number = *register_table.entry(rid).or_insert(len);
let _ = leader_table.insert(number, rid); let _ = leader_table.insert(number, rid);
println!("[REG] {number}={rid:?}");
number number
} }
@@ -109,13 +110,15 @@ fn get_expression_number(
expression_table: &mut HashMap<Expression, usize>, expression_table: &mut HashMap<Expression, usize>,
) -> usize { ) -> usize {
let len = register_table.len() + expression_table.len(); 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( fn traverse_rpo(
bid: BlockId, bid: BlockId,
code: &mut FunctionDefinition, code: &mut FunctionDefinition,
reverse_cfg: &HashMap<BlockId, Vec<(BlockId, JumpArg)>>, reverse_cfg: &mut HashMap<BlockId, Vec<(BlockId, JumpArg)>>,
domtree: &Domtree, domtree: &Domtree,
register_table: &mut HashMap<RegisterId, usize>, register_table: &mut HashMap<RegisterId, usize>,
expression_table: &mut HashMap<Expression, usize>, expression_table: &mut HashMap<Expression, usize>,
@@ -130,16 +133,25 @@ fn traverse_rpo(
.and_then(|bid_idom| leader_tables.get(bid_idom)) .and_then(|bid_idom| leader_tables.get(bid_idom))
.cloned() .cloned()
.unwrap_or_default(); .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() { for (aid, _) in block.phinodes.iter().enumerate() {
let rid = RegisterId::arg(bid, aid); let rid = RegisterId::arg(bid, aid);
if !predecessors
.iter()
.all(|(_, arg)| arg.args[aid].get_register().is_some())
{
continue;
}
let numbers = predecessors let numbers = predecessors
.iter() .iter()
.filter_map(|(_, arg)| arg.args[aid].get_register()) .filter_map(|(_, arg)| arg.args[aid].get_register())
.map(|(rid, _)| { .map(|(rid, _)| {
get_register_number(*rid, register_table, expression_table, leader_table) get_register_number(*rid, register_table, expression_table, &mut leader_table)
}) })
.collect::<HashSet<_>>(); .collect::<HashSet<_>>();
if numbers.len() == 1 { if numbers.len() == 1 {
@@ -147,17 +159,30 @@ fn traverse_rpo(
let _ = register_table.insert(rid, number); let _ = register_table.insert(rid, number);
let _ = leader_table.insert(number, rid); let _ = leader_table.insert(number, rid);
} else { } 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() { for (i, inst) in block.instructions.iter_mut().enumerate() {
let expr = match inst.deref().deref() { let expr = match inst.deref().deref() {
Instruction::BinOp { op, lhs, rhs, .. } => Expression::BinOp { Instruction::BinOp { op, lhs, rhs, .. } => Expression::BinOp {
op: op.clone(), op: op.clone(),
lhs: ir_operand_to_gvn_operand(lhs, register_table, expression_table, leader_table), lhs: ir_operand_to_gvn_operand(
rhs: ir_operand_to_gvn_operand(rhs, register_table, expression_table, leader_table), 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 { Instruction::UnaryOp { op, operand, .. } => Expression::UnaryOp {
op: op.clone(), op: op.clone(),
@@ -165,7 +190,7 @@ fn traverse_rpo(
operand, operand,
register_table, register_table,
expression_table, expression_table,
leader_table, &mut leader_table,
), ),
}, },
_ => continue, _ => continue,
@@ -177,14 +202,72 @@ fn traverse_rpo(
if let Some(leader_value) = leader_table.get(&number) { if let Some(leader_value) = leader_table.get(&number) {
// *inst.deref_mut() = Instruction::Nop; // *inst.deref_mut() = Instruction::Nop;
let _ = register_table.insert(rid, number);
let _unused = replaces.insert(rid, ir::Operand::register(*leader_value, inst.dtype())); let _unused = replaces.insert(rid, ir::Operand::register(*leader_value, inst.dtype()));
println!("왜 않?"); // println!("왜 않?");
} else { } 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( fn ir_operand_to_gvn_operand(
@@ -203,3 +286,9 @@ fn ir_operand_to_gvn_operand(
_ => Operand::IrOperand(operand.clone()), _ => Operand::IrOperand(operand.clone()),
} }
} }
fn fill_jump_args(bid: BlockId, arg: &mut JumpArg, mut new_args: Vec<ir::Operand>) {
if bid == arg.bid {
arg.args.append(&mut new_args);
}
}