changeset 270:cdc76d183bcc

first register allocator
author Windel Bouwman
date Mon, 19 Aug 2013 21:14:28 +0200
parents 5f8c04a8d26b
children cf7d5fb7d9c8
files python/codegenarm.py python/graph.py python/ir/function.py python/irmach.py python/registerallocator.py
diffstat 5 files changed, 56 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/python/codegenarm.py	Sun Aug 18 17:43:18 2013 +0200
+++ b/python/codegenarm.py	Mon Aug 19 21:14:28 2013 +0200
@@ -3,7 +3,6 @@
 from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo
 import cortexm3 as arm
 from ppci import CompilerError
-import graph
 import flowgraph
 import registerallocator
 from instructionselector import InstructionSelector
@@ -100,9 +99,20 @@
         self.outs.getSection('code').address = 0x08000000
         self.outs.getSection('data').address = 0x20000000
 
+    def useUnused(self, inslist):
+        # Use unused temporaries at the end of the list
+        defTemps = []
+        for d in (i.dst for i in inslist):
+            print(d)
+            defTemps.append(d)
+        useTemps = [d for d in ([i.src] for i in inslist)]
+        print(defTemps)
+        print(useTemps)
+
     def generate(self, ircode, cfg_file=None, ig_file=None):
-        x = self.ins_sel.munchProgram(ircode)
-        cfg = flowgraph.FlowGraph(x)
+        ir2 = self.ins_sel.munchProgram(ircode)
+        self.useUnused(ir2)
+        cfg = flowgraph.FlowGraph(ir2)
         if cfg_file:
             cfg.to_dot(cfg_file)
         ig = registerallocator.InterferenceGraph(cfg)
@@ -111,6 +121,12 @@
 
         regs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7']
         ra = registerallocator.RegisterAllocator()
-        ra.registerAllocate(ig, regs)
+        regMap = ra.registerAllocate(ig, regs)
+        print(regMap)
+        for i in ir2:
+            i.src = tuple(regMap[t] for t in i.src)
+            i.dst = tuple(regMap[t] for t in i.dst)
+            print(i)
 
 
+
--- a/python/graph.py	Sun Aug 18 17:43:18 2013 +0200
+++ b/python/graph.py	Mon Aug 19 21:14:28 2013 +0200
@@ -43,3 +43,8 @@
         self.succ = []
         self.pred = []
 
+    @property
+    def Adj(self):
+        return set(self.succ) | set(self.pred)
+
+
--- a/python/ir/function.py	Sun Aug 18 17:43:18 2013 +0200
+++ b/python/ir/function.py	Mon Aug 19 21:14:28 2013 +0200
@@ -28,7 +28,8 @@
                     bbs.append(sb)
                     worklist.append(sb)
         bbs.remove(self.entry)
-        bbs.remove(self.epiloog)
+        if self.epiloog in bbs:
+            bbs.remove(self.epiloog)
         bbs.insert(0, self.entry)
         bbs.append(self.epiloog)
         return bbs
--- a/python/irmach.py	Sun Aug 18 17:43:18 2013 +0200
+++ b/python/irmach.py	Mon Aug 19 21:14:28 2013 +0200
@@ -1,6 +1,10 @@
 
 """
-  Abstract assembly language instructions
+  Abstract assembly language instructions.
+
+  This is the second intermediate representation.
+  
+  Instructions are selected and scheduled at this stage.
 """
 
 
--- a/python/registerallocator.py	Sun Aug 18 17:43:18 2013 +0200
+++ b/python/registerallocator.py	Mon Aug 19 21:14:28 2013 +0200
@@ -62,11 +62,31 @@
     """ Target independent register allocator """
     def registerAllocate(self, ig, regs):
         """ Color the given interference graph with the provided registers """
-        self.regMap = {}
-        # TODO: implement ;)
+        regMap = {}
         regs = set(regs)
-        for n in ig.nodes:
-            print(n)
+        K = len(regs)
+        allvars = list(ig.nodes)
+
+        # Chaitin's algorithm:
+        # remove all nodes that have less than K neighbours:
+        worklist = []
+        while allvars:
+            less_k = [n for n in allvars if len(n.Adj - set(worklist)) < K]
+            if not less_k:
+                raise NotImplementedError('Spilling not implemented')
+            n = less_k[0]
+            worklist.append(n)
+            allvars.remove(n)
+
+        # Add nodes back to the graph: 
+        while worklist:
+            n = worklist.pop(-1)
+            adj = n.Adj - set(worklist)
+            possibleregs = set(regs) - set(regMap[n.varname] for n in adj)
+            regMap[n.varname] = list(possibleregs)[0]
+        # We have a register mapping!
+        #print(self.regMap)
+        return regMap
 
         # TODO: implement spilling
         # TODO: implement coalescing