Permalink
Browse files

Merge branch 'master' of github.com:kmill/dcc

  • Loading branch information...
2 parents 48b5bc6 + c9b35b6 commit 37e1b7c87cec83c6f730b9436d92f6f009feab44 @dvorak42 dvorak42 committed Mar 20, 2012
Showing with 71 additions and 17 deletions.
  1. +45 −6 doc/writeup-project-2.tex
  2. +6 −2 src/Assembly.hs
  3. +20 −9 src/LowIR.hs
View
@@ -10,35 +10,74 @@
\section {Overview}
+The Purpose of this project was to extend the semantic checker
+produced at the end of the last project to actually generate correct
+x86 assembly code.
+
+Our Code Generator follows a four step process. The first step is to
+translate the Hybrid AST and Symbol Table produced as the output of
+the previous project into a Mid-Level IR that represents the code as a
+graph of Basic Blocks. The second step is to translate the mid IR into
+a Low-Level IR that translates the higher level instructions used in
+the mid IR to low level assembly instructions. The low IR initially
+makes use of a number of ``Symbolic Registers'', so the next step of
+code generation is to use a basic Register Allocator to replace these
+symbolic registers with real registers and memory locations. Finally,
+the low IR with all symbolic registers allocated is translated
+directly into assembly language.
+
+The rest of this document outlines each of these steps in detail. The
+mid level IR is described in Section~\ref{sec:midir}. The low level IR
+is described in Section~\ref{sec:lowir}. The register allocator is
+described in Section~\ref{sec:regalloc}. The assembly generator is
+described in Section~\ref{sec:assembly}.
\section{Division of Work}
\label{sec:division}
+The work was divided as follows. Kyle Miller designed and wrote the
+mid IR and the low IR and wrote all of the translation functions
+between them. Kyle also implemented several optimizations. Alec
+Thomson wrote an initial assembly template that provided some skeleton
+code for eventual assembly generation. Alec also wrote the simple
+register allocator. Patrick Hulin and Steven Valdez wrote the code to translate the
+low ir directly into assembly code. Each member of the team spent a
+considerable amount of time debugging the final product.
+
\section{Assumptions about Spec}
\label{sec:assumptions}
+The following were assumptions we made about the Decaf spec while we
+wrote the code generator:
+
+\begin{itemize}
+\item The Array index expression is evaluated before the assignment expression.
+\item Binary operators are evaluated left to right.
+\item Method arguments are evaluated right to left.
+\end{itemize}
+
\section {Mid IR}
+\label{sec:midir}
TODO: Totally put an image of one of the graphs created by graphviz here
\section {Low IR}
+\label{sec:lowir}
TODO: Totally put an image of one of the graphs created by graphviz here
\section {Register Allocation}
+\label{sec:regalloc}
The code makes use of a very simple register allocator to eliminate
-all symbolic registers from the Low IR.
+all symbolic registers from the Low IR. It's behavior is very
+simple. It
\section {Assembly Generation}
+\label{sec:assembly}
\section {Test Plan}
-\begin{itemize}
-\item Evaluate Array index expression before assignment expression.
-\item Binary operators evaluate left to right.
-\item Evaluate method arguments right to left.
-\end{itemize}
\end{document}
View
@@ -77,7 +77,7 @@ instrCode (StoreMem pos addr oper) = [ binInstr "movq" oper addr ]
instrCode (LoadMem pos reg addr) = [ binInstr "movq" addr reg ]
-instrCode (LowCall pos label _) = [ " call " ++ label ]
+instrCode (LowCall pos label _) = [ " call " ++ (methodLabel label) ]
instrCode (LowCallout pos label nargs) = [ binInstr "movq" (LowOperConst 0) RAX
, " call " ++ label ]
@@ -142,6 +142,10 @@ basicBlockCode method irGraph@(Graph graphMap _) vertex = [bLabel ++ ":"] ++ ins
-- Translate method
--
+methodLabel :: String -> String
+methodLabel "main" = "main"
+methodLabel name = "method_" ++ name
+
calleeSaved :: [X86Reg]
calleeSaved = [ RBP, RBX, R12, R13, R14, R15 ]
@@ -151,7 +155,7 @@ methodCode (LowIRMethod pos retP name numArgs localsSize irGraph) =
--"main" -> ["movq $1, %rax", "movq $0, %rbx", "int $0x80"]
_ -> ["leave", "ret"]
in
- [ name ++ ":"
+ [ (methodLabel name) ++ ":"
, "enter $(" ++ (show localsSize) ++ "), $0" ] ++
map (unInstr "pushq") calleeSaved ++
[ "jmp " ++ (vertexLabel name (startVertex irGraph))] ++
View
@@ -256,19 +256,21 @@ loadStringLit pos str
trace' x = trace ("***\n" ++ show x) x
simplifyLIR :: LowIRGraph -> LowIRGraph
-simplifyLIR lir = normalizeBlocks lir -- $ mergeRegs $ normalizeBlocks lir
+simplifyLIR lir = normalizeBlocks $ mergeRegs $ normalizeBlocks lir
mergeRegs :: LowIRGraph -> LowIRGraph
mergeRegs lir
- = let keepRegs = Map.map (\(keep,_,_) -> keep) (determineExtents lir)
- lir' = mapGWithKey (\k bb -> fixBB (fromJust $ Map.lookup k keepRegs) bb) lir
+ = let extents = (determineExtents lir)
+ keepRegs = Map.map (\(keep,_,_) -> keep) extents
+ lir' = mapGWithKey (\k bb -> fixBB (fromJust $ Map.lookup k extents) bb) lir
in lir'
- where fixBB alive bb
- = let alive' = (X86Reg RSP):(X86Reg RBP):alive
- (trees, test) = evalLowInstrs alive' Map.empty []
+ where fixBB (keep,dead,alive) bb
+ = let keep' = (X86Reg RSP):(X86Reg RBP):keep
+ (trees, test) = evalLowInstrs keep' Map.empty []
(blockCode bb) (blockTest bb)
bb' = BasicBlock trees test (blockTestPos bb)
- in evalLowIRForest alive' (blockTestPos bb) trees test
+ bb'' = evalLowIRForest keep' (blockTestPos bb) trees test
+ in bb'' --trace ("\n+++1\n" ++ show bb ++ "\n+++2" ++ show bb' ++ "\n+++3" ++ show bb'') bb''
getFreshSReg :: [RegName] -> RegName
@@ -310,6 +312,14 @@ setReplaceables n@(LowCallNode _ _ _) [] = n
setReplaceables n@(LowCalloutNode _ _ _) [] = n
setReplaceables _ _ = error "setReplaceables :-("
+getUsedRegisters :: LowIRTree -> [RegName]
+getUsedRegisters (LowOperNode (OperReg reg)) = [reg]
+getUsedRegisters (LowOperNode _) = []
+getUsedRegisters node = concatMap getUsedRegisters (getReplaceables node)
+
+getForestUsedRegisters :: [LowIRTree] -> [RegName]
+getForestUsedRegisters trees = concatMap getUsedRegisters trees
+
instance Show LowIRTree where
show t = render $ pp t
@@ -461,8 +471,9 @@ evalLowInstrs alive regMap evaled (instr:instrs) test
evalLowIRForest :: [RegName] -> SourcePos -> [LowIRTree] -> IRTest LowIRTree
-> LowBasicBlock
-evalLowIRForest used pos nodes test
- = let code = concatMap (evalLowIRTree used) nodes
+evalLowIRForest keep pos nodes test
+ = let used = keep ++ getForestUsedRegisters nodes
+ code = concatMap (evalLowIRTree used) nodes
(testcode, test') = evalLowIRTreeTest used pos test
in BasicBlock (code ++ testcode) test' pos

0 comments on commit 37e1b7c

Please sign in to comment.