fn global_liveness_analysis(
    blocks: LinkedHashMap<MuName, CFGBlockNode>,
    cf: &mut CompiledFunction,
    func: &MuFunctionVersion
) {
    info!("---global liveness analysis---");
    info!("{} blocks", blocks.len());

    // init live in and live out
    let mut livein: LinkedHashMap<MuName, LinkedHashSet<MuID>> = {
        let mut ret = LinkedHashMap::new();
        for name in blocks.keys() {
            ret.insert(name.clone(), LinkedHashSet::new());
        }
        ret
    };
    let mut liveout: LinkedHashMap<MuName, LinkedHashSet<MuID>> = {
        let mut ret = LinkedHashMap::new();
        for name in blocks.keys() {
            ret.insert(name.clone(), LinkedHashSet::new());
        }
        ret
    };

    // is the result changed in this iteration?
    let mut is_changed = true;
    // record iteration count
    let mut i = 0;

    while is_changed {
        trace_if!(TRACE_LIVENESS, "---iteration {}---", i);
        i += 1;

        // reset
        is_changed = false;

        for node in blocks.keys() {
            let cfg_node = blocks.get(node).unwrap();

            // old livein/out
            let in_set_old = livein.get(node).unwrap().clone();
            let out_set_old = liveout.get(node).unwrap().clone();

            // in <- use + (out - def)
            {
                let inset = livein.get_mut(node).unwrap();

                inset.clear();

                // (1) out - def
                inset.add_all(liveout.get(node).unwrap().clone());
                for def in cfg_node.defs.iter() {
                    inset.remove(def);
                }

                // (2) in + (out - def)
                for in_reg in cfg_node.uses.iter() {
                    inset.insert(*in_reg);
                }
            }

            // out[n] <- union(in[s] for every successor s of n)
            {
                let outset = liveout.get_mut(node).unwrap();
                outset.clear();

                for s in cfg_node.succ.iter() {
                    outset.add_all(livein.get(s).unwrap().clone());
                }
            }

            // is in/out changed in this iteration?
            let n_changed = !in_set_old.equals(livein.get(node).unwrap()) ||
                !out_set_old.equals(liveout.get(node).unwrap());

            if TRACE_LIVENESS {
                trace!("block {}", node);
                trace!("in(old)  = {:?}", in_set_old);
                trace!("in(new)  = {:?}", livein.get(node).unwrap());
                trace!("out(old) = {:?}", out_set_old);
                trace!("out(new) = {:?}", liveout.get(node).unwrap());
            }

            is_changed = is_changed || n_changed;
        }
    }

    info!("finished in {} iterations", i);

    // set live in and live out
    for block in blocks.keys() {
        let livein: Vec<MuID> = livein
            .get(block)
            .unwrap()
            .clone()
            .iter()
            .map(|x| *x)
            .collect();
        if TRACE_LIVENESS {
            let display_array: Vec<String> = livein
                .iter()
                .map(|x| func.context.get_temp_display(*x))
                .collect();
            trace!("livein  for block {}: {:?}", block, display_array);
        }
        cf.mc_mut().set_ir_block_livein(block, livein);

        let liveout: Vec<MuID> = liveout
            .get(block)
            .unwrap()
            .clone()
            .iter()
            .map(|x| *x)
            .collect();
        if TRACE_LIVENESS {
            let display_array: Vec<String> = liveout
                .iter()
                .map(|x| func.context.get_temp_display(*x))
                .collect();
            trace!("liveout for block {}: {:?}", block, display_array);
        }
        cf.mc_mut().set_ir_block_liveout(block, liveout);
    }
}
/// global analysis, the iterative algorithm to compute livenss until livein/out reaches a fix point
global analysis, the iterative algorithm to compute livenss until livein/out reaches a fix point
global analysis the iterative algorithm to compute livenss until livein / out reaches a fix point
fn global_liveness_analysis(
    blocks: LinkedHashMap<MuName, CFGBlockNode>,
    cf: &mut CompiledFunction,
    func: &MuFunctionVersion
) {
    info!("---global liveness analysis---");
    info!("{} blocks", blocks.len());
    // init live in and live out
    let mut livein: LinkedHashMap<MuName, LinkedHashSet<MuID>> = {
        let mut ret = LinkedHashMap::new();
        for name in blocks.keys() {
            ret.insert(name.clone(), LinkedHashSet::new());
        }
        ret
    };
    let mut liveout: LinkedHashMap<MuName, LinkedHashSet<MuID>> = {
        let mut ret = LinkedHashMap::new();
        for name in blocks.keys() {
            ret.insert(name.clone(), LinkedHashSet::new());
        }
        ret
    };
    // is the result changed in this iteration?
    let mut is_changed = true;
    // record iteration count
    let mut i = 0;
    while is_changed {
        trace_if!(TRACE_LIVENESS, "---iteration {}---", i);
        i += 1;
        // reset
        is_changed = false;
        for node in blocks.keys() {
            let cfg_node = blocks.get(node).unwrap();
            // old livein/out
            let in_set_old = livein.get(node).unwrap().clone();
            let out_set_old = liveout.get(node).unwrap().clone();
            // in <- use + (out - def)
            {
                let inset = livein.get_mut(node).unwrap();
                inset.clear();
                // (1) out - def
                inset.add_all(liveout.get(node).unwrap().clone());
                for def in cfg_node.defs.iter() {
                    inset.remove(def);
                }
                // (2) in + (out - def)
                for in_reg in cfg_node.uses.iter() {
                    inset.insert(*in_reg);
                }
            }
            // out[n] <- union(in[s] for every successor s of n)
            {
                let outset = liveout.get_mut(node).unwrap();
                outset.clear();
                for s in cfg_node.succ.iter() {
                    outset.add_all(livein.get(s).unwrap().clone());
                }
            }
            // is in/out changed in this iteration?
            let n_changed = !in_set_old.equals(livein.get(node).unwrap()) ||
                !out_set_old.equals(liveout.get(node).unwrap());
            if TRACE_LIVENESS {
                trace!("block {}", node);
                trace!("in(old)  = {:?}", in_set_old);
                trace!("in(new)  = {:?}", livein.get(node).unwrap());
                trace!("out(old) = {:?}", out_set_old);
                trace!("out(new) = {:?}", liveout.get(node).unwrap());
            }
            is_changed = is_changed || n_changed;
        }
    }
    info!("finished in {} iterations", i);
    // set live in and live out
    for block in blocks.keys() {
        let livein: Vec<MuID> = livein
            .get(block)
            .unwrap()
            .clone()
            .iter()
            .map(|x| *x)
            .collect();
        if TRACE_LIVENESS {
            let display_array: Vec<String> = livein
                .iter()
                .map(|x| func.context.get_temp_display(*x))
                .collect();
            trace!("livein  for block {}: {:?}", block, display_array);
        }
        cf.mc_mut().set_ir_block_livein(block, livein);
        let liveout: Vec<MuID> = liveout
            .get(block)
            .unwrap()
            .clone()
            .iter()
            .map(|x| *x)
            .collect();
        if TRACE_LIVENESS {
            let display_array: Vec<String> = liveout
                .iter()
                .map(|x| func.context.get_temp_display(*x))
                .collect();
            trace!("liveout for block {}: {:?}", block, display_array);
        }
        cf.mc_mut().set_ir_block_liveout(block, liveout);
    }
}
fn global_liveness_analysis ( blocks : LinkedHashMap < MuName , CFGBlockNode > , cf : & mut CompiledFunction , func : & MuFunctionVersion ) { info ! ( " " ) ; info ! ( " " blocks len ( ) ) ; // init live in and live out let mut livein : LinkedHashMap < MuName , LinkedHashSet < MuID > > = { let mut ret = LinkedHashMap :: new ( ) ; for name in blocks . keys ( ) { ret . insert ( name . clone ( ) , LinkedHashSet :: new ( ) ) ; } ret } ; let mut liveout : LinkedHashMap < MuName , LinkedHashSet < MuID > > = { let mut ret = LinkedHashMap :: new ( ) ; for name in blocks . keys ( ) { ret . insert ( name . clone ( ) , LinkedHashSet :: new ( ) ) ; } ret } ; // is the result changed in this iteration? let mut is_changed = true ; // record iteration count let mut i = 0 ; while is_changed { trace_if ! ( TRACE_LIVENESS " " i ) ; i += 1 ; // reset is_changed = false ; for node in blocks . keys ( ) { let cfg_node = blocks . get ( node ) . unwrap ( ) ; // old livein/out let in_set_old = livein . get ( node ) . unwrap ( ) . clone ( ) ; let out_set_old = liveout . get ( node ) . unwrap ( ) . clone ( ) ; // in <- use + (out - def) { let inset = livein . get_mut ( node ) . unwrap ( ) ; inset . clear ( ) ; // (1) out - def inset . add_all ( liveout . get ( node ) . unwrap ( ) . clone ( ) ) ; for def in cfg_node . defs . iter ( ) { inset . remove ( def ) ; } // (2) in + (out - def) for in_reg in cfg_node . uses . iter ( ) { inset . insert ( * in_reg ) ; } } // out[n] <- union(in[s] for every successor s of n) { let outset = liveout . get_mut ( node ) . unwrap ( ) ; outset . clear ( ) ; for s in cfg_node . succ . iter ( ) { outset . add_all ( livein . get ( s ) . unwrap ( ) . clone ( ) ) ; } } // is in/out changed in this iteration? let n_changed = ! in_set_old . equals ( livein . get ( node ) . unwrap ( ) ) || ! out_set_old . equals ( liveout . get ( node ) . unwrap ( ) ) ; if TRACE_LIVENESS { trace ! ( " " node ) ; trace ! ( " " in_set_old ) ; trace ! ( " " livein get ( node ) unwrap ( ) ) ; trace ! ( " " out_set_old ) ; trace ! ( " " liveout get ( node ) unwrap ( ) ) ; } is_changed = is_changed || n_changed ; } } info ! ( " " i ) ; // set live in and live out for block in blocks . keys ( ) { let livein : Vec < MuID > = livein . get ( block ) . unwrap ( ) . clone ( ) . iter ( ) . map ( | x | * x ) . collect ( ) ; if TRACE_LIVENESS { let display_array : Vec < String > = livein . iter ( ) . map ( | x | func . context . get_temp_display ( * x ) ) . collect ( ) ; trace ! ( " " block display_array ) ; } cf . mc_mut ( ) . set_ir_block_livein ( block , livein ) ; let liveout : Vec < MuID > = liveout . get ( block ) . unwrap ( ) . clone ( ) . iter ( ) . map ( | x | * x ) . collect ( ) ; if TRACE_LIVENESS { let display_array : Vec < String > = liveout . iter ( ) . map ( | x | func . context . get_temp_display ( * x ) ) . collect ( ) ; trace ! ( " " block display_array ) ; } cf . mc_mut ( ) . set_ir_block_liveout ( block , liveout ) ; } }
global analysis, the iterative algorithm to compute livenss until livein/out reaches a fix point
global analysis the iterative algorithm to compute livenss until livein / out reaches a fix point
blocks
LinkedHashMap<MuName, CFGBlockNode>
cf
&mut CompiledFunction
func
&MuFunctionVersion
blocks
LinkedHashMap<MuName, CFGBlockNode>
cf
&mut CompiledFunction
func
&MuFunctionVersion