fn insert_phi_nodes(function: &mut il::Function) -> Result<()> {
    let cfg = function.control_flow_graph();
    let entry = cfg.entry().ok_or("CFG entry must be set")?;

    let dominance_frontiers = cfg.graph().compute_dominance_frontiers(entry)?;
    let non_local_scalars = compute_non_local_scalars(cfg);

    for (scalar, defs) in scalars_mutated_in_blocks(cfg) {
        if !non_local_scalars.contains(&scalar) {
            continue; // ignore local scalars
        }

        let mut phi_insertions: HashSet<usize> = HashSet::new();
        let mut queue: VecDeque<usize> = defs.iter().cloned().collect();
        while let Some(block_index) = queue.pop_front() {
            for df_index in &dominance_frontiers[&block_index] {
                if phi_insertions.contains(df_index) {
                    continue;
                }

                let phi_node = {
                    let mut phi_node = il::PhiNode::new(scalar.clone());
                    let cfg = function.control_flow_graph();
                    for predecessor in cfg.predecessor_indices(*df_index)? {
                        phi_node.add_incoming(scalar.clone(), predecessor);
                    }
                    if *df_index == entry {
                        phi_node.set_entry_scalar(scalar.clone());
                    }
                    phi_node
                };

                let cfg = function.control_flow_graph_mut();
                let df_block = cfg.block_mut(*df_index)?;
                df_block.add_phi_node(phi_node);

                phi_insertions.insert(*df_index);

                if !defs.contains(df_index) {
                    queue.push_back(*df_index);
                }
            }
        }
    }

    Ok(())
}
/// Inserts phi nodes where necessary.
///
/// Implements the algorithm for constructing Semi-Pruned SSA form,
/// see Algorithm 3.1 in "SSA-based Compiler Design" book for more details.
Inserts phi nodes where necessary.
Implements the algorithm for constructing Semi-Pruned SSA form,
see Algorithm 3.1 in "SSA-based Compiler Design" book for more details.
Inserts phi nodes where necessary . Implements the algorithm for constructing Semi - Pruned SSA form see Algorithm 3 . 1 in " SSA - based Compiler Design " book for more details .
fn insert_phi_nodes(function: &mut il::Function) -> Result<()> {
    let cfg = function.control_flow_graph();
    let entry = cfg.entry().ok_or("CFG entry must be set")?;
    let dominance_frontiers = cfg.graph().compute_dominance_frontiers(entry)?;
    let non_local_scalars = compute_non_local_scalars(cfg);
    for (scalar, defs) in scalars_mutated_in_blocks(cfg) {
        if !non_local_scalars.contains(&scalar) {
            continue; // ignore local scalars
        }
        let mut phi_insertions: HashSet<usize> = HashSet::new();
        let mut queue: VecDeque<usize> = defs.iter().cloned().collect();
        while let Some(block_index) = queue.pop_front() {
            for df_index in &dominance_frontiers[&block_index] {
                if phi_insertions.contains(df_index) {
                    continue;
                }
                let phi_node = {
                    let mut phi_node = il::PhiNode::new(scalar.clone());
                    let cfg = function.control_flow_graph();
                    for predecessor in cfg.predecessor_indices(*df_index)? {
                        phi_node.add_incoming(scalar.clone(), predecessor);
                    }
                    if *df_index == entry {
                        phi_node.set_entry_scalar(scalar.clone());
                    }
                    phi_node
                };
                let cfg = function.control_flow_graph_mut();
                let df_block = cfg.block_mut(*df_index)?;
                df_block.add_phi_node(phi_node);
                phi_insertions.insert(*df_index);
                if !defs.contains(df_index) {
                    queue.push_back(*df_index);
                }
            }
        }
    }
    Ok(())
}
fn insert_phi_nodes ( function : & mut il :: Function ) -> Result < ( ) > { let cfg = function . control_flow_graph ( ) ; let entry = cfg . entry ( ) . ok_or ( " " ) ? ; let dominance_frontiers = cfg . graph ( ) . compute_dominance_frontiers ( entry ) ? ; let non_local_scalars = compute_non_local_scalars ( cfg ) ; for ( scalar , defs ) in scalars_mutated_in_blocks ( cfg ) { if ! non_local_scalars . contains ( & scalar ) { continue ; // ignore local scalars } let mut phi_insertions : HashSet < usize > = HashSet :: new ( ) ; let mut queue : VecDeque < usize > = defs . iter ( ) . cloned ( ) . collect ( ) ; while let Some ( block_index ) = queue . pop_front ( ) { for df_index in & dominance_frontiers [ & block_index ] { if phi_insertions . contains ( df_index ) { continue ; } let phi_node = { let mut phi_node = il :: PhiNode :: new ( scalar . clone ( ) ) ; let cfg = function . control_flow_graph ( ) ; for predecessor in cfg . predecessor_indices ( * df_index ) ? { phi_node . add_incoming ( scalar . clone ( ) , predecessor ) ; } if * df_index == entry { phi_node . set_entry_scalar ( scalar . clone ( ) ) ; } phi_node } ; let cfg = function . control_flow_graph_mut ( ) ; let df_block = cfg . block_mut ( * df_index ) ? ; df_block . add_phi_node ( phi_node ) ; phi_insertions . insert ( * df_index ) ; if ! defs . contains ( df_index ) { queue . push_back ( * df_index ) ; } } } } Ok ( ( ) ) }
Inserts phi nodes where necessary.
Inserts phi nodes where necessary .
function
&mut il::Function
function
&mut il::Function