Beispiel #1
0
def make_int_graph(cfg):
    liveouts = flow.get_lives(cfg)
    g = {}
    for n in cfg.vertices.keys():
        inst = cfg.inst(n)
        if type(inst) != IR:
            continue
        defed = cfg.def_(n)
        uninterfered = [defed]
        if defed is None:
            continue
        if inst.opcode == 'move':
            uninterfered.append(inst.rs)
        if defed.typ != 'virtual':
            continue
        if defed not in g:
            g[defed] = set()
        for reg in liveouts[n]:
            if reg in uninterfered or reg.typ != 'virtual':
                continue
            g[defed].add(reg)
            if reg not in g:
                g[reg] = set()
            g[reg].add(defed)

    return g, liveouts
Beispiel #2
0
 def remove_placeholders(self):
     ''' 
     replace Prolog/Epilog/SaveRegisters/RestoreRegisters with real instructions
     now that we know what registers are used
     '''
     cfg = flow.make_cfg(self.insts)
     outs = flow.get_lives(cfg)
     # t registers that need to be saved
     tregs = []
     for node in sorted(cfg.get_calls()): 
         tregs.append(sorted({reg for reg in outs[node]
             if reg.typ == 't'}))
     space = (max(len(regs) for regs in tregs) * 4
             if len(tregs) > 0
             else 0) 
     t_offset = self.alloc(size=space)
     s_offset = self.alloc(size=len(self.sregs)*4+4)
     # replace prologs/epilogs with stores and loads
     insts = []
     i = 0
     if i < len(tregs):
         regs = tregs[i]
         i += 1
     for inst in self.insts:
         inst_type = type(inst)
         if inst_type == Call:
             store_regs(regs, t_offset, insts)
             insts.append(
                 new_ir('add', rd=REG_SP, rs=REG_SP, rt=grammar.Int(-mulof4(inst.extra))))
             insts.append(new_ir('jal', rs=funcname_to_branch(inst.name), rt=None, rd=None))
             insts.append(
                 new_ir('add', rd=REG_SP, rs=REG_SP, rt=grammar.Int(mulof4(inst.extra))))
             load_regs(regs, t_offset, insts)
             if i < len(tregs):
                 regs = tregs[i]
                 i += 1
         elif inst_type == Prolog:
             # grow stack and store needed s registers
             grow = new_ir('add',
                     rd=REG_SP,
                     rs=REG_SP,
                     rt=grammar.Int(-self.stack_size()))
             insts.extend([
                     new_ir('move', rd=REG_FP, rs=REG_SP, rt=None),
                     grow
                     ])
             store_regs(self.sregs+[REG_RA], s_offset, insts)
         elif inst_type == Epilog:
             # restore used registers
             load_regs(self.sregs+[REG_RA], s_offset, insts)
             shrink = new_ir('add',
                     rd=REG_SP,
                     rs=REG_SP,
                     rt=grammar.Int(self.stack_size()))
             insts.extend([ 
                 shrink,
                 new_ir('jr', rs=Register('ra', None), rt=None, rd=None)
                 ])
         else:
             insts.append(inst)
     self.insts = insts 
Beispiel #3
0
 def remove_placeholders(self):
     ''' 
     replace Prolog/Epilog/SaveRegisters/RestoreRegisters with real instructions
     now that we know what registers are used
     '''
     cfg = flow.make_cfg(self.insts)
     outs = flow.get_lives(cfg)
     # t registers that need to be saved
     tregs = []
     for node in sorted(cfg.get_calls()):
         tregs.append(sorted({reg for reg in outs[node] if reg.typ == 't'}))
     space = (max(len(regs) for regs in tregs) * 4 if len(tregs) > 0 else 0)
     t_offset = self.alloc(size=space)
     s_offset = self.alloc(size=len(self.sregs) * 4 + 4)
     # replace prologs/epilogs with stores and loads
     insts = []
     i = 0
     if i < len(tregs):
         regs = tregs[i]
         i += 1
     for inst in self.insts:
         inst_type = type(inst)
         if inst_type == Call:
             store_regs(regs, t_offset, insts)
             insts.append(
                 new_ir('add',
                        rd=REG_SP,
                        rs=REG_SP,
                        rt=grammar.Int(-mulof4(inst.extra))))
             insts.append(
                 new_ir('jal',
                        rs=funcname_to_branch(inst.name),
                        rt=None,
                        rd=None))
             insts.append(
                 new_ir('add',
                        rd=REG_SP,
                        rs=REG_SP,
                        rt=grammar.Int(mulof4(inst.extra))))
             load_regs(regs, t_offset, insts)
             if i < len(tregs):
                 regs = tregs[i]
                 i += 1
         elif inst_type == Prolog:
             # grow stack and store needed s registers
             grow = new_ir('add',
                           rd=REG_SP,
                           rs=REG_SP,
                           rt=grammar.Int(-self.stack_size()))
             insts.extend(
                 [new_ir('move', rd=REG_FP, rs=REG_SP, rt=None), grow])
             store_regs(self.sregs + [REG_RA], s_offset, insts)
         elif inst_type == Epilog:
             # restore used registers
             load_regs(self.sregs + [REG_RA], s_offset, insts)
             shrink = new_ir('add',
                             rd=REG_SP,
                             rs=REG_SP,
                             rt=grammar.Int(self.stack_size()))
             insts.extend([
                 shrink,
                 new_ir('jr', rs=Register('ra', None), rt=None, rd=None)
             ])
         else:
             insts.append(inst)
     self.insts = insts