-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathredundantLoadStore.py
102 lines (73 loc) · 3.43 KB
/
redundantLoadStore.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""
File: redundantLoadStore.py
Authors: Tim van Deurzen, Koos van Strien
Date: 26-02-2010
"""
import re
from basicblock import *
from operations_new import *
from optimizationClass import *
class redundantLoadStore(optimizationClass):
"""
Optimizes assembly by removing any unecessary loads or stores.
"""
def __init__(self, blocks):
"""
Initializes all the necessary variables.
"""
self.name = "Remove redundant loads / stores"
self.optimizedBlocks = blocks
self.output = [" ==== Redundant load / store optimizer ==== "]
self.changed = []
self.exceptions = []
def analyseBasicBlock(self, block):
self.output.append("\n>>>> Starting analysis of new block. <<<<\n")
for i, op in enumerate(block.operations):
if op.type not in (operation.LOAD, operation.STORE):
continue
if op.included == False:
self.output.append("\t{{ operation previously excluded: " +
op.code + " }}")
self.output.append("\t--> Analysing operation: " + str(op) +
" on line " + str(op.lineNumber))
target = op.getTarget()
source = op.getAddress()
offset = None
if op.usesOffset():
offset = op.getOffsetRegister()
pattern = "\$(s|f)[0-9p]+"
if re.match(pattern, target):
continue
next_ops = block.operations[i + 1:]
for n_op in next_ops:
n_target = None
n_source = None
n_offset = None
if n_op.type not in (operation.CONTROL, operation.SYSTEM):
n_target = n_op.getTarget()
if n_op.type in (operation.LOAD, operation.STORE):
n_source = n_op.getAddress()
if n_op.usesOffset():
n_offset = n_op.getOffsetRegister()
if n_op.type == operation.LOAD and op.type == operation.LOAD:
if n_op.size == op.size and n_target == target and \
n_source == source:
self.output.append("\n\t!!--> Excluding identical" +
"load / store operation from output.\n")
n_op.exclude()
if n_op.type == operation.LOAD and op.type == operation.STORE:
if n_op.size == op.size and n_target == target and \
n_source == source:
self.output.append("\n\t!!--> Excluding load that was" +
"previously stored but not updated.\n")
n_op.exclude()
if n_op.type not in (operation.CONTROL, operation.SYSTEM) and \
n_target == target or n_target == offset:
self.output.append("\n\t!!--> Register was updated cannot " +
"optimize load.\n")
break
if n_op.type == operation.CONTROL:
if n_op.operation == "jal" or n_op.operation == "jalr":
self.output.append("\n\t!!--> Breaking on function call " +
"(jal / jalr).\n")
break