The whole compiler and its proof of semantic preservation
Require Cexec.
Translation passes.
Require Initializers.
Require SimplExpr.
Require SimplLocals.
Require Cshmgen.
Require Cshmannotgen.
Require Cshmstackgen.
Require Cshmdefgen.
Require Cminorgen.
Require Selection.
Require RTLgen.
Require Tailcall.
Require Inlining.
Require Renumber.
Require Constprop.
Require CSE.
Require CSE2.
Require Deadcode.
Require Unusedglob.
Require RTLdefgen.
Require Allocation.
Require Tunneling.
Require Linearize.
Require CleanupLabels.
Require Debugvar.
Require Stacking.
Require Asmgen.
Proofs of semantic preservation.
Require SimplExprproof.
Require SimplLocalsproof.
Require Cshmgenproof.
Require Cshmannotgenproof.
Require Cminorgenproof.
Require Selectionproof.
Require RTLgenproof.
Require Tailcallproof.
Require Inliningproof.
Require Renumberproof.
Require Constpropproof.
Require CSEproof.
Require Deadcodeproof.
Require Unusedglobproof.
Require Allocproof.
Require Tunnelingproof.
Require Linearizeproof.
Require CleanupLabelsproof.
Require Debugvarproof.
Require Stackingproof.
Require Asmgenproof.
Command-line flags.
Import Compopts.
Annotations passes
Require CsharpminorAnalysis.
Import Utf8 String Coqlib Errors Smallstep.
Pretty-printers (defined in Caml).
Parameter print_Clight:
Clight.program ->
unit.
Parameter print_Cminor:
Z ->
Cminor.program ->
unit.
Parameter print_RTL:
Z ->
RTL.program ->
unit.
Parameter print_LTL:
LTL.program ->
unit.
Parameter print_Mach:
Mach.program ->
unit.
Open Local Scope string_scope.
Composing the translation passes
We first define useful monadic composition operators,
along with funny (but convenient) notations.
Definition apply_total (
A B:
Type) (
x:
res A) (
f:
A ->
B) :
res B :=
match x with Error msg =>
Error msg |
OK x1 =>
OK (
f x1)
end.
Definition apply_partial (
A B:
Type)
(
x:
res A) (
f:
A ->
res B) :
res B :=
match x with Error msg =>
Error msg |
OK x1 =>
f x1 end.
Notation "
a @@@
b" :=
(
apply_partial _ _ a b) (
at level 50,
left associativity).
Notation "
a @@
b" :=
(
apply_total _ _ a b) (
at level 50,
left associativity).
Definition print {
A:
Type} (
printer:
A ->
unit) (
prog:
A) :
A :=
let unused :=
printer prog in prog.
Definition time {
A B:
Type} (
name:
string) (
f:
A ->
B) :
A ->
B :=
f.
Definition total_if {
A:
Type}
(
flag:
unit ->
bool) (
f:
A ->
A) (
prog:
A) :
A :=
if flag tt then f prog else prog.
Definition partial_if {
A:
Type}
(
flag:
unit ->
bool) (
f:
A ->
res A) (
prog:
A) :
res A :=
if flag tt then f prog else OK prog.
We define three translation functions for whole programs: one
starting with a C program, one with a Cminor program, one with an
RTL program. The three translations produce Asm programs ready for
pretty-printing and assembling.
Definition transf_rtl_program (
f:
RTL.program) :
res Asm.program :=
OK f
@@
print (
print_RTL 0)
@@
total_if Compopts.optim_tailcalls (
time "
Tail calls"
Tailcall.transf_program)
@@
print (
print_RTL 1)
@@@
time "
Inlining"
Inlining.transf_program
@@
print (
print_RTL 2)
@@
time "
Renumbering"
Renumber.transf_program
@@
print (
print_RTL 3)
@@
total_if Compopts.optim_constprop (
time "
Constant propagation"
Constprop.transf_program)
@@
print (
print_RTL 4)
@@
total_if Compopts.optim_constprop (
time "
Renumbering"
Renumber.transf_program)
@@
print (
print_RTL 5)
@@@
partial_if Compopts.optim_CSE (
time "
CSE"
CSE.transf_program)
@@
print (
print_RTL 6)
@@@
partial_if Compopts.optim_redundancy (
time "
Redundancy elimination"
Deadcode.transf_program)
@@
print (
print_RTL 7)
@@@
time "
Unused globals"
Unusedglob.transform_program
@@
print (
print_RTL 8)
@@@
time "
Register allocation"
Allocation.transf_program
@@
print print_LTL
@@
time "
Branch tunneling"
Tunneling.tunnel_program
@@@
time "
CFG linearization"
Linearize.transf_program
@@
time "
Label cleanup"
CleanupLabels.transf_program
@@@
partial_if Compopts.debug (
time "
Debugging info for local variables"
Debugvar.transf_program)
@@@
time "
Mach generation"
Stacking.transf_program
@@
print print_Mach
@@@
time "
Asm generation"
Asmgen.transf_program.
Definition transf_rtl_program2 (
f:
RTL.program) :
res Asm.program :=
OK f
@@
print (
print_RTL 0)
@@
total_if Compopts.optim_tailcalls (
time "
Tail calls"
Tailcall.transf_program)
@@
print (
print_RTL 1)
@@@
time "
Inlining"
Inlining.transf_program
@@
print (
print_RTL 2)
@@
time "
Renumbering"
Renumber.transf_program
@@
print (
print_RTL 3)
@@
total_if Compopts.optim_constprop (
time "
Constant propagation"
Constprop.transf_program)
@@
print (
print_RTL 4)
@@
total_if Compopts.optim_constprop (
time "
Renumbering"
Renumber.transf_program)
@@
print (
print_RTL 5)
@@@
partial_if Compopts.optim_CSE (
time "
CSE"
CSE2.transf_program)
@@
print (
print_RTL 6)
@@@
partial_if Compopts.optim_redundancy (
time "
Redundancy elimination"
Deadcode.transf_program)
@@
print (
print_RTL 7)
@@@
time "
Unused globals"
Unusedglob.transform_program
@@
print (
print_RTL 8)
@@@
time "
Register allocation"
Allocation.transf_program
@@
print print_LTL
@@
time "
Branch tunneling"
Tunneling.tunnel_program
@@@
time "
CFG linearization"
Linearize.transf_program
@@
time "
Label cleanup"
CleanupLabels.transf_program
@@@
partial_if Compopts.debug (
time "
Debugging info for local variables"
Debugvar.transf_program)
@@@
time "
Mach generation"
Stacking.transf_program
@@
print print_Mach
@@@
time "
Asm generation"
Asmgen.transf_program.
Definition transf_rtl_program_def (
f:
RTL.program) :
res Asm.program :=
OK f
@@
print (
print_RTL 0)
@@
total_if Compopts.optim_tailcalls (
time "
Tail calls"
Tailcall.transf_program)
@@
print (
print_RTL 1)
@@@
time "
Inlining"
Inlining.transf_program
@@
print (
print_RTL 2)
@@
time "
Renumbering"
Renumber.transf_program
@@
print (
print_RTL 3)
@@
total_if Compopts.optim_constprop (
time "
Constant propagation"
Constprop.transf_program)
@@
print (
print_RTL 4)
@@
total_if Compopts.optim_constprop (
time "
Renumbering"
Renumber.transf_program)
@@
print (
print_RTL 5)
@@@
partial_if Compopts.optim_CSE (
time "
CSE"
CSE.transf_program)
@@
print (
print_RTL 6)
@@@
partial_if Compopts.optim_redundancy (
time "
Redundancy elimination"
Deadcode.transf_program)
@@
print (
print_RTL 7)
@@@
time "
Unused globals"
Unusedglob.transform_program
@@
print (
print_RTL 8)
@@@
time "
RTLdefgen"
RTLdefgen.transf_program
@@
time "
Renumbering"
Renumber.transf_program
@@
print (
print_RTL 9)
@@@
time "
Register allocation"
Allocation.transf_program
@@
print print_LTL
@@
time "
Branch tunneling"
Tunneling.tunnel_program
@@@
time "
CFG linearization"
Linearize.transf_program
@@
time "
Label cleanup"
CleanupLabels.transf_program
@@@
partial_if Compopts.debug (
time "
Debugging info for local variables"
Debugvar.transf_program)
@@@
time "
Mach generation"
Stacking.transf_program
@@
print print_Mach
@@@
time "
Asm generation"
Asmgen.transf_program.
Definition transf_cminor_program (
p:
Cminor.program) :
res Asm.program :=
OK p
@@
print (
print_Cminor 0)
@@@
time "
Instruction selection"
Selection.sel_program
@@@
time "
RTL generation"
RTLgen.transl_program
@@@
transf_rtl_program.
Definition transf_cminor_program2 (
p:
Cminor.program) :
res Asm.program :=
OK p
@@
print (
print_Cminor 0)
@@@
time "
Instruction selection"
Selection.sel_program
@@@
time "
RTL generation"
RTLgen.transl_program
@@@
transf_rtl_program2.
Definition transf_cminor_program_def (
p:
Cminor.program) :
res Asm.program :=
OK p
@@
print (
print_Cminor 0)
@@@
time "
Instruction selection"
Selection.sel_program
@@@
time "
RTL generation"
RTLgen.transl_program
@@@
transf_rtl_program_def.
Definition transf_clight_program (
p:
Clight.program) :
res Asm.program :=
OK p
@@
print print_Clight
@@@
time "
Simplification of locals"
SimplLocals.transf_program
@@@
time "
C#
minor generation"
Cshmgen.transl_program
@@@
time "
C#
minorannot generation"
Cshmannotgen.transl_program
@@@
time "
Cminor generation"
Cminorgen.transl_program
@@@
transf_cminor_program.
Import ToString.
Definition transf_clight_program_def (
p:
Clight.program) :
res Asm.program :=
OK p
@@
print print_Clight
@@@
time "
Simplification of locals"
SimplLocals.transf_program
@@@
time "
C#
minor generation"
Cshmgen.transl_program
@@@
time "
C#
minorannot generation"
Cshmannotgen.transl_program
@@@ (
fun p =>
match time "
Annotation inference" (
CsharpminorAnalysis.vanalysis (
num_dom tt) (
max_concretize tt) (
trace tt) (
verbose tt) (
unroll tt))
p with
| (
tt, (
nil,
log)) =>
time "
C#
minor annotation" (
Annotagen.doit log)
p
| (
_, (
alarms,
_)) =>
Errors.Error (
Errors.msg ("
Alarms during inference."
++
new_line
++ @
ListToString _ (
fun a => (
a tt))
alarms))
end)
@@@
time "
C#
minorannotdef generation" (
Cshmdefgen.transl_program (λ
_,
true))
@@@ (
fun p =>
match time "
Defensive program safety validation" (
CsharpminorAnalysis.vanalysis (
num_dom tt) (
max_concretize tt) (
trace tt) (
verbose tt) (
unroll tt))
p with
| (
_, (
nil,
_)) =>
OK p
| (
_, (
alarms,
_)) =>
DebugLib.print ("
Alarms:"
++
new_line
++ @
ListToString _ (
fun a => (
a tt))
alarms)
(
OK p)
end)
@@@
time "
Cminor generation"
Cminorgen.transl_program
@@@
transf_cminor_program2.
Definition transf_clight_program_def2 (
p:
Clight.program) :
res Asm.program :=
OK p
@@
print print_Clight
@@@
time "
Simplification of locals"
SimplLocals.transf_program
@@@
time "
C#
minor generation"
Cshmgen.transl_program
@@@
time "
C#
minorannot generation"
Cshmannotgen.transl_program
@@@ (
fun p =>
match time "
Annotation inference" (
CsharpminorAnalysis.vanalysis (
num_dom tt) (
max_concretize tt) (
trace tt) (
verbose tt) (
unroll tt))
p with
| (
tt, (
nil,
log)) =>
time "
C#
minor annotation" (
Annotagen.doit log)
p
| (
_, (
alarms,
_)) =>
Errors.Error (
Errors.msg ("
Alarms during inference."
++
new_line
++ @
ListToString _ (
fun a => (
a tt))
alarms))
end)
@@@
time "
Cminor generation"
Cminorgen.transl_program
@@@
transf_cminor_program_def.
Definition transf_c_program (
p:
Csyntax.program) :
res Asm.program :=
OK p
@@@
time "
Clight generation"
SimplExpr.transl_program
@@@
transf_clight_program.
Definition transf_c_program_def (
p:
Csyntax.program) :
res Asm.program :=
OK p
@@@
time "
Clight generation"
SimplExpr.transl_program
@@@
transf_clight_program_def.
Definition transf_c_program_def2 (
p:
Csyntax.program) :
res Asm.program :=
OK p
@@@
time "
Clight generation"
SimplExpr.transl_program
@@@
transf_clight_program_def2.
Force Initializers and Cexec to be extracted as well.
Definition transl_init :=
Initializers.transl_init.
Definition cexec_do_step :=
Cexec.do_step.
The following lemmas help reason over compositions of passes.
Lemma print_identity:
forall (
A:
Type) (
printer:
A ->
unit) (
prog:
A),
print printer prog =
prog.
Proof.
intros;
unfold print.
destruct (
printer prog);
auto.
Qed.
Lemma compose_print_identity:
forall (
A:
Type) (
x:
res A) (
f:
A ->
unit),
x @@
print f =
x.
Proof.
Remark forward_simulation_identity:
forall sem,
forward_simulation sem sem.
Proof.
intros.
apply forward_simulation_step with (
fun s1 s2 =>
s2 =
s1);
intros.
-
auto.
-
exists s1;
auto.
-
subst s2;
auto.
-
subst s2.
exists s1';
auto.
Qed.
Lemma total_if_simulation:
forall (
A:
Type) (
sem:
A ->
semantics) (
flag:
unit ->
bool) (
f:
A ->
A) (
prog:
A),
(
forall p,
forward_simulation (
sem p) (
sem (
f p))) ->
forward_simulation (
sem prog) (
sem (
total_if flag f prog)).
Proof.
Lemma partial_if_simulation:
forall (
A:
Type) (
sem:
A ->
semantics) (
flag:
unit ->
bool) (
f:
A ->
res A) (
prog tprog:
A),
partial_if flag f prog =
OK tprog ->
(
forall p tp,
f p =
OK tp ->
forward_simulation (
sem p) (
sem tp)) ->
forward_simulation (
sem prog) (
sem tprog).
Proof.
Semantic preservation
We prove that the
transf_program translations preserve semantics
by constructing the following simulations:
-
Forward simulations from Cstrategy / Cminor / RTL to Asm
(composition of the forward simulations for each pass).
-
Backward simulations for the same languages
(derived from the forward simulation, using receptiveness of the source
language and determinacy of Asm).
-
Backward simulation from Csem to Asm
(composition of two backward simulations).
These results establish the correctness of the whole compiler!
Theorem transf_rtl_program_correct:
forall p tp,
transf_rtl_program p =
OK tp ->
forward_simulation (
RTL.semantics p) (
Asm.semantics tp)
*
backward_simulation (
RTL.semantics p) (
Asm.semantics tp).
Proof.
Theorem transf_cminor_program_correct:
forall p tp,
transf_cminor_program p =
OK tp ->
forward_simulation (
Cminor.semantics p) (
Asm.semantics tp)
*
backward_simulation (
Cminor.semantics p) (
Asm.semantics tp).
Proof.
Theorem transf_clight_program_correct:
forall p tp,
transf_clight_program p =
OK tp ->
forward_simulation (
Clight.semantics1 p) (
Asm.semantics tp)
*
backward_simulation (
Clight.semantics1 p) (
Asm.semantics tp).
Proof.
Theorem transf_cstrategy_program_correct:
forall p tp,
transf_c_program p =
OK tp ->
forward_simulation (
Cstrategy.semantics p) (
Asm.semantics tp)
*
backward_simulation (
atomic (
Cstrategy.semantics p)) (
Asm.semantics tp).
Proof.
Theorem transf_c_program_correct:
forall p tp,
transf_c_program p =
OK tp ->
backward_simulation (
Csem.semantics p) (
Asm.semantics tp).
Proof.
Definition transf_rtl_program_def1 (
f:
RTL.program) :
res Asm.program :=
OK f
@@
print (
print_RTL 0)
@@
total_if Compopts.optim_tailcalls (
time "
Tail calls"
Tailcall.transf_program)
@@
print (
print_RTL 1)
@@@
time "
Inlining"
Inlining.transf_program
@@
print (
print_RTL 2)
@@
time "
Renumbering"
Renumber.transf_program
@@
print (
print_RTL 3)
@@
total_if Compopts.optim_constprop (
time "
Constant propagation"
Constprop.transf_program)
@@
print (
print_RTL 4)
@@
total_if Compopts.optim_constprop (
time "
Renumbering"
Renumber.transf_program)
@@
print (
print_RTL 5)
@@@
partial_if Compopts.optim_CSE (
time "
CSE_def1"
CSE2.transf_program)
@@
print (
print_RTL 6)
@@@
partial_if Compopts.optim_redundancy (
time "
Redundancy elimination"
Deadcode.transf_program)
@@
print (
print_RTL 7)
@@@
time "
Unused globals"
Unusedglob.transform_program
@@
print (
print_RTL 8)
@@@
time "
Register allocation"
Allocation.transf_program
@@
print print_LTL
@@
time "
Branch tunneling"
Tunneling.tunnel_program
@@@
time "
CFG linearization"
Linearize.transf_program
@@
time "
Label cleanup"
CleanupLabels.transf_program
@@@
partial_if Compopts.debug (
time "
Debugging info for local variables"
Debugvar.transf_program)
@@@
time "
Mach generation"
Stacking.transf_program
@@
print print_Mach
@@@
time "
Asm generation"
Asmgen.transf_program.
Definition transf_cminor_program_def1 (
p:
Cminor.program) :
res Asm.program :=
OK p
@@
print (
print_Cminor 1)
@@@
time "
Instruction selection"
Selection.sel_program
@@@
time "
RTL generation"
RTLgen.transl_program
@@@
transf_rtl_program_def1.
Definition transf_clight_program_def1 (
p:
Clight.program) :
res Asm.program :=
OK p
@@
print print_Clight
@@@
time "
Simplification of locals"
SimplLocals.transf_program
@@@
time "
C#
minor generation"
Cshmgen.transl_program
@@@
time "
C#
minorannot generation"
Cshmannotgen.transl_program
@@@
time "
C#
minorannotdef generation" (
Cshmdefgen.transl_program (
fun _ =>
true))
@@@
time "
Cminor generation"
Cminorgen.transl_program
@@@
transf_cminor_program_def1.
Definition transf_c_program_def1 (
p:
Csyntax.program) :
res Asm.program :=
OK p
@@@
time "
Clight generation"
SimplExpr.transl_program
@@@
transf_clight_program_def1.
Definition transf_rtl_program_def2 (
f:
RTL.program) :
res Asm.program :=
OK f
@@
print (
print_RTL 0)
@@
total_if Compopts.optim_tailcalls (
time "
Tail calls"
Tailcall.transf_program)
@@
print (
print_RTL 1)
@@@
time "
Inlining"
Inlining.transf_program
@@
print (
print_RTL 2)
@@
time "
Renumbering"
Renumber.transf_program
@@
print (
print_RTL 3)
@@
total_if Compopts.optim_constprop (
time "
Constant propagation"
Constprop.transf_program)
@@
print (
print_RTL 4)
@@
total_if Compopts.optim_constprop (
time "
Renumbering"
Renumber.transf_program)
@@
print (
print_RTL 5)
@@@
partial_if Compopts.optim_CSE (
time "
CSE"
CSE.transf_program)
@@
print (
print_RTL 6)
@@@
partial_if Compopts.optim_redundancy (
time "
Redundancy elimination"
Deadcode.transf_program)
@@
print (
print_RTL 7)
@@@
time "
Unused globals"
Unusedglob.transform_program
@@
print (
print_RTL 8)
@@@
time "
RTLdefgen"
RTLdefgen.transf_program
@@
time "
Renumbering"
Renumber.transf_program
@@
print (
print_RTL 9)
@@@
time "
Register allocation"
Allocation.transf_program
@@
print print_LTL
@@
time "
Branch tunneling"
Tunneling.tunnel_program
@@@
time "
CFG linearization"
Linearize.transf_program
@@
time "
Label cleanup"
CleanupLabels.transf_program
@@@
partial_if Compopts.debug (
time "
Debugging info for local variables"
Debugvar.transf_program)
@@@
time "
Mach generation"
Stacking.transf_program
@@
print print_Mach
@@@
time "
Asm generation"
Asmgen.transf_program.
Definition transf_cminor_program_def2 (
p:
Cminor.program) :
res Asm.program :=
OK p
@@
print (
print_Cminor 2)
@@@
time "
Instruction selection"
Selection.sel_program
@@@
time "
RTL generation"
RTLgen.transl_program
@@@
transf_rtl_program_def2.