-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathsimplify.py
105 lines (82 loc) · 4.19 KB
/
simplify.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
103
104
105
import opcode
from utils import insMnemonic
def simplifyPass1(bb_list):
"""
Eliminates a basic block that only contains an unconditional branch.
"""
foo = True
while foo:
foo = False
for i in range(len(bb_list)):
bb = bb_list[i]
if bb.isHandler and len(bb.instructions) == 1:
ins = bb.instructions[0]
if insMnemonic(ins) == 'JUMP_FORWARD' or insMnemonic(ins) == 'JUMP_ABSOLUTE':
branch_target_bb = bb.successors[0] # Branch target of this basic block
branch_target_bb.predecessors.remove(bb)
branch_target_bb.isHandler = True
for refIns in bb.refHandlerIns:
refIns.arg = branch_target_bb
branch_target_bb.refHandlerIns = bb.refHandlerIns
# Now iterate over all predecessors of this bb
for j in range(len(bb.predecessors)):
# Remove this bb from the successor list
# Add branch target bb to the successor list
bb.predecessors[j].successors.remove(bb)
bb.predecessors[j].addSuccessor(branch_target_bb)
branch_target_bb.addPredecessor(bb.predecessors[j])
last_ins = bb.predecessors[j].instructions[-1]
if last_ins.opkode in opcode.hasjabs or last_ins.opkode in opcode.hasjrel:
last_ins.arg = branch_target_bb
del bb_list[i]
foo = True
break
elif not bb.isHandler and len(bb.instructions) == 1:
ins = bb.instructions[0]
if insMnemonic(ins) == 'JUMP_FORWARD' or insMnemonic(ins) == 'JUMP_ABSOLUTE':
branch_target_bb = bb.successors[0] # Branch target of this basic block
branch_target_bb.predecessors.remove(bb)
# Now iterate over all predecessors of this bb
for j in range(len(bb.predecessors)):
# Remove this bb from the successor list
# Add branch target bb to the successor list
bb.predecessors[j].successors.remove(bb)
bb.predecessors[j].addSuccessor(branch_target_bb)
branch_target_bb.addPredecessor(bb.predecessors[j])
last_ins = bb.predecessors[j].instructions[-1]
if last_ins.opkode in opcode.hasjabs or last_ins.opkode in opcode.hasjrel:
last_ins.arg = branch_target_bb
del bb_list[i]
foo = True
break
def simplifyPass2(bb_list):
"""
Merges a basic block into its predecessor if there is only one and the
predecessor only has one successor.
"""
foo = True
while foo:
foo = False
for i in range(len(bb_list)):
bb = bb_list[i]
# Not a handler block & has only 1 predecessor
if not bb.isHandler and len(bb.predecessors) == 1:
pred = bb.predecessors[0]
# Predecessor has only 1 successor
if len(pred.successors) == 1:
# Merge this bb with its predecessor
last_ins_pred = pred.instructions[-1]
# If last instruction of predecessor is either JUMP_ABSOLUTE or JUMP_FORWARD, delete it
if insMnemonic(last_ins_pred) == 'JUMP_ABSOLUTE' or insMnemonic(last_ins_pred) == 'JUMP_FORWARD':
del pred.instructions[-1]
# Append all instructions of current bb
for ins in bb.instructions:
pred.addInstruction(ins)
del pred.successors[:]
for succ in bb.successors:
pred.addSuccessor(succ)
succ.predecessors.remove(bb)
succ.addPredecessor(pred)
del bb_list[i]
foo = True
break