1 % |
|
2 \begin{isabellebody}% |
|
3 \def\isabellecontext{a{\isadigit{6}}}% |
|
4 \isamarkupfalse% |
|
5 % |
|
6 \isamarkupsubsection{Optimising Compiler Verification% |
|
7 } |
|
8 \isamarkuptrue% |
|
9 % |
|
10 \begin{isamarkuptext}% |
|
11 Section 3.3 of the Isabelle tutorial describes an expression compiler for a stack machine. In this exercise we will build and verify an optimising expression compiler for a register machine.% |
|
12 \end{isamarkuptext}% |
|
13 \isamarkuptrue% |
|
14 % |
|
15 \begin{isamarkuptext}% |
|
16 \subsubsection*{The Source Language: Expressions}% |
|
17 \end{isamarkuptext}% |
|
18 \isamarkuptrue% |
|
19 % |
|
20 \begin{isamarkuptext}% |
|
21 The arithmetic expressions we will work with consist of variables, constants, and an arbitrary binary operator \isa{oper}.% |
|
22 \end{isamarkuptext}% |
|
23 \isamarkuptrue% |
|
24 \isacommand{consts}\ oper\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline |
|
25 \isanewline |
|
26 \isamarkupfalse% |
|
27 \isacommand{types}\ var\ {\isacharequal}\ string\isanewline |
|
28 \isanewline |
|
29 \isamarkupfalse% |
|
30 \isacommand{datatype}\ exp\ {\isacharequal}\ \isanewline |
|
31 \ \ \ \ Const\ nat\ \isanewline |
|
32 \ \ {\isacharbar}\ Var\ var\isanewline |
|
33 \ \ {\isacharbar}\ Op\ exp\ exp\isamarkupfalse% |
|
34 % |
|
35 \begin{isamarkuptext}% |
|
36 The state in which an expression is evaluated is modelled by an {\em environment} function that maps variables to constants.% |
|
37 \end{isamarkuptext}% |
|
38 \isamarkuptrue% |
|
39 \isacommand{types}\ env\ {\isacharequal}\ {\isachardoublequote}var\ {\isasymRightarrow}\ nat{\isachardoublequote}\isamarkupfalse% |
|
40 % |
|
41 \begin{isamarkuptext}% |
|
42 Define a function \isa{value} that evaluates an expression in a given environment.% |
|
43 \end{isamarkuptext}% |
|
44 \isamarkuptrue% |
|
45 \isacommand{consts}\ value\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}exp\ {\isasymRightarrow}\ env\ {\isasymRightarrow}\ nat{\isachardoublequote}\isamarkupfalse% |
|
46 % |
|
47 \begin{isamarkuptext}% |
|
48 \subsubsection*{The Register Machine}% |
|
49 \end{isamarkuptext}% |
|
50 \isamarkuptrue% |
|
51 % |
|
52 \begin{isamarkuptext}% |
|
53 As the name suggests, a register machine uses a collection of registers to store intermediate results. There exists a special register, called the accumulator, that serves as an implicit argument to each instruction. The rest of the registers make up the register file, and can be randomly accessed using an index.% |
|
54 \end{isamarkuptext}% |
|
55 \isamarkuptrue% |
|
56 \isacommand{types}\ regIndex\ {\isacharequal}\ nat\isanewline |
|
57 \isanewline |
|
58 \isamarkupfalse% |
|
59 \isacommand{datatype}\ cell\ {\isacharequal}\ \isanewline |
|
60 \ \ \ \ Acc\isanewline |
|
61 \ \ {\isacharbar}\ Reg\ regIndex\isamarkupfalse% |
|
62 % |
|
63 \begin{isamarkuptext}% |
|
64 The state of the register machine is denoted by a function that maps storage cells to constants.% |
|
65 \end{isamarkuptext}% |
|
66 \isamarkuptrue% |
|
67 \isacommand{types}\ state\ {\isacharequal}\ {\isachardoublequote}cell\ {\isasymRightarrow}\ nat{\isachardoublequote}\isamarkupfalse% |
|
68 % |
|
69 \begin{isamarkuptext}% |
|
70 The instruction set for the register machine is defined as follows:% |
|
71 \end{isamarkuptext}% |
|
72 \isamarkuptrue% |
|
73 \isacommand{datatype}\ instr\ {\isacharequal}\ \isanewline |
|
74 \ \ LI\ nat\ \ \ \ \ \ \ \ \isanewline |
|
75 \ \ % |
|
76 \isamarkupcmt{Load Immediate: loads a constant into the accumulator.% |
|
77 } |
|
78 \ \isanewline |
|
79 {\isacharbar}\ LOAD\ regIndex\ \isanewline |
|
80 \ \ % |
|
81 \isamarkupcmt{Loads the contents of a register into the accumulator.% |
|
82 } |
|
83 \isanewline |
|
84 {\isacharbar}\ STORE\ regIndex\ \isanewline |
|
85 \ \ % |
|
86 \isamarkupcmt{Saves the contents of the accumulator in a register.% |
|
87 } |
|
88 \ \isanewline |
|
89 {\isacharbar}\ OPER\ regIndex\ \isanewline |
|
90 \ \ % |
|
91 \isamarkupcmt{Performs the binary operation \isa{oper}.% |
|
92 } |
|
93 \isanewline |
|
94 \ \ \ \ % |
|
95 \isamarkupcmt{The first argument is taken from a register.% |
|
96 } |
|
97 \isanewline |
|
98 \ \ \ \ % |
|
99 \isamarkupcmt{The second argument is taken from the accumulator.% |
|
100 } |
|
101 \ \isanewline |
|
102 \ \ \ \ % |
|
103 \isamarkupcmt{The result of the computation is stored in the accumulator.% |
|
104 } |
|
105 \isamarkupfalse% |
|
106 % |
|
107 \begin{isamarkuptext}% |
|
108 A program is a list of such instructions. The result of running a program is a change of state of the register machine. Define a function \isa{exec} that models this.% |
|
109 \end{isamarkuptext}% |
|
110 \isamarkuptrue% |
|
111 \isacommand{consts}\ exec\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}state\ {\isasymRightarrow}\ instr\ list\ {\isasymRightarrow}\ state{\isachardoublequote}\isamarkupfalse% |
|
112 % |
|
113 \begin{isamarkuptext}% |
|
114 \subsubsection*{Compilation}% |
|
115 \end{isamarkuptext}% |
|
116 \isamarkuptrue% |
|
117 % |
|
118 \begin{isamarkuptext}% |
|
119 The task now is to translate an expression into a sequence of instructions that computes it. At the end of execution, the result should be stored in the accumulator. |
|
120 |
|
121 Before execution, the values of each variable need to be stored somewhere in the register file. A {\it mapping} function maps variables to positions in the register file.% |
|
122 \end{isamarkuptext}% |
|
123 \isamarkuptrue% |
|
124 \isacommand{types}\ map\ {\isacharequal}\ {\isachardoublequote}var\ {\isasymRightarrow}\ regIndex{\isachardoublequote}\isamarkupfalse% |
|
125 % |
|
126 \begin{isamarkuptext}% |
|
127 Define a function \isa{cmp} that compiles an expression into a sequence of instructions. The evaluation should proceed in a bottom-up depth-first manner. |
|
128 |
|
129 State and prove a theorem expressing the correctness of \isa{cmp}. |
|
130 |
|
131 Hints: |
|
132 \begin{itemize} |
|
133 \item The compilation function is dependent on the mapping function. |
|
134 \item The compilation function needs some way of storing intermediate results. It should be clever enough to reuse registers it no longer needs. |
|
135 \item It may be helpful to assume that at each recursive call, compilation is only allowed to use registers with indices greater than a given value to store intermediate results. |
|
136 \end{itemize}% |
|
137 \end{isamarkuptext}% |
|
138 \isamarkuptrue% |
|
139 % |
|
140 \begin{isamarkuptext}% |
|
141 \subsubsection*{Compiler Optimisation: Common Subexpressions}% |
|
142 \end{isamarkuptext}% |
|
143 \isamarkuptrue% |
|
144 % |
|
145 \begin{isamarkuptext}% |
|
146 In the previous section, the compiler \isa{cmp} was allowed to evaluate a subexpression every time it occurred. In situations where arithmetic operations are costly, one may want to compute commonly occurring subexpressions only once. |
|
147 |
|
148 For example, to compute \isa{{\isacharparenleft}a\ op\ b{\isacharparenright}\ op\ {\isacharparenleft}a\ op\ b{\isacharparenright}}, \isa{cmp} was allowed three calls to \isa{oper}, when only two were needed. |
|
149 |
|
150 Develop an optimised compiler \isa{optCmp}, that evaluates every commonly occurring subexpression only once. Prove its correctness.% |
|
151 \end{isamarkuptext}% |
|
152 \isamarkuptrue% |
|
153 \isamarkupfalse% |
|
154 \end{isabellebody}% |
|
155 %%% Local Variables: |
|
156 %%% mode: latex |
|
157 %%% TeX-master: "root" |
|
158 %%% End: |
|