Add SSA version of the IR
    Args:
        function
        all_state_variables_instances

def add_ssa_ir(function, all_state_variables_instances):
    '''
        Add SSA version of the IR
    Args:
        function
        all_state_variables_instances
    '''

    if not function.is_implemented:
        return

    init_definition = dict()
    for v in function.parameters:
        if v.name:
            init_definition[v.name] = (v, function.entry_point)
            function.entry_point.add_ssa_ir(Phi(LocalIRVariable(v), set()))

    for v in function.returns:
        if v.name:
            init_definition[v.name] = (v, function.entry_point)

    # We only add phi function for state variable at entry node if
    # The state variable is used
    # And if the state variables is written in another function (otherwise its stay at index 0)
    for (_, variable_instance) in all_state_variables_instances.items():
        if is_used_later(function.entry_point, variable_instance):
            # rvalues are fixed in solc_parsing.declaration.function
            function.entry_point.add_ssa_ir(Phi(StateIRVariable(variable_instance), set()))

    add_phi_origins(function.entry_point, init_definition, dict())


    for node in function.nodes:
        for (variable, nodes) in node.phi_origins_local_variables.values():
            if len(nodes)<2:
                continue
            if not is_used_later(node, variable):
                continue
            node.add_ssa_ir(Phi(LocalIRVariable(variable), nodes))
        for (variable, nodes) in node.phi_origins_state_variables.values():
            if len(nodes)<2:
                continue
            #if not is_used_later(node, variable.name, []):
            #    continue
            node.add_ssa_ir(Phi(StateIRVariable(variable), nodes))

    init_local_variables_instances = dict()
    for v in function.parameters:
        if v.name:
            new_var = LocalIRVariable(v)
            function.add_parameter_ssa(new_var)
            if new_var.is_storage:
                fake_variable = LocalIRVariable(v)
                fake_variable.name = 'STORAGE_'+fake_variable.name
                fake_variable.set_location('reference_to_storage')
                new_var.refers_to = {fake_variable}
                init_local_variables_instances[fake_variable.name] = fake_variable
            init_local_variables_instances[v.name] = new_var

    for v in function.returns:
        if v.name:
            new_var = LocalIRVariable(v)
            function.add_return_ssa(new_var)
            if new_var.is_storage:
                fake_variable = LocalIRVariable(v)
                fake_variable.name = 'STORAGE_'+fake_variable.name
                fake_variable.set_location('reference_to_storage')
                new_var.refers_to = {fake_variable}
                init_local_variables_instances[fake_variable.name] = fake_variable
            init_local_variables_instances[v.name] = new_var

    all_init_local_variables_instances = dict(init_local_variables_instances)

    init_state_variables_instances = dict(all_state_variables_instances)

    initiate_all_local_variables_instances(function.nodes, init_local_variables_instances, all_init_local_variables_instances)

    generate_ssa_irs(function.entry_point,
                     dict(init_local_variables_instances),
                     all_init_local_variables_instances,
                     dict(init_state_variables_instances),
                     all_state_variables_instances,
                     init_local_variables_instances,
                     [])

    fix_phi_rvalues_and_storage_ref(function.entry_point,
                                    dict(init_local_variables_instances),
                                    all_init_local_variables_instances,
                                    dict(init_state_variables_instances),
                                    all_state_variables_instances,
                                    init_local_variables_instances)