Jayke Meijer 14 лет назад
Родитель
Сommit
a2133db3c7
6 измененных файлов с 88 добавлено и 11 удалено
  1. 6 0
      benchmarks/.gitignore
  2. 8 2
      benchmarks/build/hello.s
  3. 4 2
      benchmarks/hello.c
  4. 31 6
      src/dataflow.py
  5. 10 1
      src/optimize/advanced.py
  6. 29 0
      tests/test_dataflow.py

+ 6 - 0
benchmarks/.gitignore

@@ -0,0 +1,6 @@
+acron
+clinpack
+dhrystone
+pi
+slalom
+whet

+ 8 - 2
benchmarks/build/hello.s

@@ -6,11 +6,14 @@
  # -mgas -mgpOPT
 
  # Cc1 arguments (-G value = 8, Cpu = default, ISA = 1):
- # -quiet -dumpbase -o
+ # -quiet -dumpbase -O0 -o
 
 gcc2_compiled.:
 __gnu_compiled_c:
 	.sdata
+	.align	2
+$LC2:
+	.ascii	"e: %d\n\000"
 	.align	3
 $LC0:
 	.word	0x00000000		# 2
@@ -25,7 +28,7 @@ $LC1:
 
 	.text
 
-	.loc	1 2
+	.loc	1 3
 	.ent	main
 main:
 	.frame	$fp,64,$31		# vars= 40, regs= 2/0, args= 16, extra= 0
@@ -53,6 +56,9 @@ main:
 	s.d	$f0,40($fp)
 	li	$2,0x00000061		# 97
 	sb	$2,48($fp)
+	la	$4,$LC2
+	lw	$5,28($fp)
+	jal	printf
 	move	$2,$0
 	j	$L1
 $L1:

+ 4 - 2
benchmarks/hello.c

@@ -1,9 +1,11 @@
-int main(void)
-{
+#include <stdio.h>
+
+int main(void) {
     int x = 1, b = 5, d = x + b, e = x + 10;
     double y = 2., z = 3.5;
     char c = 'a';
 
+	printf("e: %d\n", e);  // 11
 
     return 0;
 }

+ 31 - 6
src/dataflow.py

@@ -11,6 +11,10 @@ class BasicBlock(Block):
 
         self.dominates = []
         self.dominated_by = []
+        self.in_set = set([])
+        self.out_set = set([])
+        self.gen_set = set([])
+        self.kill_set = set([])
 
     def add_edge_to(self, block):
         if block not in self.edges_to:
@@ -23,17 +27,38 @@ class BasicBlock(Block):
             block.dominated_by.append(self)
 
     def get_gen(self):
-        pass
-
+        for s in self.statements:       
+            if s.is_arith():
+                self.gen_set.add(s[0])
+                print 'added: ', s[0]
+        
+        return self.gen_set
+        
     def get_kill(self):
-        pass
+#        if self.edges_from != []:
+        for backw in self.edges_from:
+            self.kill_set = self.kill_set | backw.get_kill()
+            
+        self.kill_set = self.kill_set - self.get_gen()
+        print 'get_kill_set', self.kill_set
+        return self.kill_set
 
     def get_in(self):
-        pass
+        for backw in self.edges_from:
+            self.in_set = self.in_set | backw.get_out()
+        print 'in_set', self.in_set
+        return self.in_set
 
     def get_out(self):
-        pass
-
+        print 'gen_set', self.gen_set
+        print 'get_in', self.get_in()
+        print 'get_kill', self.get_kill()
+        self.out_set = self.gen_set | (self.get_in() - self.get_kill())
+        
+def reaching_definition(blocks):
+    generate_flow_graph(blocks)
+
+    
 
 def find_leaders(statements):
     """Determine the leaders, which are:

+ 10 - 1
src/optimize/advanced.py

@@ -8,6 +8,11 @@ def create_variable():
 def eliminate_common_subexpressions(block):
     """
     Common subexpression elimination:
+    x = a + b           ->  u = a + b
+    y = a + b               x = u
+                            y = u
+
+    The algorithm used is as follows:
     - Traverse through the statements in reverse order.
     - If the statement can be possibly be eliminated, walk further collecting
       all other occurrences of the expression until one of the arguments is
@@ -65,7 +70,11 @@ def to_hex(value):
 def fold_constants(block):
     """
     Constant folding:
-    - An immidiate load defines a register value:
+    x = 3 + 5           ->  x = 8
+    y = x * 2               y = 16
+
+    To keep track of constant values, the following assumptions are made:
+    - An immediate load defines a register value:
         li $reg, XX     ->  register[$reg] = XX
     - Integer variable definition is of the following form:
         li $reg, XX     ->  constants[VAR] = XX

+ 29 - 0
tests/test_dataflow.py

@@ -23,6 +23,35 @@ class TestDataflow(unittest.TestCase):
         self.assertEqual(map(lambda b: b.statements, find_basic_blocks(s)), \
                 [B(s[:2]).statements, B(s[2:4]).statements, \
                  B(s[4:]).statements])
+                 
+#    def test_get_gen(self):
+#        b1 = B([S('command', 'add', '$1', '$2', '$3'), \
+#                S('command', 'add', '$2', '$3', '$4'), \
+#                S('command', 'add', '$1', '$4', '$5')])
+#        
+#        self.assertEqual(b1.get_gen(), ['$1', '$2'])
+
+#    def test_get_out(self):
+#        b1 = B([S('command', 'add', '$1', '$2', '$3'), \
+#                S('command', 'add', '$2', '$3', '$4'), \
+#                S('command', 'add', '$1', '$4', '$5'), \
+#                S('command', 'j', 'b2')])
+#        
+#        b2 = B([S('command', 'add', '$3', '$5', '$6'), \
+#                S('command', 'add', '$1', '$2', '$3'), \
+#                S('command', 'add', '$6', '$4', '$5')])      
+#                
+#        blocks = [b1, b2]
+#        
+#        for block in blocks:
+#            block.out_set = block.get_gen()
+#            print 'block.out_set', block.out_set       
+
+#        generate_flow_graph(blocks)     
+#        print b1.get_gen()
+#        print b2.get_gen()
+#        print b2.get_out()
+
 
     def test_generate_flow_graph_simple(self):
         b1 = B([S('command', 'foo'), S('command', 'j', 'b2')])