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
620544cc
Commit
620544cc
authored
Dec 30, 2011
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:taddeus/peephole
parents
2aac7d87
9525cbe1
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
16 additions
and
54 deletions
+16
-54
report/report.tex
report/report.tex
+8
-48
src/optimize/advanced.py
src/optimize/advanced.py
+2
-1
src/statement.py
src/statement.py
+3
-3
tests/test_statement.py
tests/test_statement.py
+3
-2
No files found.
report/report.tex
View file @
620544cc
...
@@ -116,7 +116,7 @@ We now add the instruction above the first use, and write the result in a new
...
@@ -116,7 +116,7 @@ We now add the instruction above the first use, and write the result in a new
variable. Then all occurrences of this expression can be replaced by a move of
variable. Then all occurrences of this expression can be replaced by a move of
from new variable into the original destination variable of the instruction.
from new variable into the original destination variable of the instruction.
This is a less efficient method then the
DAG
, but because the basic blocks are
This is a less efficient method then the
dag
, but because the basic blocks are
in general not very large and the execution time of the optimizer is not a
in general not very large and the execution time of the optimizer is not a
primary concern, this is not a big problem.
primary concern, this is not a big problem.
...
@@ -216,7 +216,7 @@ The optimizations are done in two different steps. First the global
...
@@ -216,7 +216,7 @@ The optimizations are done in two different steps. First the global
optimizations are performed, which are only the optimizations on branch-jump
optimizations are performed, which are only the optimizations on branch-jump
constructions. This is done repeatedly until there are no more changes.
constructions. This is done repeatedly until there are no more changes.
After all possible global optimizations are done, the program is sep
a
rated into
After all possible global optimizations are done, the program is sep
e
rated into
basic blocks. The algorithm to do this is described earlier, and means all
basic blocks. The algorithm to do this is described earlier, and means all
jump and branch instructions are called leaders, as are their targets. A basic
jump and branch instructions are called leaders, as are their targets. A basic
block then goes from leader to leader.
block then goes from leader to leader.
...
@@ -236,57 +236,17 @@ concatenated again into a list. After this is done, the list is passed on to
...
@@ -236,57 +236,17 @@ concatenated again into a list. After this is done, the list is passed on to
the writer, which writes the instructions back to Assembly and saves the file
the writer, which writes the instructions back to Assembly and saves the file
so we can let xgcc compile it.
so we can let xgcc compile it.
\section
{
Testing
}
\section
{
Results
}
Of course, it has to be guaranteed that the optimized code still functions
exactly the same as the none-optimized code. To do this, testing is an
important part of out program. We have two stages of testing. The first stage
is unit testing. The second stage is to test whether the compiled code has
exactly the same output.
\subsection
{
Unit testing
}
For almost every piece of important code, unit tests are available. Unit tests
give the possibility to check whether each small part of the program, for
instance each small function, is performing as expected. This way bugs are
found early and very exactly. Otherwise, one would only see that there is a
mistake in the program, not knowing where this bug is. Naturally, this means
debugging is a lot easier.
The unit tests can be run by executing
\texttt
{
make test
}
in the root folder of
the project. This does require the
\texttt
{
textrunner
}
module.
Also available is a coverage report. This report shows how much of the code has
\subsection
{
pi.c
}
been unit tested. To make this report, the command
\texttt
{
make coverage
}
can
be run in the root folder. The report is than added as a folder
\emph
{
coverage
}
in which a
\emph
{
index.html
}
can be used to see the entire report.
\subsection
{
Ouput comparison
}
\subsection
{
acron.c
}
In order to check whether the optimization does not change the functioning of
\subsection
{
whet.c
}
the program, the output of the provided benchmark programs has to be compared
to the output after optimization. If any of these outputs is not equal to the
original output, our optimizations are to aggressive, or there is a bug
somewhere in the code.
\s
ection
{
Results
}
\s
ubsection
{
slalom.c
}
The following results have been obtained:
\\
\subsection
{
clinpack.c
}
\begin{tabular}
{
|c|c|c|c|c|c|
}
\hline
Benchmark
&
Original
&
Optimized
&
Original
&
Optimized
&
Performance
\\
&
Instructions
&
instructions
&
cycles
&
cycles
&
boost(cycles)
\\
\hline
pi
&
134
&
&
13011
&
&
\\
acron
&
&
&
4435687
&
&
\\
dhrystone
&
&
&
2887710
&
&
\\
whet
&
&
&
2864089
&
&
\\
slalom
&
&
&
27270
&
&
\\
clinpack
&
&
&
1547941
&
&
\\
\hline
\end{tabular}
\\
\\
The imput for slalom was 1000 seconds and a minimum of
$
n
=
100
$
\section
{
Conclusion
}
\section
{
Conclusion
}
...
...
src/optimize/advanced.py
View file @
620544cc
...
@@ -141,7 +141,7 @@ def fold_constants(block):
...
@@ -141,7 +141,7 @@ def fold_constants(block):
if
s
.
name
==
'li'
:
if
s
.
name
==
'li'
:
# Save value in register
# Save value in register
if
not
isinstance
(
s
[
1
],
int
):
if
not
isinstance
(
s
[
1
],
int
):
# Negative numbers are stored as int
register
[
s
[
0
]]
=
int
(
s
[
1
],
16
)
register
[
s
[
0
]]
=
int
(
s
[
1
],
16
)
else
:
else
:
register
[
s
[
0
]]
=
s
[
1
]
register
[
s
[
0
]]
=
s
[
1
]
...
@@ -175,6 +175,7 @@ def fold_constants(block):
...
@@ -175,6 +175,7 @@ def fold_constants(block):
known
.
append
((
s
[
0
],
register
[
s
[
0
]]))
known
.
append
((
s
[
0
],
register
[
s
[
0
]]))
elif
s
.
name
==
'mult'
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
# Multiplication/division with constants
print
s
rs
,
rt
=
s
rs
,
rt
=
s
a
,
b
=
register
[
rs
],
register
[
rt
]
a
,
b
=
register
[
rs
],
register
[
rt
]
...
...
src/statement.py
View file @
620544cc
...
@@ -154,7 +154,7 @@ class Statement:
...
@@ -154,7 +154,7 @@ class Statement:
def get_def(self):
def get_def(self):
"""Get the variable that this statement defines, if any."""
"""Get the variable that this statement defines, if any."""
instr = ['
move
', '
addu
', '
subu
', '
li
', '
dmfc1
', '
mov
.
d
']
instr = ['
div
', '
move
', '
addu
', '
subu
', '
li
', '
dmfc1
', '
mov
.
d
']
if self.is_command('
mtc1
'):
if self.is_command('
mtc1
'):
return [self[1]]
return [self[1]]
...
@@ -178,7 +178,7 @@ class Statement:
...
@@ -178,7 +178,7 @@ class Statement:
if (self.is_branch()
\
if (self.is_branch()
\
and not self.is_command(*['
bc1f
', '
bc1t
', '
bct
', '
bcf
']))
\
and not self.is_command(*['
bc1f
', '
bc1t
', '
bct
', '
bcf
']))
\
or self.is_store() or self.is_compare()
\
or self.is_store() or self.is_compare()
\
or self.is_command(*['
mult
', '
d
iv
', '
d
sz
', '
mtc1
']):
or self.is_command(*['
mult
', '
dsz
', '
mtc1
']):
if self.name == '
dsz
':
if self.name == '
dsz
':
m = re.match('
^
[
^
(]
+
\
(([
^
)]
+
)
\
)
$
', self[0])
m = re.match('
^
[
^
(]
+
\
(([
^
)]
+
)
\
)
$
', self[0])
...
@@ -206,7 +206,7 @@ class Statement:
...
@@ -206,7 +206,7 @@ class Statement:
# Case arg2
# Case arg2
if self.is_double_arithmetic() or self.is_set_if_less()
\
if self.is_double_arithmetic() or self.is_set_if_less()
\
or self.is_logical() or self.is_truncate()
\
or self.is_logical() or self.is_truncate()
\
or self.is_command(*['
addu
', '
subu
']):
or self.is_command(*['
addu
', '
subu
'
, '
div
'
]):
if not isinstance(self[2], int):
if not isinstance(self[2], int):
use.append(self[2])
use.append(self[2])
...
...
tests/test_statement.py
View file @
620544cc
...
@@ -99,8 +99,9 @@ class TestStatement(unittest.TestCase):
...
@@ -99,8 +99,9 @@ class TestStatement(unittest.TestCase):
a
=
[
'a'
]
a
=
[
'a'
]
self
.
assertEqual
(
S
(
'command'
,
'move'
,
'a'
,
'b'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'move'
,
'a'
,
'b'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'subu'
,
'a'
,
'b'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'subu'
,
'a'
,
'b'
,
'c'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'addu'
,
'a'
,
'b'
,
'c'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'addu'
,
'a'
,
'b'
,
'c'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'div'
,
'a'
,
'b'
,
'c'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'sll'
,
'a'
,
'b'
,
'c'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'sll'
,
'a'
,
'b'
,
'c'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'srl'
,
'a'
,
'b'
,
'c'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'srl'
,
'a'
,
'b'
,
'c'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'la'
,
'a'
,
'16($fp)'
).
get_def
(),
a
)
self
.
assertEqual
(
S
(
'command'
,
'la'
,
'a'
,
'16($fp)'
).
get_def
(),
a
)
...
@@ -130,7 +131,7 @@ class TestStatement(unittest.TestCase):
...
@@ -130,7 +131,7 @@ class TestStatement(unittest.TestCase):
self
.
assertEqual
(
S
(
'command'
,
'subu'
,
'$3'
,
'$1'
,
'$2'
).
get_use
(),
\
self
.
assertEqual
(
S
(
'command'
,
'subu'
,
'$3'
,
'$1'
,
'$2'
).
get_use
(),
\
arg2
)
arg2
)
self
.
assertEqual
(
S
(
'command'
,
'mult'
,
'$1'
,
'$2'
).
get_use
(),
arg2
)
self
.
assertEqual
(
S
(
'command'
,
'mult'
,
'$1'
,
'$2'
).
get_use
(),
arg2
)
self
.
assertEqual
(
S
(
'command'
,
'div'
,
'$1'
,
'$2'
).
get_use
(),
arg2
)
self
.
assertEqual
(
S
(
'command'
,
'div'
,
'$
3'
,
'$
1'
,
'$2'
).
get_use
(),
arg2
)
self
.
assertEqual
(
S
(
'command'
,
'move'
,
'$2'
,
'$1'
).
get_use
(),
arg1
)
self
.
assertEqual
(
S
(
'command'
,
'move'
,
'$2'
,
'$1'
).
get_use
(),
arg1
)
self
.
assertEqual
(
S
(
'command'
,
'beq'
,
'$1'
,
'$2'
,
'$L1'
).
get_use
(),
\
self
.
assertEqual
(
S
(
'command'
,
'beq'
,
'$1'
,
'$2'
,
'$L1'
).
get_use
(),
\
arg2
)
arg2
)
...
...
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