Просмотр исходного кода

Merge branch 'master' of github.com:taddeus/peephole

Richard Torenvliet 14 лет назад
Родитель
Сommit
53d3416cde
3 измененных файлов с 85 добавлено и 12 удалено
  1. 55 0
      benchmarks/build/test.s
  2. 7 0
      benchmarks/test.c
  3. 23 12
      src/optimize/advanced.py

+ 55 - 0
benchmarks/build/test.s

@@ -0,0 +1,55 @@
+	.file	1 "test.c"
+
+ # GNU C 2.7.2.3 [AL 1.1, MM 40, tma 0.1] SimpleScalar running sstrix compiled by GNU C
+
+ # Cc1 defaults:
+ # -mgas -mgpOPT
+
+ # Cc1 arguments (-G value = 8, Cpu = default, ISA = 1):
+ # -quiet -dumpbase -O0 -o
+
+gcc2_compiled.:
+__gnu_compiled_c:
+	.text
+	.align	2
+	.globl	main
+
+	.text
+
+	.loc	1 3
+	.ent	main
+main:
+	.frame	$fp,48,$31		# vars= 24, regs= 2/0, args= 16, extra= 0
+	.mask	0xc0000000,-4
+	.fmask	0x00000000,0
+	subu	$sp,$sp,48
+	sw	$31,44($sp)
+	sw	$fp,40($sp)
+	move	$fp,$sp
+	jal	__main
+	li	$2,0x00000002		# 2
+	sw	$2,16($fp)
+	li	$2,0x00000005		# 5
+	sw	$2,20($fp)
+	lw	$2,16($fp)
+	lw	$3,20($fp)
+	mult	$2,$3
+	mflo	$2
+	sw	$2,24($fp)
+	lw	$2,16($fp)
+	move	$4,$2
+	sll	$3,$4,1
+	addu	$3,$3,$2
+	sll	$2,$3,1
+	sw	$2,28($fp)
+	li	$2,0x00000015		# 21
+	sw	$2,32($fp)
+	move	$2,$0
+	j	$L1
+$L1:
+	move	$sp,$fp			# sp not trusted here
+	lw	$31,44($sp)
+	lw	$fp,40($sp)
+	addu	$sp,$sp,48
+	j	$31
+	.end	main

+ 7 - 0
benchmarks/test.c

@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(void) {
+    int a = 2, b = 5, c = a * b, d = a * 6, e = 3 * 7;
+
+    return 0;
+}

+ 23 - 12
src/optimize/advanced.py

@@ -147,10 +147,27 @@ def fold_constants(block):
         elif s.name == 'lw' and s[1] in constants:
         elif s.name == 'lw' and s[1] in constants:
             # Usage of variable with constant value
             # Usage of variable with constant value
             register[s[0]] = constants[s[1]]
             register[s[0]] = constants[s[1]]
-        elif s.name in ['addu', 'subu', 'mult', 'div']:
-            # TODO: implement 'mult' optimization
-            # Calculation with constants
-            rd, rs, rt = s[0], s[1], s[2]
+        elif s.name == 'mflo':
+            # Move of `Lo' register to another register
+            register[s[0]] = register['Lo']
+        elif s.name == 'mfhi':
+            # Move of `Hi' register to another register
+            register[s[0]] = register['Hi']
+        elif s.name in ['mult', 'div'] \
+                and s[0] in register and s[1] in register:
+            # Multiplication/division with constants
+            rs, rt = s
+
+            if s.name == 'mult':
+                binary = bin(register[rs] * register[rt])[2:]
+                binary = '0' * (64 - len(binary)) + binary
+                register['Hi'] = int(binary[:32], base=2)
+                register['Lo'] = int(binary[32:], base=2)
+            elif s.name == 'div':
+                register['Lo'], register['Hi'] = divmod(rs, rt)
+        elif s.name in ['addu', 'subu']:
+            # Addition/subtraction with constants
+            rd, rs, rt = s
             rs_known = rs in register
             rs_known = rs in register
             rt_known = rt in register
             rt_known = rt in register
 
 
@@ -167,22 +184,16 @@ def fold_constants(block):
                 if s.name == 'subu':
                 if s.name == 'subu':
                     result = to_hex(rs_val - rt_val)
                     result = to_hex(rs_val - rt_val)
 
 
-                if s.name == 'mult':
-                    result = to_hex(rs_val * rt_val)
-
-                if s.name == 'div':
-                    result = to_hex(rs_val / rt_val)
-
                 block.replace(1, [S('command', 'li', rd, result)])
                 block.replace(1, [S('command', 'li', rd, result)])
                 register[rd] = result
                 register[rd] = result
                 changed = True
                 changed = True
             elif rt_known:
             elif rt_known:
-                # c = 10        ->  b = a + 10
+                # a = 10        ->  b = c + 10
                 # b = c + a
                 # b = c + a
                 s[2] = register[rt]
                 s[2] = register[rt]
                 changed = True
                 changed = True
             elif rs_known and s.name == 'addu':
             elif rs_known and s.name == 'addu':
-                # a = 10        ->  b = c + 10
+                # c = 10        ->  b = a + 10
                 # b = c + a
                 # b = c + a
                 s[1] = rt
                 s[1] = rt
                 s[2] = register[rs]
                 s[2] = register[rs]