mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-14 22:38:46 +00:00
HW5 (2)
This commit is contained in:
119
src/opt/gvn.rs
119
src/opt/gvn.rs
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user