':param func:
:param callsites:
:return:'

def _refine_function_arguments(self, func, callsites):

    for (i, c) in enumerate(callsites):
        if (c.simprocedure_name is not None):
            continue
        l.debug('Refining    %s    at    0x%x    (%d/%d).', repr(func), c.addr, i, len(callsites))
        blocks_ahead = [c]
        blocks_after = []
        successors = self.get_successors_and_jumpkind(c, excluding_fakeret=False)
        for (s, jk) in successors:
            if (jk == 'Ijk_FakeRet'):
                blocks_after = [s]
                break
        regs_overwritten = set()
        stack_overwritten = set()
        regs_read = set()
        regs_written = set()
        try:
            path = self.project.factory.path(self.project.factory.blank_state(mode='fastpath', addr=blocks_ahead[0].addr))
            path.step()
            all_successors = (path.next_run.successors + path.next_run.unsat_successors)
            if (not all_successors):
                continue
            suc = all_successors[0]
            se = suc.se
            actions = suc.history.recent_actions
            sp = (se.exactly_int(suc.regs.sp, default=0) + self.project.arch.call_sp_fix)
            for ac in actions:
                if ((ac.type == 'reg') and (ac.action == 'write')):
                    regs_overwritten.add(ac.offset)
                elif ((ac.type == 'mem') and (ac.action == 'write')):
                    addr = se.exactly_int(ac.addr.ast, default=0)
                    if ((self.project.arch.call_pushes_ret and (addr >= (sp + (self.project.arch.bits / 8)))) or ((not self.project.arch.call_pushes_ret) and (addr >= sp))):
                        offset = (addr - sp)
                        stack_overwritten.add(offset)
            func.prepared_registers.add(tuple(regs_overwritten))
            func.prepared_stack_variables.add(tuple(stack_overwritten))
        except (SimError, AngrError):
            pass
        try:
            if blocks_after:
                path = self.project.factory.path(self.project.factory.blank_state(mode='fastpath', addr=blocks_after[0].addr))
                path.step()
                all_successors = (path.next_run.successors + path.next_run.unsat_successors)
                if (not all_successors):
                    continue
                suc = all_successors[0]
                actions = suc.history.recent_actions
                for ac in actions:
                    if ((ac.type == 'reg') and (ac.action == 'read') and (ac.offset not in regs_written)):
                        regs_read.add(ac.offset)
                    elif ((ac.type == 'reg') and (ac.action == 'write')):
                        regs_written.add(ac.offset)
                regs_read = self.project.arch.argument_registers.intersection(regs_read)
                func.registers_read_afterwards.add(tuple(regs_read))
        except (SimError, AngrError):
            pass
