Procházet zdrojové kódy

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

Taddeus Kroes před 14 roky
rodič
revize
fb30dd2f77
2 změnil soubory, kde provedl 86 přidání a 48 odebrání
  1. 0 3
      TODO.txt
  2. 86 45
      report/report.tex

+ 0 - 3
TODO.txt

@@ -1,3 +0,0 @@
-Jump/branch end of basoc block, Label begin of BB
-instr writing to register and immediatly overwritten by second instruction
-    (general case of second optimization in table practicum assignment)

+ 86 - 45
report/report.tex

@@ -16,7 +16,6 @@
 
 \begin{document}
 \maketitle
-\pagebreak
 \tableofcontents
 \pagebreak
 
@@ -38,17 +37,18 @@ the keywords in to an action.
 
 There are two general types of of optimizations of the assembly code, global
 optimizations and optimizations on a so-called basic block. These optimizations
-will be discussed seperatly
+will be discussed separately
 
 \subsection{Global optimizations}
 
 We only perform one global optimization, which is optimizing branch-jump
 statements. The unoptimized Assembly code contains sequences of code of the
 following structure:
-\begin{lstlisting}
+\begin{verbatim}
     beq ...,$Lx
     j $Ly
-$Lx:   ...\end{lstlisting}
+$Lx:   ...
+\end{verbatim}
 This is inefficient, since there is a jump to a label that follows this code.
 It would be more efficient to replace the branch statement with a \texttt{bne}
 (the opposite case) to the label used in the jump statement. This way the jump
@@ -69,8 +69,8 @@ for a piece of code not containing any branches or jumps.
 
 To create a basic block, you need to define what is the leader of a basic
 block. We call a statement a leader if it is either a jump/branch statement, or
-the target of such a statement. Then a basic block runs from one leader
-(not including this leader) until the next leader (including this leader). !!!!
+the target of such a statement. Then a basic block runs from one leader until
+the next leader.
 
 There are quite a few optimizations we perform on these basic blocks, so we
 will describe the types of optimizations here in stead of each optimization.
@@ -79,14 +79,14 @@ will describe the types of optimizations here in stead of each optimization.
 
 These are optimizations that simply look for a certain statement or pattern of
 statements, and optimize these. For example,
-\begin{lstlisting}
+\begin{verbatim}
 mov $regA,$regB
 instr $regA, $regA,... 
-\end{lstlisting}
+\end{verbatim}
 can be optimized into
-\begin{lstlisting}
+\begin{verbatim}
 instr $regA, $regB,...
-\end{lstlisting}
+\end{verbatim}
 since the register \texttt{\$regA} gets overwritten by the second instruction
 anyway, and the instruction can easily use \texttt{\$regB} in stead of
 \texttt{\$regA}. There are a few more of these cases, which are the same as
@@ -107,12 +107,12 @@ We search from the end of the block up for instructions that are eligible for
 CSE. If we find one, we check further up in the code for the same instruction,
 and add that to a temporary storage list. This is done until the beginning of
 the block or until one of the arguments of this expression is assigned. Now all
-occurences of this expression can be replaced by a move of a new variable that
-is generated above the first occurence, which contains the value of the
+occurrences of this expression can be replaced by a move of a new variable that
+is generated above the first occurrence, which contains the value of the
 expression.
 
 This is a less efficient method, but because the basic blocks are in general
-not very large and the exectution time of the optimizer is not a primary
+not very large and the execution time of the optimizer is not a primary
 concern, this is not a big problem.
 
 \section{Implementation}
@@ -129,23 +129,51 @@ The program has three steps, parsing the Assembly code into a datastructure we
 can use, the so-called Intermediate Representation, performing optimizations on
 this IR and writing the IR back to Assembly.
 
-\subsection{Parsing with PLY}
+\subsection{Parsing}
 
+The parsing is done with PLY, which allows us to perform Lex-Yacc tasks in
+Python by using a Lex-Yacc like syntax. This way there is no need to combine
+languages like we should do otherwise since Lex and Yacc are coupled with C.
 
+The decision was made to not recognize exactly every possible instruction in
+the parser, but only if something is for example a command, a comment or a gcc
+directive. We then transform per line to a object called a Statement. A
+statement has a type, a name and optionally a list of arguments. These
+statements together form a statement list, which is placed in another object
+called a Block. In the beginning there is one block for the entire program, but
+after global optimizations this will be separated in several blocks that are
+the basic blocks.
 
 \subsection{Optimizations}
 
+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 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.
 
+After the division in basic blocks, optimizations are performed on each of
+these basic blocks. This is also done repeatedly, since some times several
+steps can be done to optimize something.
 
 \subsection{Writing}
 
+Once all the optimizations have been done, the IR needs to be rewritten into
+Assembly code, so the xgcc crosscompiler can make binary code out of it.
 
+The writer expects a list of statements, so first the blocks have to be
+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{Results}
 
 \subsection{pi.c}
 
-\subsection{arcron.c}
+\subsection{acron.c}
 
 \subsection{whet.c}
 
@@ -157,42 +185,55 @@ this IR and writing the IR back to Assembly.
 
 \appendix
 
-\section{Total list of optimizations}
+\section{List of all optimizations}
 
 \label{opt}
 
 \textbf{Global optimizations}
 
-\begin{tabular}{| c c c |}
-\hline
-\begin{lstlisting}
-    beq ...,$Lx
-    j $Ly
-$Lx:   ...\end{lstlisting} & $\Rightarrow$ & \begin{lstlisting}
-    bne ...,$Ly
-$Lx:   ...\end{lstlisting}\\
-\hline
-\begin{lstlisting}
-    bne ...,$Lx
-    j $Ly
-$Lx:   ...\end{lstlisting} & $\Rightarrow$ & \begin{lstlisting}
-    beq ...,$Ly
-$Lx:   ...\end{lstlisting}\\
-\hline
-\end{tabular}\\
-\\
+\begin{verbatim}
+    beq ...,$Lx             bne ...,$Ly
+    j $Ly               ->  $Lx:   ...
+$Lx:   ...
+
+
+    bne ...,$Lx             beq ...,$Ly
+    j $Ly               ->  $Lx:   ...
+$Lx:   ...
+\end{verbatim}
 \textbf{Simple basic block optimizations}
 
-\begin{tabular}{|c c c|}
-\hline
-\begin{lstlisting}
-    beq ...,$Lx
-    j $Ly
-$Lx:   ...\end{lstlisting} & $\Rightarrow$ & \begin{lstlisting}
-    bne ...,$Ly
-$Lx:   ...\end{lstlisting}\\
-\hline
-\end{tabular}\\
-\\
+\begin{verbatim}
+mov $regA,$regA         ->  --- // remove it
+
+
+mov $regA,$regB         ->  instr $regA, $regB,...
+instr $regA, $regA,...
+
+
+instr $regA,...             instr $4,...
+mov [$4-$7], $regA      ->  jal XXX
+jal  XXX
+
+
+sw $regA,XXX            ->  sw $regA, XXX
+ld $regA,XXX
+
+
+shift $regA,$regA,0     ->  --- // remove it
+
+
+add $regA,$regA,X       ->  lw ...,X($regA)
+lw ...,0($regA)
+\end{verbatim}
 \textbf{Advanced basic block optimizations}
+
+\begin{verbatim}
+# Common subexpression elimination
+addu $regA, $regB, 4        addu $regD, $regB, 4
+...                         move $regA, $regD
+Code not writing $regB  ->  ...
+...                         ...
+addu $regC, $regB, 4        move $regC, $regD
+\end{verbatim}
 \end{document}