gcrecomp-core 0.0.1-alpha

Static recompiler for GameCube games to Rust
Documentation
// Loop Analysis
use crate::recompiler::analysis::control_flow::{ControlFlowGraph, Loop};
use bitvec::prelude::*;
use smallvec::SmallVec;

pub struct LoopAnalyzer;

impl LoopAnalyzer {
    pub fn analyze_loops(cfg: &ControlFlowGraph) -> Vec<LoopInfo> {
        let loops = crate::recompiler::analysis::control_flow::ControlFlowAnalyzer::detect_loops(cfg);
        
        loops.into_iter().map(|loop_| {
            LoopInfo {
                header: loop_.header,
                body: loop_.body,
                back_edges: loop_.back_edges,
                exits: loop_.exits,
                induction_variables: Vec::new(),
                invariants: Vec::new(),
            }
        }).collect()
    }
    
    pub fn find_induction_variables(
        loop_: &LoopInfo,
        cfg: &ControlFlowGraph,
    ) -> Vec<InductionVariable> {
        // Analyze loop body to find induction variables
        // (variables that are incremented/decremented each iteration)
        let mut ivs = Vec::new();

        for (block_idx, is_in_loop) in loop_.body.iter().enumerate() {
            if *is_in_loop {
                if let Some(block) = cfg.nodes.get(block_idx) {
                    for inst in &block.instructions {
                        // Check for addi/subi with loop counter
                        // This is simplified - would need more analysis
                    }
                }
            }
        }

        ivs
    }
}

#[derive(Debug, Clone)]
pub struct LoopInfo {
    pub header: u32,
    pub body: BitVec<u32>,
    pub back_edges: SmallVec<[(u32, u32); 2]>,
    pub exits: SmallVec<[u32; 2]>,
    pub induction_variables: Vec<InductionVariable>,
    pub invariants: Vec<u8>, // Registers that are invariant in the loop
}

#[derive(Debug, Clone)]
pub struct InductionVariable {
    pub register: u8,
    pub initial_value: u32,
    pub step: i32,
    pub is_incrementing: bool,
}