use alloc::{vec, vec::Vec};
use cubecl_ir::{CoopMma, GlobalState, Instruction, Operation, Operator, UnaryOperands, Value};
use hashbrown::HashMap;
use crate::post_processing::{
analysis_helper::GlobalAnalyses,
util::AtomicCounter,
visitor::{InstructionVisitor, Visitor},
};
#[derive(Default, Debug)]
pub struct InlineAssignments {
substitutions: HashMap<Value, Value>,
}
impl InstructionVisitor for InlineAssignments {
fn visit_instruction(
&mut self,
mut inst: Instruction,
_global_state: &GlobalState,
analyses: &GlobalAnalyses,
changes: &AtomicCounter,
) -> Vec<Instruction> {
let mut visitor = Visitor(());
visitor.visit_operation(&mut inst.operation, analyses, |_, val| {
if let Some(substitution) = self.substitutions.get(val) {
*val = *substitution;
changes.inc();
}
});
match &mut inst.operation {
Operation::Copy(input)
| Operation::Operator(Operator::Cast(UnaryOperands { input }))
| Operation::Operator(Operator::Reinterpret(UnaryOperands { input }))
| Operation::CoopMma(CoopMma::Cast { input })
if (input.is_immutable() || input.is_array_like() || input.ty.is_ptr())
&& (inst.out.unwrap().is_immutable()
|| inst.out.unwrap().is_array_like()
|| inst.out.unwrap().ty.is_ptr())
&& input.ty == inst.out.unwrap().ty =>
{
self.substitutions.insert(inst.out.unwrap(), *input);
changes.inc();
vec![]
}
_ => vec![inst],
}
}
}