gcrecomp_core/recompiler/analysis/
loop_analysis.rs1use crate::recompiler::analysis::control_flow::{ControlFlowGraph, Loop};
3use bitvec::prelude::*;
4use smallvec::SmallVec;
5
6pub struct LoopAnalyzer;
7
8impl LoopAnalyzer {
9 pub fn analyze_loops(cfg: &ControlFlowGraph) -> Vec<LoopInfo> {
10 let loops = crate::recompiler::analysis::control_flow::ControlFlowAnalyzer::detect_loops(cfg);
11
12 loops.into_iter().map(|loop_| {
13 LoopInfo {
14 header: loop_.header,
15 body: loop_.body,
16 back_edges: loop_.back_edges,
17 exits: loop_.exits,
18 induction_variables: Vec::new(),
19 invariants: Vec::new(),
20 }
21 }).collect()
22 }
23
24 pub fn find_induction_variables(
25 loop_: &LoopInfo,
26 cfg: &ControlFlowGraph,
27 ) -> Vec<InductionVariable> {
28 let mut ivs = Vec::new();
31
32 for (block_idx, is_in_loop) in loop_.body.iter().enumerate() {
33 if *is_in_loop {
34 if let Some(block) = cfg.nodes.get(block_idx) {
35 for inst in &block.instructions {
36 }
39 }
40 }
41 }
42
43 ivs
44 }
45}
46
47#[derive(Debug, Clone)]
48pub struct LoopInfo {
49 pub header: u32,
50 pub body: BitVec<u32>,
51 pub back_edges: SmallVec<[(u32, u32); 2]>,
52 pub exits: SmallVec<[u32; 2]>,
53 pub induction_variables: Vec<InductionVariable>,
54 pub invariants: Vec<u8>, }
56
57#[derive(Debug, Clone)]
58pub struct InductionVariable {
59 pub register: u8,
60 pub initial_value: u32,
61 pub step: i32,
62 pub is_incrementing: bool,
63}
64