Skip to content
Browse files

added reg_allocator

  • Loading branch information...
1 parent c1f3629 commit a6afd89c64bd5f9ee98c2c7c7e270c51ab2006a6 @cantora committed
Showing with 125 additions and 6 deletions.
  1. +13 −1 analyze_test.py
  2. +5 −1 pyc
  3. +26 −4 pyc_asm_nodes.py
  4. +81 −0 pyc_reg_allocator.py
View
14 analyze_test.py 100644 → 100755
@@ -1,5 +1,7 @@
+#!/usr/bin/env python
import pyc_var_analyzer
from pyc_asm_nodes import *
+import pyc_reg_allocator
asm_list = [
Mov(Immed(Int(4)), Var("z")),
@@ -20,4 +22,14 @@
graph = pyc_var_analyzer.to_intf_graph(live_list)
-print "graph:\n\t%s" % "\n\t".join(["%s: %s" % (repr(k), repr(v)) for (k,v) in graph.items()])
+print "graph:\n\t%s" % "\n\t".join(["%s: %s" % (repr(k), repr(v)) for (k,v) in graph.items()])
+
+memallocs = pyc_reg_allocator.alloc(live_list, graph)
+
+print "mem allocation offsets:\n\t%s" % "\n\t".join(["%s: %s" % (repr(k), repr(v)) for (k,v) in memallocs.items()])
+
+print "mem allocations:\n\t%s" % "\n\t".join(["%s: %s" % (repr(k), repr(pyc_reg_allocator.index_to_loc(v))) for (k,v) in memallocs.items()])
+
+patched_asm_list = pyc_reg_allocator.patch(asm_list, memallocs)
+
+print "patched asm list:\n\t%s" % "\n\t".join([("%s" % repr(x) ) for x in patched_asm_list])
View
6 pyc
@@ -5,6 +5,8 @@ import sys
import pyc_ast
import pyc_asm_list
import pyc_var_analyzer
+import pyc_reg_allocator
+
from pyc_log import *
import os.path
@@ -65,7 +67,9 @@ def run(options):
for n in asm_list:
log(repr(n))
- pyc_var_analyzer.interference_graph(asm_list)
+ live_list, graph = pyc_var_analyzer.interference_graph(asm_list)
+
+ pyc_reg_allocator.alloc(live_list, graph)
exit()
insns = []
View
30 pyc_asm_nodes.py
@@ -8,7 +8,7 @@ def __init__(self, *args):
def __repr__(self):
tup = tuple([self.__class__.__name__] + [repr(x) for x in self.con_args])
- arg_fmt = ", ".join(["%s" for x in self.con_args])
+ arg_fmt = ", ".join(["%s" for x in range(0, len(self.con_args) )])
fmt = "%%s(%s)" % arg_fmt
return fmt % tup
@@ -53,7 +53,7 @@ def __init__(self, *args):
AsmNode.__init__(self, *args)
self.operand_props = {}
-
+
def new_operand(self, name, operand, mode):
if mode not in self.op_modes.keys():
raise Exception("invalid operand mode: %s" % repr(mode))
@@ -62,10 +62,13 @@ def new_operand(self, name, operand, mode):
setattr(self, name, operand)
def get_operand(self, name):
- return self.op_modes[self.operand_props[name]](self.__dict__[name])
+ return self.op_modes[self.operand_props[name]](self.get_operand_node(name))
+
+ def get_operand_node(self, name):
+ return self.__dict__[name]
def operand_names(self):
- return self.operand_props.keys()
+ return reversed(self.operand_props.keys())
def read_operand(self, name, asm_node):
self.new_operand(name, asm_node, 'r')
@@ -79,6 +82,9 @@ def read_write_operand(self, name, asm_node):
def operands(self):
return [self.get_operand(name) for name in self.operand_names()]
+ def operand_nodes(self):
+ return [self.get_operand_node(name) for name in self.operand_names()]
+
def inst_join(self, list):
return self.asm_tab.join(list)
@@ -100,6 +106,22 @@ def writes(self):
def reads(self):
return [op.asm_node for op in self.read_operands() + self.read_write_operands()]
+ def patch_vars(self, fn_to_mem_loc):
+ args = []
+
+ for name in self.operand_names():
+ #print name
+ asm_node = self.get_operand_node(name)
+ if not isinstance(asm_node, Var):
+ args.append(asm_node)
+ continue
+
+ #print("patch op %s" % repr(name))
+ args.append(fn_to_mem_loc(asm_node) )
+
+ return self.__class__(*args)
+
+
"""
def sub_loc_for_var(self, mem_map):
if isinstance(self.src, Var):
View
81 pyc_reg_allocator.py
@@ -0,0 +1,81 @@
+from pyc_var_analyzer import IntfGraph
+from pyc_log import *
+from pyc_asm_nodes import *
+import random
+import copy
+
+caller_save = [
+ "ecx",
+ "edx",
+ "eax"
+]
+
+callee_save = [
+ "ebx",
+ "esi",
+ "edi"
+]
+
+registers = callee_save + caller_save
+
+def index_to_loc(index):
+ global registers
+
+ if index < 0:
+ raise Exception("invalid index %d" % index)
+ elif index < len(registers):
+ return Register(registers[index])
+ else:
+ return EBPIndirect(index - len(registers) )
+
+
+def alloc(live_list, graph):
+ global registers
+ mem_map = {}
+ todo = set(graph.keys())
+
+ #registers are like variables for which me must allocate
+ #themselves
+ for i in range(0, len(registers)):
+ mem_map[Register(registers[i])] = i
+
+ while len(todo) > 0:
+ constraints = {}
+
+ log("todo: %s" % repr(todo))
+
+ for node in todo:
+ constraints[node] = set([])
+ log(" find constraints on %s" % repr(node) )
+ for neighbor in graph[node]:
+ n_loc = mem_map.get(neighbor, None)
+ log(" reg for neighbor %s: %s" % (repr(neighbor), repr(n_loc) ) )
+ if not n_loc is None:
+ constraints[node].add(n_loc)
+
+ sorted_nodes = sorted(constraints.keys(), key = lambda k: len(graph[k]), reverse = True)
+ log("allocate memory for %s" % repr(sorted_nodes[0]) )
+ i = 0
+ while i in constraints[sorted_nodes[0]]:
+ i = i+1
+
+ mem_map[sorted_nodes[0]] = i
+ log(" allocated %d" % i)
+
+ todo.remove(sorted_nodes[0])
+
+
+ return mem_map
+
+
+def patch(asm_list, mem_map):
+ result = []
+
+ for ins in asm_list:
+ #log("set locs in %s" % repr(ins))
+ new_ins = ins.patch_vars(lambda node: index_to_loc(mem_map[node]) )
+
+ #log(" patched: %s" % repr(new_ins) )
+ result.append(new_ins)
+
+ return result

0 comments on commit a6afd89

Please sign in to comment.
Something went wrong with that request. Please try again.