fn build_cfg_nodes(cf: &mut CompiledFunction) -> LinkedHashMap<MuName, CFGBlockNode> {
    info!("---local liveness analysis---");
    let mc = cf.mc();
    let mut ret = LinkedHashMap::new();
    let all_blocks = mc.get_all_blocks();

    // create maps (start_inst -> name) and (end_inst -> name)
    // we will use it to find basic blocks when given a inst index
    let (start_inst_map, end_inst_map) = {
        let mut start_inst_map: LinkedHashMap<usize, &str> = LinkedHashMap::new();
        let mut end_inst_map: LinkedHashMap<usize, &str> = LinkedHashMap::new();
        for block in all_blocks.iter() {
            let range = match mc.get_block_range(block) {
                Some(range) => range,
                None => panic!("cannot find range for block {}", block)
            };
            // start inst
            let first_inst = range.start;
            // last inst (we need to skip symbols)
            let last_inst = match mc.get_last_inst(range.end) {
                Some(last) => last,
                None => {
                    panic!(
                        "cannot find last instruction in block {}, \
                         this block contains no instruction?",
                        block
                    )
                }
            };
            trace_if!(
                TRACE_LIVENESS,
                "Block {}: start_inst={}, end_inst(inclusive)={}",
                block,
                first_inst,
                last_inst
            );

            start_inst_map.insert(first_inst, block);
            end_inst_map.insert(last_inst, block);
        }

        (start_inst_map, end_inst_map)
    };

    // collect info for each basic block
    for block in mc.get_all_blocks().iter() {
        trace_if!(TRACE_LIVENESS, "---block {}---", block);
        let range = mc.get_block_range(block).unwrap();
        let start_inst = range.start;
        let end = range.end;

        // livein set of this block is what temps this block uses from other blocks
        // defs is what temps this block defines in the block
        let (livein, defs) = {
            // we gradually build livein
            let mut livein = vec![];
            // we need to know all temporaries defined in the block
            // if a temporary is not defined in this block, it is a livein for this block
            let mut all_defined: LinkedHashSet<MuID> = LinkedHashSet::new();

            for i in start_inst..end {
                let reg_uses = mc.get_inst_reg_uses(i);

                // if a reg is used but not defined before, it is a live-in
                for reg in reg_uses {
                    let reg = c(reg);
                    if !all_defined.contains(&reg) {
                        livein.push(reg);
                    }
                }

                let reg_defs = mc.get_inst_reg_defines(i);
                for reg in reg_defs {
                    let reg = c(reg);
                    all_defined.insert(reg);
                }
            }

            let defs: Vec<MuID> = all_defined.iter().map(|x| *x).collect();

            (livein, defs)
        };

        let preds: Vec<String> = {
            let mut ret = vec![];

            // predecessors of the first instruction is the predecessors of this block
            for pred in mc.get_preds(start_inst).into_iter() {
                match end_inst_map.get(pred) {
                    Some(str) => ret.push(String::from(*str)),
                    None => {}
                }
            }

            ret
        };

        let succs: Vec<String> = {
            let mut ret = vec![];

            // successors of the last instruction is the successors of this block
            for succ in mc.get_succs(mc.get_last_inst(end).unwrap()).into_iter() {
                match start_inst_map.get(succ) {
                    Some(str) => ret.push(String::from(*str)),
                    None => {}
                }
            }

            ret
        };

        let node = CFGBlockNode {
            block: block.clone(),
            pred: preds,
            succ: succs,
            uses: livein,
            defs: defs
        };

        trace_if!(TRACE_LIVENESS, "as CFGNode {:?}", node);
        ret.insert(block.clone(), node);
    }

    ret
}
/// builds a LinkedHashMap from basic block names to CFGBlockNode
/// We need to collect for each basic block:
/// * predecessors
/// * successors
/// * uses
/// * defs
builds a LinkedHashMap from basic block names to CFGBlockNode
We need to collect for each basic block:
predecessors
successors
uses
defs
builds a LinkedHashMap from basic block names to CFGBlockNode We need to collect for each basic block : predecessors successors uses defs
fn build_cfg_nodes(cf: &mut CompiledFunction) -> LinkedHashMap<MuName, CFGBlockNode> {
    info!("---local liveness analysis---");
    let mc = cf.mc();
    let mut ret = LinkedHashMap::new();
    let all_blocks = mc.get_all_blocks();
    // create maps (start_inst -> name) and (end_inst -> name)
    // we will use it to find basic blocks when given a inst index
    let (start_inst_map, end_inst_map) = {
        let mut start_inst_map: LinkedHashMap<usize, &str> = LinkedHashMap::new();
        let mut end_inst_map: LinkedHashMap<usize, &str> = LinkedHashMap::new();
        for block in all_blocks.iter() {
            let range = match mc.get_block_range(block) {
                Some(range) => range,
                None => panic!("cannot find range for block {}", block)
            };
            // start inst
            let first_inst = range.start;
            // last inst (we need to skip symbols)
            let last_inst = match mc.get_last_inst(range.end) {
                Some(last) => last,
                None => {
                    panic!(
                        "cannot find last instruction in block {}, \
                         this block contains no instruction?",
                        block
                    )
                }
            };
            trace_if!(
                TRACE_LIVENESS,
                "Block {}: start_inst={}, end_inst(inclusive)={}",
                block,
                first_inst,
                last_inst
            );
            start_inst_map.insert(first_inst, block);
            end_inst_map.insert(last_inst, block);
        }
        (start_inst_map, end_inst_map)
    };
    // collect info for each basic block
    for block in mc.get_all_blocks().iter() {
        trace_if!(TRACE_LIVENESS, "---block {}---", block);
        let range = mc.get_block_range(block).unwrap();
        let start_inst = range.start;
        let end = range.end;
        // livein set of this block is what temps this block uses from other blocks
        // defs is what temps this block defines in the block
        let (livein, defs) = {
            // we gradually build livein
            let mut livein = vec![];
            // we need to know all temporaries defined in the block
            // if a temporary is not defined in this block, it is a livein for this block
            let mut all_defined: LinkedHashSet<MuID> = LinkedHashSet::new();
            for i in start_inst..end {
                let reg_uses = mc.get_inst_reg_uses(i);
                // if a reg is used but not defined before, it is a live-in
                for reg in reg_uses {
                    let reg = c(reg);
                    if !all_defined.contains(&reg) {
                        livein.push(reg);
                    }
                }
                let reg_defs = mc.get_inst_reg_defines(i);
                for reg in reg_defs {
                    let reg = c(reg);
                    all_defined.insert(reg);
                }
            }
            let defs: Vec<MuID> = all_defined.iter().map(|x| *x).collect();
            (livein, defs)
        };
        let preds: Vec<String> = {
            let mut ret = vec![];
            // predecessors of the first instruction is the predecessors of this block
            for pred in mc.get_preds(start_inst).into_iter() {
                match end_inst_map.get(pred) {
                    Some(str) => ret.push(String::from(*str)),
                    None => {}
                }
            }
            ret
        };
        let succs: Vec<String> = {
            let mut ret = vec![];
            // successors of the last instruction is the successors of this block
            for succ in mc.get_succs(mc.get_last_inst(end).unwrap()).into_iter() {
                match start_inst_map.get(succ) {
                    Some(str) => ret.push(String::from(*str)),
                    None => {}
                }
            }
            ret
        };
        let node = CFGBlockNode {
            block: block.clone(),
            pred: preds,
            succ: succs,
            uses: livein,
            defs: defs
        };
        trace_if!(TRACE_LIVENESS, "as CFGNode {:?}", node);
        ret.insert(block.clone(), node);
    }
    ret
}
fn build_cfg_nodes ( cf : & mut CompiledFunction ) -> LinkedHashMap < MuName , CFGBlockNode > { info ! ( " " ) ; let mc = cf . mc ( ) ; let mut ret = LinkedHashMap :: new ( ) ; let all_blocks = mc . get_all_blocks ( ) ; // create maps (start_inst -> name) and (end_inst -> name) // we will use it to find basic blocks when given a inst index let ( start_inst_map , end_inst_map ) = { let mut start_inst_map : LinkedHashMap < usize , & str > = LinkedHashMap :: new ( ) ; let mut end_inst_map : LinkedHashMap < usize , & str > = LinkedHashMap :: new ( ) ; for block in all_blocks . iter ( ) { let range = match mc . get_block_range ( block ) { Some ( range ) => range , None => panic ! ( " " block ) } ; // start inst let first_inst = range . start ; // last inst (we need to skip symbols) let last_inst = match mc . get_last_inst ( range . end ) { Some ( last ) => last , None => { panic ! ( " \
 " block ) } } ; trace_if ! ( TRACE_LIVENESS " " block first_inst last_inst ) ; start_inst_map . insert ( first_inst , block ) ; end_inst_map . insert ( last_inst , block ) ; } ( start_inst_map , end_inst_map ) } ; // collect info for each basic block for block in mc . get_all_blocks ( ) . iter ( ) { trace_if ! ( TRACE_LIVENESS " " block ) ; let range = mc . get_block_range ( block ) . unwrap ( ) ; let start_inst = range . start ; let end = range . end ; // livein set of this block is what temps this block uses from other blocks // defs is what temps this block defines in the block let ( livein , defs ) = { // we gradually build livein let mut livein = vec ! [ ] ; // we need to know all temporaries defined in the block // if a temporary is not defined in this block, it is a livein for this block let mut all_defined : LinkedHashSet < MuID > = LinkedHashSet :: new ( ) ; for i in start_inst .. end { let reg_uses = mc . get_inst_reg_uses ( i ) ; // if a reg is used but not defined before, it is a live-in for reg in reg_uses { let reg = c ( reg ) ; if ! all_defined . contains ( & reg ) { livein . push ( reg ) ; } } let reg_defs = mc . get_inst_reg_defines ( i ) ; for reg in reg_defs { let reg = c ( reg ) ; all_defined . insert ( reg ) ; } } let defs : Vec < MuID > = all_defined . iter ( ) . map ( | x | * x ) . collect ( ) ; ( livein , defs ) } ; let preds : Vec < String > = { let mut ret = vec ! [ ] ; // predecessors of the first instruction is the predecessors of this block for pred in mc . get_preds ( start_inst ) . into_iter ( ) { match end_inst_map . get ( pred ) { Some ( str ) => ret . push ( String :: from ( * str ) ) , None => { } } } ret } ; let succs : Vec < String > = { let mut ret = vec ! [ ] ; // successors of the last instruction is the successors of this block for succ in mc . get_succs ( mc . get_last_inst ( end ) . unwrap ( ) ) . into_iter ( ) { match start_inst_map . get ( succ ) { Some ( str ) => ret . push ( String :: from ( * str ) ) , None => { } } } ret } ; let node = CFGBlockNode { block : block . clone ( ) , pred : preds , succ : succs , uses : livein , defs : defs } ; trace_if ! ( TRACE_LIVENESS " " node ) ; ret . insert ( block . clone ( ) , node ) ; } ret }
builds a LinkedHashMap from basic block names to CFGBlockNode
We need to collect for each basic block:
 predecessors
 successors
 uses
 defs
builds a LinkedHashMap from basic block names to CFGBlockNode We need to collect for each basic block : predecessors successors uses defs
cf
&mut CompiledFunction
cf
&mut CompiledFunction