Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
peephole
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
peephole
Commits
00d7bd2f
Commit
00d7bd2f
authored
Dec 29, 2011
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed existing unit tests and added tests for reaching definitions..
parent
19cebc60
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
60 additions
and
80 deletions
+60
-80
src/liveness.py
src/liveness.py
+3
-3
src/optimize/__init__.py
src/optimize/__init__.py
+7
-4
src/optimize/advanced.py
src/optimize/advanced.py
+1
-1
src/reaching_definitions.py
src/reaching_definitions.py
+0
-7
tests/test_liveness.py
tests/test_liveness.py
+2
-2
tests/test_optimize_advanced.py
tests/test_optimize_advanced.py
+4
-1
tests/test_reaching_definitions.py
tests/test_reaching_definitions.py
+43
-62
No files found.
src/liveness.py
View file @
00d7bd2f
...
@@ -2,14 +2,12 @@ def create_gen_kill(block):
...
@@ -2,14 +2,12 @@ def create_gen_kill(block):
# Get the last of each definition series and put in in the `def' set
# Get the last of each definition series and put in in the `def' set
block
.
live_gen
=
set
()
block
.
live_gen
=
set
()
block
.
live_kill
=
set
()
block
.
live_kill
=
set
()
print
'block:'
,
block
for
s
in
block
:
for
s
in
block
:
# If a register is used without having been defined in this block,
# If a register is used without having been defined in this block,
# yet, put it in the `gen' set
# yet, put it in the `gen' set
for
reg
in
s
.
get_use
():
for
reg
in
s
.
get_use
():
if
reg
not
in
block
.
live_kill
:
if
reg
not
in
block
.
live_kill
:
print
' add:'
,
reg
block
.
live_gen
.
add
(
reg
)
block
.
live_gen
.
add
(
reg
)
for
reg
in
s
.
get_def
():
for
reg
in
s
.
get_def
():
...
@@ -17,4 +15,6 @@ def create_gen_kill(block):
...
@@ -17,4 +15,6 @@ def create_gen_kill(block):
def
create_in_out
(
blocks
):
def
create_in_out
(
blocks
):
pass
for
b
in
blocks
:
b
.
live_in
=
set
()
b
.
live_out
=
set
()
src/optimize/__init__.py
View file @
00d7bd2f
from
src.dataflow
import
find_basic_blocks
,
reaching_definitions
from
src.dataflow
import
find_basic_blocks
import
src.liveness
as
liveness
import
src.reaching_definitions
as
reaching_definitions
from
redundancies
import
remove_redundant_jumps
,
move_1
,
move_2
,
move_3
,
\
from
redundancies
import
remove_redundant_jumps
,
move_1
,
move_2
,
move_3
,
\
move_4
,
load
,
shift
,
add
move_4
,
load
,
shift
,
add
from
advanced
import
eliminate_common_subexpressions
,
fold_constants
,
\
from
advanced
import
eliminate_common_subexpressions
,
fold_constants
,
\
copy_propagation
,
algebraic_transformations
,
eliminate_dead_code
copy_propagation
,
eliminate_dead_code
def
remove_redundancies
(
block
):
def
remove_redundancies
(
block
):
...
@@ -48,8 +50,9 @@ def optimize(statements, verbose=0):
...
@@ -48,8 +50,9 @@ def optimize(statements, verbose=0):
# Divide into basic blocks
# Divide into basic blocks
blocks
=
find_basic_blocks
(
statements
)
blocks
=
find_basic_blocks
(
statements
)
# Find reaching definitions
# Perform dataflow analysis
reaching_definitions
(
blocks
)
liveness
.
create_in_out
(
blocks
)
reaching_definitions
.
create_in_out
(
blocks
)
# Optimize basic blocks
# Optimize basic blocks
map
(
optimize_block
,
blocks
)
map
(
optimize_block
,
blocks
)
...
...
src/optimize/advanced.py
View file @
00d7bd2f
...
@@ -18,7 +18,7 @@ def reg_can_be_used_in(reg, block, start, end):
...
@@ -18,7 +18,7 @@ def reg_can_be_used_in(reg, block, start, end):
elif
s
.
defines
(
reg
):
elif
s
.
defines
(
reg
):
return
True
return
True
return
reg
not
in
block
.
out_se
t
return
reg
not
in
block
.
live_ou
t
def
find_free_reg
(
block
,
start
,
end
):
def
find_free_reg
(
block
,
start
,
end
):
...
...
src/reaching_definitions.py
View file @
00d7bd2f
...
@@ -44,7 +44,6 @@ def create_in_out(blocks):
...
@@ -44,7 +44,6 @@ def create_in_out(blocks):
# Create gen/kill sets
# Create gen/kill sets
defs
=
get_defs
(
blocks
)
defs
=
get_defs
(
blocks
)
print
'defs:'
,
defs
for
b
in
blocks
:
for
b
in
blocks
:
create_gen_kill
(
b
,
defs
)
create_gen_kill
(
b
,
defs
)
...
@@ -56,19 +55,13 @@ def create_in_out(blocks):
...
@@ -56,19 +55,13 @@ def create_in_out(blocks):
change
=
False
change
=
False
for
b
in
blocks
:
for
b
in
blocks
:
print
'block:'
,
b
b
.
reach_in
=
set
()
b
.
reach_in
=
set
()
for
pred
in
b
.
edges_from
:
for
pred
in
b
.
edges_from
:
print
'pred: '
,
pred
b
.
reach_in
|=
pred
.
reach_out
b
.
reach_in
|=
pred
.
reach_out
print
'b.reach_in: '
,
b
.
reach_in
print
'b.reach_out: '
,
b
.
reach_out
new_out
=
b
.
reach_gen
|
(
b
.
reach_in
-
b
.
reach_kill
)
new_out
=
b
.
reach_gen
|
(
b
.
reach_in
-
b
.
reach_kill
)
print
'new_out: '
,
new_out
if
new_out
!=
b
.
reach_out
:
if
new_out
!=
b
.
reach_out
:
print
'changed'
b
.
reach_out
=
new_out
b
.
reach_out
=
new_out
change
=
True
change
=
True
tests/test_liveness.py
View file @
00d7bd2f
...
@@ -23,14 +23,14 @@ class TestLiveness(unittest.TestCase):
...
@@ -23,14 +23,14 @@ class TestLiveness(unittest.TestCase):
create_gen_kill
(
block
)
create_gen_kill
(
block
)
self
.
assertEqual
(
block
.
live_gen
,
set
([
'$1'
,
'$2'
]))
self
.
assertEqual
(
block
.
live_gen
,
set
([
'$1'
,
'$2'
]))
self
.
assertEqual
(
block
.
live_kill
,
set
([
'$3'
,
'$1'
,
'$
1
'
]))
self
.
assertEqual
(
block
.
live_kill
,
set
([
'$3'
,
'$1'
,
'$
4
'
]))
#def test_create_in_out(self):
#def test_create_in_out(self):
# s11 = S('command', 'li', 'a', 3)
# s11 = S('command', 'li', 'a', 3)
# s12 = S('command', 'li', 'b', 5)
# s12 = S('command', 'li', 'b', 5)
# s13 = S('command', 'li', 'd', 4)
# s13 = S('command', 'li', 'd', 4)
# s14 = S('command', 'li', 'x', 100)
# s14 = S('command', 'li', 'x', 100)
# s15 = S('command', 'b
lt
', 'a', 'b', 'L1')
# s15 = S('command', 'b
eq
', 'a', 'b', 'L1')
# b1 = B([s11, s12, s13, s14, s15])
# b1 = B([s11, s12, s13, s14, s15])
# s21 = S('command', 'addu', 'c', 'a', 'b')
# s21 = S('command', 'addu', 'c', 'a', 'b')
...
...
tests/test_optimize_advanced.py
View file @
00d7bd2f
...
@@ -4,6 +4,7 @@ from copy import copy
...
@@ -4,6 +4,7 @@ from copy import copy
from
src.optimize.advanced
import
eliminate_common_subexpressions
,
\
from
src.optimize.advanced
import
eliminate_common_subexpressions
,
\
fold_constants
,
copy_propagation
,
algebraic_transformations
fold_constants
,
copy_propagation
,
algebraic_transformations
from
src.statement
import
Statement
as
S
,
Block
as
B
from
src.statement
import
Statement
as
S
,
Block
as
B
import
src.liveness
as
liveness
class
TestOptimizeAdvanced
(
unittest
.
TestCase
):
class
TestOptimizeAdvanced
(
unittest
.
TestCase
):
...
@@ -22,6 +23,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
...
@@ -22,6 +23,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
e
=
[
S
(
'command'
,
'addu'
,
'$8'
,
'$regA'
,
'$regB'
),
\
e
=
[
S
(
'command'
,
'addu'
,
'$8'
,
'$regA'
,
'$regB'
),
\
S
(
'command'
,
'move'
,
'$regC'
,
'$8'
),
\
S
(
'command'
,
'move'
,
'$regC'
,
'$8'
),
\
S
(
'command'
,
'move'
,
'$regD'
,
'$8'
)]
S
(
'command'
,
'move'
,
'$regD'
,
'$8'
)]
liveness
.
create_in_out
([
b
])
eliminate_common_subexpressions
(
b
)
eliminate_common_subexpressions
(
b
)
self
.
assertEqual
(
b
.
statements
,
e
)
self
.
assertEqual
(
b
.
statements
,
e
)
...
@@ -30,6 +32,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
...
@@ -30,6 +32,7 @@ class TestOptimizeAdvanced(unittest.TestCase):
S
(
'command'
,
'li'
,
'$regA'
,
'0x00000001'
),
S
(
'command'
,
'li'
,
'$regA'
,
'0x00000001'
),
S
(
'command'
,
'addu'
,
'$regD'
,
'$regA'
,
'$regB'
)])
S
(
'command'
,
'addu'
,
'$regD'
,
'$regA'
,
'$regB'
)])
e
=
copy
(
b
.
statements
)
e
=
copy
(
b
.
statements
)
liveness
.
create_in_out
([
b
])
eliminate_common_subexpressions
(
b
)
eliminate_common_subexpressions
(
b
)
self
.
assertEqual
(
b
.
statements
,
e
)
self
.
assertEqual
(
b
.
statements
,
e
)
...
...
tests/test_reaching_definitions.py
View file @
00d7bd2f
import
unittest
import
unittest
from
src.statement
import
Statement
as
S
from
src.statement
import
Statement
as
S
from
src.dataflow
import
BasicBlock
as
B
from
src.dataflow
import
BasicBlock
as
B
,
find_basic_blocks
from
src.reaching_definitions
import
get_defs
,
create_gen_kill
,
create_in_out
from
src.reaching_definitions
import
get_defs
,
create_gen_kill
,
create_in_out
...
@@ -26,7 +26,7 @@ class TestReachingDefinitions(unittest.TestCase):
...
@@ -26,7 +26,7 @@ class TestReachingDefinitions(unittest.TestCase):
'$4'
:
set
([
s4
.
sid
])
'$4'
:
set
([
s4
.
sid
])
})
})
def
test_create_gen_kill
_simple
(
self
):
def
test_create_gen_kill
(
self
):
s1
=
S
(
'command'
,
'addu'
,
'$3'
,
'$1'
,
'$2'
)
s1
=
S
(
'command'
,
'addu'
,
'$3'
,
'$1'
,
'$2'
)
s2
=
S
(
'command'
,
'addu'
,
'$1'
,
'$3'
,
10
)
s2
=
S
(
'command'
,
'addu'
,
'$1'
,
'$3'
,
10
)
s3
=
S
(
'command'
,
'subu'
,
'$3'
,
'$1'
,
5
)
s3
=
S
(
'command'
,
'subu'
,
'$3'
,
'$1'
,
5
)
...
@@ -38,63 +38,44 @@ class TestReachingDefinitions(unittest.TestCase):
...
@@ -38,63 +38,44 @@ class TestReachingDefinitions(unittest.TestCase):
self
.
assertEqual
(
block
.
reach_gen
,
set
([
s2
.
sid
,
s3
.
sid
,
s4
.
sid
]))
self
.
assertEqual
(
block
.
reach_gen
,
set
([
s2
.
sid
,
s3
.
sid
,
s4
.
sid
]))
self
.
assertEqual
(
block
.
reach_kill
,
set
([
s1
.
sid
]))
self
.
assertEqual
(
block
.
reach_kill
,
set
([
s1
.
sid
]))
#def test_create_gen_kill_between_blocks(self):
def
test_create_in_out
(
self
):
# s11 = S('command', 'li', 'a', 3)
s11
=
S
(
'command'
,
'li'
,
'a'
,
3
)
# s12 = S('command', 'li', 'b', 5)
s12
=
S
(
'command'
,
'li'
,
'b'
,
5
)
# s13 = S('command', 'li', 'd', 4)
s13
=
S
(
'command'
,
'li'
,
'd'
,
4
)
# s14 = S('command', 'li', 'x', 100)
s14
=
S
(
'command'
,
'li'
,
'x'
,
100
)
# s15 = S('command', 'blt', 'a', 'b', 'L1')
s15
=
S
(
'command'
,
'beq'
,
'a'
,
'b'
,
'L1'
)
# b1 = B([s11, s12, s13, s14, s15])
s21
=
S
(
'command'
,
'addu'
,
'c'
,
'a'
,
'b'
)
# s21 = S('command', 'addu', 'c', 'a', 'b')
s22
=
S
(
'command'
,
'li'
,
'd'
,
2
)
# s22 = S('command', 'li', 'd', 2)
# b2 = B([s21, s22])
s31
=
S
(
'label'
,
'L1'
)
s32
=
S
(
'command'
,
'li'
,
'c'
,
4
)
# s31 = S('label', 'L1')
s33
=
S
(
'command'
,
'mult'
,
'b'
,
'd'
)
# s32 = S('command', 'li', 'c', 4)
s34
=
S
(
'command'
,
'mflo'
,
'temp'
)
# s33 = S('command', 'mult', 'b', 'd')
s35
=
S
(
'command'
,
'addu'
,
'return'
,
'temp'
,
'c'
)
# s34 = S('command', 'mflo', 'temp')
# s35 = S('command', 'addu', 'return', 'temp', 'c')
b1
,
b2
,
b3
=
find_basic_blocks
([
s11
,
s12
,
s13
,
s14
,
s15
,
s21
,
s22
,
\
# b3 = B([s31, s32, s33, s34, s35])
s31
,
s32
,
s33
,
s34
,
s35
])
# defs = get_defs([b1, b2, b3])
create_in_out
([
b1
,
b2
,
b3
])
# create_gen_kill(b1, defs)
# create_gen_kill(b2, defs)
self
.
assertEqual
(
b1
.
reach_gen
,
set
([
s11
.
sid
,
s12
.
sid
,
s13
.
sid
,
# create_gen_kill(b3, defs)
s14
.
sid
]))
self
.
assertEqual
(
b1
.
reach_kill
,
set
([
s22
.
sid
]))
# self.assertEqual(b1.reach_gen, set([s11.sid, s12.sid, s13.sid, s14.sid]))
self
.
assertEqual
(
b2
.
reach_gen
,
set
([
s21
.
sid
,
s22
.
sid
]))
# self.assertEqual(b1.reach_kill, set([s22.sid]))
self
.
assertEqual
(
b2
.
reach_kill
,
set
([
s13
.
sid
,
s32
.
sid
]))
self
.
assertEqual
(
b3
.
reach_gen
,
set
([
s32
.
sid
,
s34
.
sid
,
s35
.
sid
]))
# self.assertEqual(b2.reach_gen, set([s21.sid, s22.sid]))
self
.
assertEqual
(
b3
.
reach_kill
,
set
([
s21
.
sid
]))
# self.assertEqual(b2.reach_kill, set([s13.sid, s32.sid]))
self
.
assertEqual
(
b1
.
reach_in
,
set
())
# self.assertEqual(b3.reach_gen, set([s32.sid, s34.sid, s35.sid]))
self
.
assertEqual
(
b1
.
reach_out
,
set
([
s11
.
sid
,
s12
.
sid
,
s13
.
sid
,
# self.assertEqual(b3.reach_kill, set([s21.sid]))
s14
.
sid
]))
self
.
assertEqual
(
b2
.
reach_in
,
set
([
s11
.
sid
,
s12
.
sid
,
s13
.
sid
,
#def test_create_in_out(self):
s14
.
sid
]))
# s11 = S('command', 'li', 'a', 3)
self
.
assertEqual
(
b2
.
reach_out
,
set
([
s21
.
sid
,
s22
.
sid
,
s11
.
sid
,
\
# s12 = S('command', 'li', 'b', 5)
s12
.
sid
,
s14
.
sid
]))
# s13 = S('command', 'li', 'd', 4)
self
.
assertEqual
(
b3
.
reach_in
,
set
([
s21
.
sid
,
s22
.
sid
,
s11
.
sid
,
\
# s14 = S('command', 'li', 'x', 100)
s12
.
sid
,
s13
.
sid
,
s14
.
sid
]))
# s15 = S('command', 'blt', 'a', 'b', 'L1')
self
.
assertEqual
(
b3
.
reach_out
,
set
([
s32
.
sid
,
s34
.
sid
,
s35
.
sid
,
\
# b1 = B([s11, s12, s13, s14, s15])
s22
.
sid
,
s11
.
sid
,
s12
.
sid
,
\
s13
.
sid
,
s14
.
sid
]))
# s21 = S('command', 'addu', 'c', 'a', 'b')
# s22 = S('command', 'li', 'd', 2)
# b2 = B([s21, s22])
# s31 = S('label', 'L1')
# s32 = S('command', 'li', 'c', 4)
# s33 = S('command', 'mult', 'b', 'd')
# s34 = S('command', 'mflo', 'temp')
# s35 = S('command', 'addu', 'return', 'temp', 'c')
# b3 = B([s31, s32, s33, s34, s35])
# create_in_out([b1, b2, b3])
# self.assertEqual(b1.reach_in, set())
# self.assertEqual(b1.reach_out, set([s11.sid, s12.sid, s13.sid]))
# self.assertEqual(b2.reach_in, set([s11.sid, s12.sid]))
# self.assertEqual(b2.reach_out, set([s12.sid, s22.sid]))
# self.assertEqual(b3.reach_in, set([s12.sid, s22.sid]))
# self.assertEqual(b3.reach_out, set())
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment