You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: ssa.rs
    path of file: ./repos/panopticon/data-flow/src
    
    the code of the file until where you have to start completion: /*
 * Panopticon - A libre disassembler
 * Copyright (C) 2017  Panopticon authors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

use crate::liveness_sets;
use panopticon_core::{ControlFlowEdge, ControlFlowGraph, ControlFlowRef, ControlFlowTarget, Function, Guard, Lvalue, Mnemonic, Operation, Result, Rvalue,
                      Statement};
use panopticon_graph_algos::{BidirectionalGraphTrait, EdgeListGraphTrait, GraphTrait, IncidenceGraphTrait, MutableGraphTrait, VertexListGraphTrait};
use panopticon_graph_algos::dominator::{dominance_frontiers, immediate_dominator};
use std::borrow::Cow;
use std::cmp::max;
use std::collections::{HashMap, HashSet};
use std::iter::FromIterator;

/// Does a simple sanity check on all RREIL statements in `func`, returns every variable name
/// found and its maximal size in bits.
pub fn type_check(func: &Function) -> Result<HashMap<Cow<'static, str>, usize>> {
    let mut ret = HashMap::<Cow<'static, str>, usize>::new();
    let cfg = func.cfg();
    fn set_len(v: &Rvalue, ret: &mut HashMap<Cow<'static, str>, usize>) {
        match v {
            &Rvalue::Variable { ref name, ref size, .. } => {
                let val = *max(ret.get(name).unwrap_or(&0), size);
                ret.insert(name.clone(), val);
            }
            _ => {}
        }
    }

    for vx in cfg.vertices() {
        if let Some(&ControlFlowTarget::Resolved(ref bb)) = cfg.vertex_label(vx) {
            for mne in bb.mnemonics.iter() {
                for o in mne.operands.iter() {
                    set_len(o, &mut ret);
                }

                for instr in mne.instructions.iter() {
                    let ops = instr.op.operands();
                    match ops.len() {
                        0 => return Err("Operation w/o arguments".into()),
                        _ => {
                            for o in ops.iter() {
                                set_len(o, &mut ret);
                            }
                        }
                    }

                    set_len(&instr.assignee.clone().into(), &mut ret);
                }
            }
        }
    }

    for ed in cfg.edges() {
        if let Some(&Guard::Predicate { ref flag, .. }) = cfg.edge_label(ed) {
            set_len(flag, &mut ret);
        }
    }

    Ok(ret)
}

/// Computes the set of gloable variables in `func` and their points of usage. Globales are
/// variables that are used in multiple basic blocks. Returns (Globals,Usage).
pub fn global_names(func: &Function) -> (HashSet<Cow<'static, str>>, HashMap<Cow<'static, str>, HashSet<ControlFlowRef>>) {
    let (varkill, uevar) = liveness_sets(func);
    let mut usage = HashMap::<Cow<'static, str>, HashSet<ControlFlowRef>>::new();
    let mut globals = HashSet::<Cow<'static, str>>::new();

    for (_, uev) in uevar {
        for v in uev {
            globals.insert(v);
        }
    }

    for (vx, vk) in varkill {
        for v in vk {
            usage.entry(v.clone()).or_insert(HashSet::new()).insert(vx);
        }
    }

    (globals, usage)
}

/// Inserts SSA Phi functions at junction points in the control flow graph of `func`. The
/// algorithm produces the semi-pruned SSA form found in Cooper, Torczon: "Engineering a Compiler".
pub fn phi_functions(func: &mut Fu
    
pub fn rename_variables(func: &mut Function) -> Result<()> {
    let (globals, _) = global_names(func);
    let mut stack = HashMap::<Cow<'static, str>, Vec<usize>>::from_iter(globals.iter().map(|x| (x.clone(), Vec::new())));
    let mut counter = HashMap::<Cow<'static, str>, usize>::new();
    let idom = immediate_dominator(func.entry_point_ref(), func.cfg());

    if idom.len() != func.cfg().num_vertices() {
        return Err("No all basic blocks are reachable from function entry point".into());
    }

    fn new_name(n: &Cow<'static, str>, counter: &mut HashMap<Cow<'static, str>, usize>, stack: &mut HashMap<Cow<'static, str>, Vec<usize>>) -> usize {
        let i = *counter.entry(n.clone()).or_insert(0);

        counter.get_mut(n).map(|x| *x += 1);
        stack.entry(n.clone()).or_insert(Vec::new()).push(i);

        i
    }
    fn rename(
        b: ControlFlowRef,
        counter: &mut HashMap<Cow<'static, str>, usize>,
        stack: &mut HashMap<Cow<'static, str>, Vec<usize>>,
        cfg: &mut ControlFlowGraph,
        idom: &HashMap<ControlFlowRef, ControlFlowRef>,
    ) -> Result<()> {
        if let Some(&mut ControlFlowTarget::Resolved(ref mut bb)) = cfg.vertex_label_mut(b) {
            bb.rewrite(
                |i| match i {
                    &mut Statement {
                        op: Operation::Phi(_),
                        assignee: Lvalue::Variable { ref name, ref mut subscript, .. },
                    } => *subscript = Some(new_name(name, counter, stack)),
                    _ => {}
                }
            );

            for mne in bb.mnemonics.iter_mut() {
                if mne.opcode != "__phi" {
                    for o in mne.operands.iter_mut() {
                        if let &mut Rvalue::Variable { ref name, ref mut subscript, .. } = o {
                            *subscript = stack.get(name).and_then(|x| x.last()).cloned();
                        }
                    }

                    for i in mne.instructions.iter_mut() {
                        let &mut Statement { ref mut op, ref mut assignee } = i;

                        if let &mut Operation::Phi(_) = op {
                            return Err("Phi instruction outside __phi mnemonic".into());
                        } else {
                            for o in op.operands_mut() {
                                if let &mut Rvalue::Variable { ref name, ref mut subscript, .. } = o {
                                    *subscript = stack[name].last().cloned();
                                }
                            }

                            if let &mut Lvalue::Variable { ref name, ref mut subscript, .. } = assignee {
                                *subscript = Some(new_name(name, counter, stack));
                            }
                        }
                    }
                }
            }
        }

        let mut succ = cfg.out_edges(b).collect::<Vec<_>>();
        succ.sort();

        for s in succ {
            if let Some(&mut Guard::Predicate { flag: Rvalue::Variable { ref name, ref mut subscript, .. }, .. }) = cfg.edge_label_mut(s) {
                *subscript = stack[name].last().cloned();
            }

            let v = cfg.target(s);
            match cfg.vertex_label_mut(v) {
                Some(&mut ControlFlowTarget::Resolved(ref mut bb)) => {
                    bb.rewrite(
                        |i| match i {
                            &mut Statement { op: Operation::Phi(ref mut ops), .. } => {
                                for o in ops.iter_mut() {
                                    if let &mut Rvalue::Variable { ref name, ref mut subscript, .. } = o {
                                        if subscript.is_none() {
                                            *subscript = stack[name].last().cloned();
                                            break;
                                        }
                                    }
                                }
                            }
                            _ => {}
                        }
                    );
                }
                Some(&mut ControlFlowTarget::Unresolved(Rvalue::Variable { ref name, ref mut subscript, .. })) => *subscript = stack[name].last().cloned(),
                _ => {}
            }
        }

        for (k, _) in idom.iter().filter(|&(_, &v)| v == b) {
            if *k != b {
                rename(*k, counter, stack, cfg, idom)?;
            }
        }

        if let Some(&mut ControlFlowTarget::Resolved(ref mut bb)) = cfg.vertex_label_mut(b) {
            bb.execute(
                |i| match i {
                    &Statement { assignee: Lvalue::Variable { ref name, .. }, .. } => {
                        stack.get_mut(name).map(|x| x.pop());
                    }
                    _ => {}
                }
            );
        }

        Ok(())
    }

    rename(
        func.entry_point_ref(),
        &mut counter,
        &mut stack,
        func.cfg_mut(),
        &idom,
    )
}