Exemple #1
0
def setMemInsnIG(line, defs, uses):
    regToSave = line[5][-1][1]
    #print("SET MEM " " " + str(regToSave))
    uses = addtouses(regToSave, defs, uses)
    iUses = []
    if regToSave != 100:
        iUses.append(regToSave)
    return cf.Insn([], iUses)
Exemple #2
0
def parseRTLtoIG(rtlFileName, numVirtRegs):
    rtlInput = readRTL(rtlFileName)
    lineCount = 0
    mapTable = {}
    defs = set()
    uses = set()
    neighbors = set()
    insns = []
    curbb = 1
    VertList = []
    #print(rtlInput)
    for line in rtlInput:
        if type(line) == list:
            if line[0] == 'insn':
                if line[4] != curbb:
                    if curbb == 1:
                        curbb = line[4]
                        if line[5][0] == 'set':
                            if 'reg' in line[5][1][0]:
                                insns.append(setRegInsnIG(line, defs, uses))
                            elif 'mem' in line[5][1][0]:
                                insns.append(setMemInsnIG(line, defs, uses))
                        continue
                    neighbors.add(line[4])
                    VertList.append(
                        cf.BasicBlock(curbb, defs, uses, neighbors, insns,
                                      numVirtRegs))
                    defs = set()
                    uses = set()
                    neighbors = set()
                    insns = []
                    curbb = line[4]
                if line[5][0] == 'set':
                    if 'reg' in line[5][1][0]:
                        insns.append(setRegInsnIG(line, defs, uses))
                    elif 'mem' in line[5][1][0]:
                        insns.append(setMemInsnIG(line, defs, uses))
            elif line[0] == 'jump_insn':
                jumpInsnIG(rtlFileName, line, neighbors)
            elif line[0] == 'code_label':
                mybb = getbasicblocknum(rtlFileName, line[1])
                neighbors.add(mybb)
            elif line[0] == 'call_insn':
                insns.append(cf.Insn([0, 1, 2, 3], []))

    VertList.append(
        cf.BasicBlock(curbb, defs, uses, neighbors, insns, numVirtRegs))
    return VertList
Exemple #3
0
def setRegInsnIG(line, defs, uses):
    regnum = line[5][1][1]
    iDefs = []
    iUses = []
    if 'mem' in line[5][2][0]:
        if 'virtual' in line[5][2][1][1][2]:
            uses = addtouses(line[5][2][1][1][1], defs, uses)
            iUses.append(line[5][2][1][1][1])
    elif ('plus' in line[5][2][0] or 'minus' in line[5][2][0]
          or 'mult' in line[5][2][0]):
        arg1 = line[5][2][1][1]
        if 'const_int' in str(line[5][2]):
            uses = addtouses(arg1, defs, uses)
            iUses.append(arg1)
        else:
            arg2 = line[5][2][2][1]
            uses = addtouses(arg1, defs, uses)
            uses = addtouses(arg2, defs, uses)
            iUses.append(arg1)
            iUses.append(arg2)
    elif 'reg' in line[5][2][0]:
        uses = addtouses(line[5][2][1], defs, uses)
        iUses.append(line[5][2][1])
        #if ("<retval>" in str(line[5][2])):
        #   uses = addtouses(line[5][2][1], defs, uses)
        #  iUses.append(line[5][2][1])
    elif ("compare" in line[5][2][0]):
        uses = addtouses(line[5][2][1][1], defs, uses)
        iUses.append(line[5][2][1][1])
        if ("const_int" not in line[5][2][2][0]):  # if constant
            uses = addtouses(line[5][2][2][1], defs, uses)
            iUses.append(line[5][2][2][1])
    if regnum != 100:
        defs.add(regnum)
        iDefs.append(regnum)
    if 100 in iUses:
        iUses.remove(100)
    return cf.Insn(iDefs, iUses)
Exemple #4
0
def main():
    numVirtRegs = 5
    cfg = controlFlowGraph.CFG(numVirtRegs)
    bb0 = controlFlowGraph.BasicBlock(numVirtRegs)
    bb1 = controlFlowGraph.BasicBlock(numVirtRegs)
    bb2 = controlFlowGraph.BasicBlock(numVirtRegs)
    bb3 = controlFlowGraph.BasicBlock(numVirtRegs)

    # no spill a
    i0 = controlFlowGraph.Insn([106], [105])
    i1 = controlFlowGraph.Insn([105], [])
    bb0.insns.append(i0)
    bb0.insns.append(i1)
    i2 = controlFlowGraph.Insn([], [107])
    i3 = controlFlowGraph.Insn([108], [106, 107])
    i4 = controlFlowGraph.Insn([107], [])
    bb1.insns.append(i2)
    bb1.insns.append(i3)
    bb1.insns.append(i4)
    i5 = controlFlowGraph.Insn([], [109])
    i6 = controlFlowGraph.Insn([108], [109, 106])
    i7 = controlFlowGraph.Insn([109], [])
    bb2.insns.append(i5)
    bb2.insns.append(i6)
    bb2.insns.append(i7)
    i8 = controlFlowGraph.Insn([], [105, 108])
    i9 = controlFlowGraph.Insn([], [105, 108])
    bb3.insns.append(i8)
    bb3.insns.append(i9)

    # spill a
    # i0 = controlFlowGraph.Insn([106], [110])
    # i1 = controlFlowGraph.Insn([110], [])
    # bb0.insns.append(i0)
    # bb0.insns.append(i1)
    # i2 = controlFlowGraph.Insn([], [107])
    # i3 = controlFlowGraph.Insn([108], [106, 107])
    # i4 = controlFlowGraph.Insn([107], [])
    # bb1.insns.append(i2)
    # bb1.insns.append(i3)
    # bb1.insns.append(i4)
    # i5 = controlFlowGraph.Insn([], [109])
    # i6 = controlFlowGraph.Insn([108], [109, 106])
    # i7 = controlFlowGraph.Insn([109], [])
    # bb2.insns.append(i5)
    # bb2.insns.append(i6)
    # bb2.insns.append(i7)
    # i8 = controlFlowGraph.Insn([], [111, 108])
    # i9 = controlFlowGraph.Insn([], [111, 108])
    # i10 = controlFlowGraph.Insn([111], []) # add def when find a use of a spilled register
    # bb3.insns.append(i8)
    # bb3.insns.append(i9)
    # bb3.insns.append(i10)
    cfg.blocks.append(bb0)
    cfg.blocks.append(bb1)
    cfg.blocks.append(bb2)
    cfg.blocks.append(bb3)

    edges = [[0 for x in range(4)] for y in range(4)]
    edges[0][1] = 1
    edges[0][2] = 1
    edges[1][3] = 1
    edges[2][3] = 1
    cfg.edges = edges

    print("STEP 1: Performing Live Variable Analysis...")
    liveVariableAnalysis.livenessAnalysis(cfg)
    print("STEP 2: Building Interference Graph...")
    ig = interferenceGraph.buildInterferenceGraph(cfg)

    print("\nInterference Graph")
    for i in range(len(ig)):
        print(ig[i])

    print("\nSTEP 3: Coloring Graph...")
    colors = graphColorizer.colorGraph(cfg, ig)
    print("\nColors: ")
    print(colors)
Exemple #5
0
def spill(cfg):

    # get values from the cfg to use/check
    spillTable = cfg.spillTable
    spilledList = cfg.spilledList
    spilledToList = []

    # determine register to spill
    registerToSpill = -1
    for i in range(105, 105 + cfg.originalNumVirtRegs):
        if (i not in spilledList):
            registerToSpill = i
            spilledList.append(registerToSpill)
            break

    # if out of registers to spill
    if (registerToSpill == -1):
        print("Current Spill Table")
        for key in spillTable.keys():
            print("Key: {} Value: {}".format(key, spillTable[key]))
        print(
            "Error: Spilled all possible registers, not possible with current amount of colors allowed."
        )
        exit()

    # determine the new register to spill to
    newSpillReg = cfg.numVirtRegs + 105

    # substitute all the appearances of the register that you want to spill with the register that you want to spill to
    for block in cfg.blocks:
        k = 0
        while k < len(block.insns):
            insn = block.insns[k]
            replaced = False

            # go through defs and check if need to substitute
            for i in range(len(insn.defs)):
                if (insn.defs[i] == registerToSpill):
                    insn.defs[i] = newSpillReg
                    replaced = True

            # go through uses and check if need to substitute
            for i in range(len(insn.uses)):
                if (insn.uses[i] == registerToSpill):
                    insn.uses[i] = newSpillReg
                    replaced = True
                    # insert the "store instruction" as the definition
                    newSpillRegList = []
                    newSpillRegList.append(newSpillReg)
                    newLoadInsn = controlFlowGraph.Insn(newSpillRegList, [])
                    block.insns.insert(k, newLoadInsn)

            # if anything was replaced, update the spilled to list, and move the register number to the next available one
            if (replaced):
                spilledToList.append(newSpillReg)
                newSpillReg += 1
            k += 1

    # register doesn't spill to anything bc not being used
    if (len(spilledToList) == 0):
        cfg.spilledList = spilledList
        return spill(cfg)

    # update the spill table
    spillTable[registerToSpill] = spilledToList

    # update the fields in the cfg
    cfg.numVirtRegs = cfg.numVirtRegs + len(spilledToList)
    cfg.spillTable = spillTable
    cfg.spilledList = spilledList

    # update the size of the live ins and live outs to account for the new spilled registers
    for block in cfg.blocks:
        block.liveIns = [0] * (cfg.numVirtRegs + 4)
        block.liveOuts = [0] * (cfg.numVirtRegs + 4)

    return cfg