Commit e755a9f6 authored by Richard Torenvliet's avatar Richard Torenvliet

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

parents 31e9202c 069c57ce
.file 1 "acron.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:
.globl w
......@@ -66,38 +68,38 @@ is_vowel:
.mask 0x40000000,-8
.fmask 0x00000000,0
subu $sp,$sp,16
sw $fp,8($sp)
sw $fp,8($sp)
move $fp,$sp
move $3,$4
sb $3,0($fp)
sb $3,0($fp)
move $2,$0
lb $4,0($fp)
li $5,0x00000041 # 65
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x00000045 # 69
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x00000049 # 73
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x0000004f # 79
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x00000055 # 85
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x00000059 # 89
bne $4,$5,$L2
lb $4,0($fp)
li $5,0x00000041 # $5 = 65
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x00000045 # $5 = 69
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x00000049 # $5 = 73
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x0000004f # $5 = 79
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x00000055 # $5 = 85
beq $4,$5,$L3
lb $4,0($fp)
li $5,0x00000059 # $5 = 89
bne $4,$5,$L2
$L3:
li $2,0x00000001 # 1
li $2,0x00000001 # $2 = 1
$L2:
j $L1
j $L1
$L1:
move $sp,$fp # sp not trusted here
lw $fp,8($sp)
lw $fp,8($sp)
addu $sp,$sp,16
j $31
j $31
.end is_vowel
.loc 1 15
.ent do_perm
......@@ -106,246 +108,246 @@ do_perm:
.mask 0xc0030000,-4
.fmask 0x00000000,0
subu $sp,$sp,56
sw $31,52($sp)
sw $fp,48($sp)
sw $17,44($sp)
sw $16,40($sp)
sw $31,52($sp)
sw $fp,48($sp)
sw $17,44($sp)
sw $16,40($sp)
move $fp,$sp
sw $4,56($fp)
sw $5,60($fp)
sw $6,64($fp)
sw $7,68($fp)
sw $0,24($fp)
lw $2,64($fp)
li $3,0x00000001 # 1
bne $2,$3,$L5
lw $2,pindex
sw $4,56($fp)
sw $5,60($fp)
sw $6,64($fp)
sw $7,68($fp)
sw $0,24($fp)
lw $2,64($fp)
li $3,0x00000001 # $3 = 1
bne $2,$3,$L5
lw $2,pindex
move $3,$2
sll $2,$3,2
la $3,w
sll $2,$3,2
la $3,w
addu $2,$2,$3
lw $3,0($2)
lb $4,0($3)
jal is_vowel
bne $2,$0,$L5
lw $2,56($fp)
lw $3,0($2)
lb $4,0($3)
jal is_vowel
bne $2,$0,$L5
lw $2,56($fp)
move $3,$2
sll $2,$3,2
la $3,w
sll $2,$3,2
la $3,w
addu $2,$2,$3
lw $3,0($2)
lb $4,0($3)
jal is_vowel
beq $2,$0,$L4
lw $3,0($2)
lb $4,0($3)
jal is_vowel
beq $2,$0,$L4
$L5:
lw $2,64($fp)
slt $3,$2,2
bne $3,$0,$L6
lw $2,64($fp)
lw $2,64($fp)
slt $3,$2,2
bne $3,$0,$L6
lw $2,64($fp)
move $3,$2
sll $2,$3,2
la $3,pindex-8
sll $2,$3,2
la $3,pindex-8
addu $2,$2,$3
lw $3,0($2)
lw $3,0($2)
move $2,$3
sll $3,$2,2
la $4,w
sll $3,$2,2
la $4,w
addu $2,$3,$4
lw $3,0($2)
lb $4,0($3)
jal is_vowel
lw $3,0($2)
lb $4,0($3)
jal is_vowel
move $16,$2
lw $2,64($fp)
lw $2,64($fp)
move $3,$2
sll $2,$3,2
la $3,pindex-4
sll $2,$3,2
la $3,pindex-4
addu $2,$2,$3
lw $3,0($2)
lw $3,0($2)
move $2,$3
sll $3,$2,2
la $4,w
sll $3,$2,2
la $4,w
addu $2,$3,$4
lw $3,0($2)
lb $4,0($3)
jal is_vowel
lw $3,0($2)
lb $4,0($3)
jal is_vowel
move $17,$2
lw $2,56($fp)
lw $2,56($fp)
move $3,$2
sll $2,$3,2
la $3,w
sll $2,$3,2
la $3,w
addu $2,$2,$3
lw $3,0($2)
lb $4,0($3)
jal is_vowel
lw $3,0($2)
lb $4,0($3)
jal is_vowel
addu $3,$16,$17
addu $2,$3,$2
sw $2,24($fp)
beq $2,$0,$L8
lw $2,24($fp)
li $3,0x00000003 # 3
bne $2,$3,$L7
sw $2,24($fp)
beq $2,$0,$L8
lw $2,24($fp)
li $3,0x00000003 # $3 = 3
bne $2,$3,$L7
$L8:
j $L4
j $L4
$L7:
$L6:
lw $2,64($fp)
lw $2,64($fp)
addu $3,$2,1
sw $3,64($fp)
sll $3,$2,2
la $4,pindex
sw $3,64($fp)
sll $3,$2,2
la $4,pindex
addu $2,$3,$4
lw $3,56($fp)
sw $3,0($2)
lw $2,64($fp)
slt $3,$2,6
beq $3,$0,$L9
lw $3,68($fp)
lw $3,56($fp)
sw $3,0($2)
lw $2,64($fp)
slt $3,$2,6
beq $3,$0,$L9
lw $3,68($fp)
subu $2,$3,1
move $3,$2
sw $3,68($fp)
beq $3,$0,$L9
sw $0,16($fp)
sw $3,68($fp)
beq $3,$0,$L9
sw $0,16($fp)
$L10:
lw $2,16($fp)
slt $3,$2,6
beq $3,$0,$L11
lw $2,16($fp)
slt $3,$2,6
beq $3,$0,$L11
$L13:
lw $2,16($fp)
lw $2,16($fp)
move $3,$2
sll $2,$3,2
lw $3,60($fp)
sll $2,$3,2
lw $3,60($fp)
addu $2,$2,$3
lw $3,0($2)
bne $3,$0,$L14
lw $2,16($fp)
lw $3,0($2)
bne $3,$0,$L14
lw $2,16($fp)
move $3,$2
sll $2,$3,2
lw $3,60($fp)
sll $2,$3,2
lw $3,60($fp)
addu $2,$2,$3
li $3,0x00000001 # 1
sw $3,0($2)
lw $4,16($fp)
lw $5,60($fp)
lw $6,64($fp)
lw $7,68($fp)
jal do_perm
lw $2,16($fp)
li $3,0x00000001 # $3 = 1
sw $3,0($2) # 0($2) = 1
lw $4,16($fp)
lw $5,60($fp)
lw $6,64($fp)
lw $7,68($fp)
jal do_perm
lw $2,16($fp)
move $3,$2
sll $2,$3,2
lw $3,60($fp)
sll $2,$3,2
lw $3,60($fp)
addu $2,$2,$3
sw $0,0($2)
sw $0,0($2)
$L14:
$L12:
lw $3,16($fp)
lw $3,16($fp)
addu $2,$3,1
move $3,$2
sw $3,16($fp)
j $L10
sw $3,16($fp)
j $L10
$L11:
j $L15
j $L15
$L9:
sw $0,28($fp)
sw $0,20($fp)
sw $0,28($fp)
sw $0,20($fp)
$L16:
lw $2,20($fp)
lw $3,64($fp)
slt $2,$2,$3
beq $2,$0,$L17
lw $2,20($fp)
lw $3,64($fp)
slt $2,$2,$3
beq $2,$0,$L17
$L19:
sw $0,32($fp)
sw $0,32($fp)
$L20:
lw $2,20($fp)
lw $2,20($fp)
move $3,$2
sll $2,$3,2
la $3,pindex
sll $2,$3,2
la $3,pindex
addu $2,$2,$3
lw $3,0($2)
lw $3,0($2)
move $2,$3
sll $3,$2,2
la $4,w
sll $3,$2,2
la $4,w
addu $2,$3,$4
lw $3,0($2)
lw $4,32($fp)
lw $3,0($2)
lw $4,32($fp)
addu $2,$3,$4
lb $4,0($2)
jal isupper
beq $2,$0,$L21
lb $4,0($2)
jal isupper
beq $2,$0,$L21
$L22:
lw $2,28($fp)
lw $2,28($fp)
addu $3,$2,1
sw $3,28($fp)
lw $3,20($fp)
sw $3,28($fp)
lw $3,20($fp)
move $4,$3
sll $3,$4,2
la $4,pindex
sll $3,$4,2
la $4,pindex
addu $3,$3,$4
lw $4,0($3)
lw $4,0($3)
move $3,$4
sll $4,$3,2
la $5,w
sll $4,$3,2
la $5,w
addu $3,$4,$5
lw $4,32($fp)
lw $4,32($fp)
addu $5,$4,1
sw $5,32($fp)
lw $5,0($3)
sw $5,32($fp)
lw $5,0($3)
addu $3,$4,$5
lbu $4,0($3)
sb $4,acron($2)
j $L20
lbu $4,0($3)
sb $4,acron($2)
j $L20
$L21:
$L18:
lw $3,20($fp)
lw $3,20($fp)
addu $2,$3,1
move $3,$2
sw $3,20($fp)
j $L16
sw $3,20($fp)
j $L16
$L17:
lw $2,28($fp)
la $3,acron
lw $2,28($fp)
la $3,acron
addu $2,$2,$3
sb $0,0($2)
la $4,$LC6
la $5,acron
jal printf
sw $0,20($fp)
sb $0,0($2)
la $4,$LC6
la $5,acron
jal printf
sw $0,20($fp)
$L23:
lw $2,20($fp)
lw $3,64($fp)
slt $2,$2,$3
beq $2,$0,$L24
lw $2,20($fp)
lw $3,64($fp)
slt $2,$2,$3
beq $2,$0,$L24
$L26:
lw $2,20($fp)
lw $2,20($fp)
move $3,$2
sll $2,$3,2
la $3,pindex
sll $2,$3,2
la $3,pindex
addu $2,$2,$3
lw $3,0($2)
lw $3,0($2)
move $2,$3
sll $3,$2,2
la $4,w
sll $3,$2,2
la $4,w
addu $2,$3,$4
la $4,$LC7
lw $5,0($2)
jal printf
la $4,$LC7
lw $5,0($2)
jal printf
$L25:
lw $3,20($fp)
lw $3,20($fp)
addu $2,$3,1
move $3,$2
sw $3,20($fp)
j $L23
sw $3,20($fp)
j $L23
$L24:
la $4,$LC8
jal printf
la $4,$LC8
jal printf
$L15:
$L4:
move $sp,$fp # sp not trusted here
lw $31,52($sp)
lw $fp,48($sp)
lw $17,44($sp)
lw $16,40($sp)
lw $31,52($sp)
lw $fp,48($sp)
lw $17,44($sp)
lw $16,40($sp)
addu $sp,$sp,56
j $31
j $31
.end do_perm
.loc 1 53
.ent main
......@@ -354,59 +356,59 @@ main:
.mask 0xc0000000,-4
.fmask 0x00000000,0
subu $sp,$sp,32
sw $31,28($sp)
sw $fp,24($sp)
sw $31,28($sp)
sw $fp,24($sp)
move $fp,$sp
jal __main
li $2,0x00000004 # 4
sw $2,20($fp)
jal __main
li $2,0x00000004 # $2 = 4
sw $2,20($fp) # 20($fp) = 4
$L28:
lw $2,20($fp)
slt $3,$2,7
beq $3,$0,$L29
lw $2,20($fp)
slt $3,$2,7
beq $3,$0,$L29
$L31:
sw $0,16($fp)
sw $0,16($fp)
$L32:
lw $2,16($fp)
slt $3,$2,6
beq $3,$0,$L33
lw $2,16($fp)
slt $3,$2,6
beq $3,$0,$L33
$L35:
lw $2,16($fp)
lw $2,16($fp)
move $3,$2
sll $2,$3,2
la $3,done
sll $2,$3,2
la $3,done
addu $2,$2,$3
li $3,0x00000001 # 1
sw $3,0($2)
lw $4,16($fp)
la $5,done
li $3,0x00000001 # $3 = 1
sw $3,0($2) # 0($2) = 1
lw $4,16($fp)
la $5,done
move $6,$0
lw $7,20($fp)
jal do_perm
lw $2,16($fp)
lw $7,20($fp)
jal do_perm
lw $2,16($fp)
move $3,$2
sll $2,$3,2
la $3,done
sll $2,$3,2
la $3,done
addu $2,$2,$3
sw $0,0($2)
sw $0,0($2)
$L34:
lw $3,16($fp)
lw $3,16($fp)
addu $2,$3,1
move $3,$2
sw $3,16($fp)
j $L32
sw $3,16($fp)
j $L32
$L33:
$L30:
lw $3,20($fp)
lw $3,20($fp)
addu $2,$3,1
move $3,$2
sw $3,20($fp)
j $L28
sw $3,20($fp)
j $L28
$L29:
$L27:
move $sp,$fp # sp not trusted here
lw $31,28($sp)
lw $fp,24($sp)
lw $31,28($sp)
lw $fp,24($sp)
addu $sp,$sp,32
j $31
j $31
.end main
This diff is collapsed.
from copy import copy
RESERVED_REGISTERS = ['$fp', '$sp']
def is_reg_dead_after(reg, block, index):
"""Check if a register is dead after a certain point in a basic block."""
if reg in RESERVED_REGISTERS:
return False
if index < len(block) - 1:
for s in block[index + 1:]:
# If used, the previous definition is live
if s.uses(reg):
return False
# If redefined, the previous definition is dead
if s.defines(reg):
return True
# If dead within the same block, check if the register is in the block's
# live_out set
return reg not in block.live_out
def create_use_def(block):
used = set()
defined = set()
......
from src.statement import Statement as S
from math import log
from src.statement import Statement as S
from src.liveness import is_reg_dead_after
def reg_can_be_used_in(reg, block, start, end):
"""Check if a register addres safely be used in a block section using local
......@@ -173,50 +175,45 @@ def fold_constants(block):
# Move of `Hi' register to another register
register[s[0]] = register['$hi']
known.append((s[0], register[s[0]]))
elif s.name in ['mult', 'div'] \
and s[0]in register and s[1] in register:
elif s.name == 'mult' and s[0]in register and s[1] in register:
# Multiplication/division with constants
print s
rs, rt = s
a, b = register[rs], register[rt]
if s.name == 'mult':
if not a or not b:
# Multiplication by 0
hi = lo = to_hex(0)
message = 'Multiplication by 0: %d * 0' % (b if a else a)
elif a == 1:
# Multiplication by 1
hi = to_hex(0)
lo = to_hex(b)
message = 'Multiplication by 1: %d * 1' % b
elif b == 1:
# Multiplication by 1
hi = to_hex(0)
lo = to_hex(a)
message = 'Multiplication by 1: %d * 1' % a
else:
# Calculate result and fill Hi/Lo registers
result = a * b
binary = bin(result)[2:]
binary = '0' * (64 - len(binary)) + binary
hi = int(binary[:32], base=2)
lo = int(binary[32:], base=2)
message = 'Constant multiplication: %d * %d = %d' \
% (a, b, result)
# Replace the multiplication with two immidiate loads to the
# Hi/Lo registers
block.replace(1, [S('command', 'li', '$hi', hi),
S('command', 'li', '$lo', li)],
message=message)
elif s.name == 'div':
lo, hi = divmod(rs, rt)
if not a or not b:
# Multiplication by 0
hi = lo = to_hex(0)
message = 'Multiplication by 0: %d * 0' % (b if a else a)
elif a == 1:
# Multiplication by 1
hi = to_hex(0)
lo = to_hex(b)
message = 'Multiplication by 1: %d * 1' % b
elif b == 1:
# Multiplication by 1
hi = to_hex(0)
lo = to_hex(a)
message = 'Multiplication by 1: %d * 1' % a
else:
# Calculate result and fill Hi/Lo registers
result = a * b
binary = bin(result)[2:]
binary = '0' * (64 - len(binary)) + binary
hi = int(binary[:32], base=2)
lo = int(binary[32:], base=2)
message = 'Constant multiplication: %d * %d = %d' \
% (a, b, result)
# Replace the multiplication with two immidiate loads to the
# Hi/Lo registers
block.replace(1, [S('command', 'li', '$hi', hi),
S('command', 'li', '$lo', li)],
message=message)
register['$lo'], register['$hi'] = lo, hi
known += [('$lo', lo), ('$hi', hi)]
changed = True
elif s.name in ['addu', 'subu']:
elif s.name in ['addu', 'subu', 'div']:
# Addition/subtraction with constants
rd, rs, rt = s
rs_known = rs in register
......@@ -233,12 +230,17 @@ def fold_constants(block):
if s.name == 'addu':
result = rs_val + rt_val
message = 'Constant addition: %d + %d = %d' \
% (rs_val, rt_val, result)
% (rs_val, rt_val, result)
if s.name == 'subu':
result = rs_val - rt_val
message = 'Constant subtraction: %d - %d = %d' \
% (rs_val, rt_val, result)
% (rs_val, rt_val, result)
if s.name == 'div':
result = rs_val / rt_val
message = 'Constant division: %d - %d = %d' \
% (rs_val, rt_val, result)
block.replace(1, [S('command', 'li', rd, to_hex(result))],
message=message)
......@@ -393,25 +395,42 @@ def eliminate_dead_code(block):
is not used in the rest of the block, and is not in the `out' set of the
block.
"""
# TODO: Finish
changed = False
unused = set()
for s in reversed(block):
for n, s in enumerate(block):
for reg in s.get_def():
if reg in unused:
if is_reg_dead_after(reg, block, n):
# Statement is redefined later, so this statement is useless
if block.debug:
s.stype = 'comment'
s.options['block'] = False
s.name = ' Dead code: %s %s' \
% (s.name, ', '.join(map(str, s)))
s.options[''] = False
s.name = ' Dead:\t%s\t%s\t(dead register %s)' \
% (s.name, ','.join(map(str, s)), reg)
else:
s.remove = True
else:
unused.add(reg)
unused -= set(s.get_use())
changed = True
#unused = set()
#for s in reversed(block):
# for reg in s.get_def():
# if reg in unused:
# # Statement is redefined later, so this statement is useless
# if block.debug:
# s.stype = 'comment'
# s.options['block'] = False
# s.name = ' Dead:\t%s\t%s' \
# % (s.name, ','.join(map(str, s)))
# else:
# s.remove = True
# changed = True
# else:
# unused.add(reg)
# unused -= set(s.get_use())
if not block.debug:
block.apply_filter(lambda s: not hasattr(s, 'remove'))
......
......@@ -148,6 +148,8 @@ class TestStatement(unittest.TestCase):
arg2)
self.assertEqual(S('command', 's.s', '$1', '10($2)').get_use(), \
arg2)
self.assertEqual(S('command', 'sw', '$1', '10($2)').get_use(), \
arg2)
self.assertEqual(S('command', 'sb', '$1', '10($2)').get_use(), \
arg2)
self.assertEqual(S('command', 'mtc1', '$1', '$2').get_use(), arg1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment