Преглед изворни кода

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

Taddeus Kroes пре 14 година
родитељ
комит
620544ccf0
4 измењених фајлова са 16 додато и 54 уклоњено
  1. 8 48
      report/report.tex
  2. 2 1
      src/optimize/advanced.py
  3. 3 3
      src/statement.py
  4. 3 2
      tests/test_statement.py

+ 8 - 48
report/report.tex

@@ -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
 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
 primary concern, this is not a big problem.
 
@@ -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
 constructions. This is done repeatedly until there are no more changes.
 
-After all possible global optimizations are done, the program is separated into
+After all possible global optimizations are done, the program is seperated into
 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
 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
 the writer, which writes the instructions back to Assembly and saves the file
 so we can let xgcc compile it.
 
-\section{Testing}
-
-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.
+\section{Results}
 
-Also available is a coverage report. This report shows how much of the code has
-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{pi.c}
 
-\subsection{Ouput comparison}
+\subsection{acron.c}
 
-In order to check whether the optimization does not change the functioning of
-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.
+\subsection{whet.c}
 
-\section{Results}
+\subsection{slalom.c}
 
-The following results have been obtained:\\
-\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$
+\subsection{clinpack.c}
 
 \section{Conclusion}
 

+ 2 - 1
src/optimize/advanced.py

@@ -141,7 +141,7 @@ def fold_constants(block):
 
         if s.name == 'li':
             # 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)
             else:
                 register[s[0]] = s[1]
@@ -175,6 +175,7 @@ def fold_constants(block):
             known.append((s[0], register[s[0]]))
         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]
 

+ 3 - 3
src/statement.py

@@ -154,7 +154,7 @@ class Statement:
 
     def get_def(self):
         """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'):
             return [self[1]]
@@ -178,7 +178,7 @@ class Statement:
         if (self.is_branch() \
                 and not self.is_command(*['bc1f', 'bc1t', 'bct', 'bcf'])) \
                 or self.is_store() or self.is_compare() \
-                or self.is_command(*['mult', 'div', 'dsz', 'mtc1']):
+                or self.is_command(*['mult', 'dsz', 'mtc1']):
             if self.name == 'dsz':
                 m = re.match('^[^(]+\(([^)]+)\)$', self[0])
 
@@ -206,7 +206,7 @@ class Statement:
         # Case arg2
         if self.is_double_arithmetic() or self.is_set_if_less() \
                 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):
                     use.append(self[2])
 

+ 3 - 2
tests/test_statement.py

@@ -99,8 +99,9 @@ class TestStatement(unittest.TestCase):
         a = ['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', 'div', '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', 'la', 'a', '16($fp)').get_def(), a)
@@ -130,7 +131,7 @@ class TestStatement(unittest.TestCase):
         self.assertEqual(S('command', 'subu', '$3', '$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', 'beq', '$1', '$2', '$L1').get_use(), \
                 arg2)