This commit is contained in:
static
2025-06-01 13:05:34 +00:00
parent 58c9a68820
commit 40ee759c23

View File

@@ -5,6 +5,7 @@ use std::ops::DerefMut;
use itertools::izip; use itertools::izip;
use lang_c::ast; use lang_c::ast;
use crate::asm::Register;
use crate::ir::*; use crate::ir::*;
use crate::opt::opt_utils::*; use crate::opt::opt_utils::*;
use crate::opt::*; use crate::opt::*;
@@ -52,6 +53,8 @@ impl Optimize<FunctionDefinition> for GvnInner {
println!("replaces: {replaces:?}"); println!("replaces: {replaces:?}");
let mut result = false;
for (bid, block) in code.blocks.iter_mut() { for (bid, block) in code.blocks.iter_mut() {
loop { loop {
let mut changed = false; let mut changed = false;
@@ -60,6 +63,8 @@ impl Optimize<FunctionDefinition> for GvnInner {
} }
changed = replace_exit_operands(&mut block.exit, &replaces) || changed; changed = replace_exit_operands(&mut block.exit, &replaces) || changed;
result = result || changed;
if !changed { if !changed {
break; break;
} }
@@ -68,7 +73,7 @@ impl Optimize<FunctionDefinition> for GvnInner {
println!("hihi2"); println!("hihi2");
false // TODO result
} }
} }
@@ -89,24 +94,38 @@ enum Expression {
op: ast::UnaryOperator, op: ast::UnaryOperator,
operand: Operand, operand: Operand,
}, },
TypeCast {
value: Operand,
target_dtype: Dtype,
},
GetElementPtr {
ptr: Operand,
offset: Operand,
dtype: Dtype,
},
} }
fn get_register_number( fn get_register_number(
rid: RegisterId, rid: RegisterId,
register_table: &mut HashMap<RegisterId, usize>, register_table: &mut HashMap<RegisterId, NumberOrConstant>,
expression_table: &HashMap<Expression, usize>, expression_table: &HashMap<Expression, usize>,
leader_table: &mut HashMap<usize, RegisterId>, leader_table: &mut HashMap<usize, RegisterOrConstant>,
) -> usize { ) -> NumberOrConstant {
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
let _ = leader_table.insert(number, rid); .entry(rid)
println!("[REG] {number}={rid:?}"); .or_insert(NumberOrConstant::Number(len))
.clone();
if let NumberOrConstant::Number(number) = number {
let _unused = leader_table.insert(number, RegisterOrConstant::Register(rid));
}
println!("[REG] {number:?}={rid:?}");
number number
} }
fn get_expression_number( fn get_expression_number(
expr: Expression, expr: Expression,
register_table: &HashMap<RegisterId, usize>, register_table: &HashMap<RegisterId, NumberOrConstant>,
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();
@@ -115,14 +134,26 @@ fn get_expression_number(
number number
} }
#[derive(Clone, Debug)]
enum RegisterOrConstant {
Register(RegisterId),
Constant(Constant),
}
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
enum NumberOrConstant {
Number(usize),
Constant(Constant),
}
fn traverse_rpo( fn traverse_rpo(
bid: BlockId, bid: BlockId,
code: &mut FunctionDefinition, code: &mut FunctionDefinition,
reverse_cfg: &mut 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, NumberOrConstant>,
expression_table: &mut HashMap<Expression, usize>, expression_table: &mut HashMap<Expression, usize>,
leader_tables: &mut HashMap<BlockId, HashMap<usize, RegisterId>>, leader_tables: &mut HashMap<BlockId, HashMap<usize, RegisterOrConstant>>,
replaces: &mut HashMap<RegisterId, ir::Operand>, replaces: &mut HashMap<RegisterId, ir::Operand>,
) { ) {
println!("bid: {bid}"); println!("bid: {bid}");
@@ -140,26 +171,34 @@ fn traverse_rpo(
if let Some(ref predecessors) = predecessors { 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()) .map(|(_, arg)| match &arg.args[aid] {
.map(|(rid, _)| { ir::Operand::Constant(constant) => NumberOrConstant::Constant(constant.clone()),
get_register_number(*rid, register_table, expression_table, &mut leader_table) ir::Operand::Register { rid, .. } => get_register_number(
*rid,
register_table,
expression_table,
&mut leader_table,
),
}) })
.collect::<HashSet<_>>(); .collect::<HashSet<_>>();
if numbers.len() == 1 { if numbers.len() == 1 {
let number = *numbers.iter().next().unwrap(); let number = numbers.iter().next().unwrap().clone();
let _ = register_table.insert(rid, number); match number {
let _ = leader_table.insert(number, rid); NumberOrConstant::Number(number) => {
let _unused = register_table.insert(rid, NumberOrConstant::Number(number));
let _unused =
leader_table.insert(number, RegisterOrConstant::Register(rid));
}
NumberOrConstant::Constant(constant) => {
let _unused =
register_table.insert(rid, NumberOrConstant::Constant(constant.clone()));
let _unused = replaces.insert(rid, ir::Operand::constant(constant.clone()));
}
}
} else { } else {
let _ = let _unused =
get_register_number(rid, register_table, expression_table, &mut leader_table); get_register_number(rid, register_table, expression_table, &mut leader_table);
} }
} }
@@ -193,6 +232,33 @@ fn traverse_rpo(
&mut leader_table, &mut leader_table,
), ),
}, },
Instruction::TypeCast {
value,
target_dtype,
} => Expression::TypeCast {
value: ir_operand_to_gvn_operand(
value,
register_table,
expression_table,
&mut leader_table,
),
target_dtype: target_dtype.clone(),
},
Instruction::GetElementPtr { ptr, offset, dtype } => Expression::GetElementPtr {
ptr: ir_operand_to_gvn_operand(
ptr,
register_table,
expression_table,
&mut leader_table,
),
offset: ir_operand_to_gvn_operand(
offset,
register_table,
expression_table,
&mut leader_table,
),
dtype: dtype.clone(),
},
_ => continue, _ => continue,
}; };
let number = get_expression_number(expr, register_table, expression_table); let number = get_expression_number(expr, register_table, expression_table);
@@ -201,10 +267,16 @@ fn traverse_rpo(
println!("{i} {number} {expression_table:?} {leader_table:?}"); println!("{i} {number} {expression_table:?} {leader_table:?}");
if let Some(leader_value) = leader_table.get(&number) { if let Some(leader_value) = leader_table.get(&number) {
// *inst.deref_mut() = Instruction::Nop; match leader_value {
let _ = register_table.insert(rid, number); RegisterOrConstant::Register(leader_value) => {
let _unused = replaces.insert(rid, ir::Operand::register(*leader_value, inst.dtype())); let _unused = register_table.insert(rid, NumberOrConstant::Number(number));
// println!("왜 않?"); let _unused =
replaces.insert(rid, ir::Operand::register(*leader_value, inst.dtype()));
}
RegisterOrConstant::Constant(constant) => {
let _unused = replaces.insert(rid, ir::Operand::constant(constant.clone()));
}
}
} else { } else {
if let Some(ref mut predecessors) = predecessors { if let Some(ref mut predecessors) = predecessors {
println!("하위 {predecessors:?} {leader_tables:?}"); println!("하위 {predecessors:?} {leader_tables:?}");
@@ -218,18 +290,28 @@ fn traverse_rpo(
let phinode_index = block.phinodes.len(); let phinode_index = block.phinodes.len();
block.phinodes.push(Named::new(None, inst.dtype())); block.phinodes.push(Named::new(None, inst.dtype()));
let _ = register_table.insert(RegisterId::arg(bid, phinode_index), number); let _unused = register_table.insert(
let _ = leader_table.insert(number, RegisterId::arg(bid, phinode_index)); RegisterId::arg(bid, phinode_index),
NumberOrConstant::Number(number),
);
let _unused = leader_table.insert(
number,
RegisterOrConstant::Register(RegisterId::arg(bid, phinode_index)),
);
let _unused = replaces.insert( let _unused = replaces.insert(
rid, rid,
ir::Operand::register(RegisterId::arg(bid, phinode_index), inst.dtype()), ir::Operand::register(RegisterId::arg(bid, phinode_index), inst.dtype()),
); );
for (bid_predecessor, jump_arg) in predecessors.iter_mut() { for (bid_predecessor, jump_arg) in predecessors.iter_mut() {
let new_arg = ir::Operand::register( let new_arg = match &leader_tables[bid_predecessor][&number] {
leader_tables[bid_predecessor][&number], RegisterOrConstant::Register(rid) => {
inst.dtype(), ir::Operand::register(*rid, inst.dtype())
); }
RegisterOrConstant::Constant(constant) => {
ir::Operand::constant(constant.clone())
}
};
jump_arg.args.push(new_arg.clone()); jump_arg.args.push(new_arg.clone());
let _ = phinode_allocs let _ = phinode_allocs
.entry(*bid_predecessor) .entry(*bid_predecessor)
@@ -241,8 +323,8 @@ fn traverse_rpo(
} }
} }
let _ = leader_table.insert(number, rid); let _unused = leader_table.insert(number, RegisterOrConstant::Register(rid));
let _ = register_table.insert(rid, number); let _unused = register_table.insert(rid, NumberOrConstant::Number(number));
} }
} }
@@ -272,17 +354,19 @@ fn traverse_rpo(
fn ir_operand_to_gvn_operand( fn ir_operand_to_gvn_operand(
operand: &ir::Operand, operand: &ir::Operand,
register_table: &mut HashMap<RegisterId, usize>, register_table: &mut HashMap<RegisterId, NumberOrConstant>,
expression_table: &HashMap<Expression, usize>, expression_table: &HashMap<Expression, usize>,
leader_table: &mut HashMap<usize, RegisterId>, leader_table: &mut HashMap<usize, RegisterOrConstant>,
) -> Operand { ) -> Operand {
match operand { match operand {
ir::Operand::Register { rid, .. } => Operand::Number(get_register_number( ir::Operand::Register { rid, .. } => {
*rid, match get_register_number(*rid, register_table, expression_table, leader_table) {
register_table, NumberOrConstant::Number(number) => Operand::Number(number),
expression_table, NumberOrConstant::Constant(constant) => {
leader_table, Operand::IrOperand(ir::Operand::Constant(constant))
)), }
}
}
_ => Operand::IrOperand(operand.clone()), _ => Operand::IrOperand(operand.clone()),
} }
} }