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 {
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<FunctionDefinition> 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<Expression, usize>,
) -> 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<BlockId, Vec<(BlockId, JumpArg)>>,
reverse_cfg: &mut HashMap<BlockId, Vec<(BlockId, JumpArg)>>,
domtree: &Domtree,
register_table: &mut HashMap<RegisterId, usize>,
expression_table: &mut HashMap<Expression, usize>,
@@ -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::<HashSet<_>>();
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,16 +202,74 @@ 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!("상위");
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);
}
// TODO: Phinode insert
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(
operand: &ir::Operand,
register_table: &mut HashMap<RegisterId, usize>,
@@ -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<ir::Operand>) {
if bid == arg.bid {
arg.args.append(&mut new_args);
}
}