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)
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
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)
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)
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