Section: New Results
Formal verification of compilers
The Compcert verified compiler for the C language
In the context of our work on compiler verification (see section 3.3.1 ), since 2005 we have been developing and formally verifying a moderately-optimizing compiler for a large subset of the C programming language, generating assembly code for the PowerPC architecture. This compiler comprises a back-end part, translating the Cminor intermediate language to PowerPC assembly and reusable for source languages other than C  , and a front-end translating the Clight subset of C to Cminor  . The compiler is mostly written within the specification language of the Coq proof assistant, from which Coq's extraction facility generates executable Caml code. The compiler comes with a 40000-line, machine-checked Coq proof of semantic preservation: the semantics of the generated PowerPC code matches that of the source Clight program.
The main activity on the Compcert compiler this year was to extend the proof of semantic preservation to the case of source programs that do not terminate. The original proof was restricted to terminating source programs because the semantics given to the source and intermediate languages were formalized using natural semantics (big-step operational semantics), which cannot describe non-terminating executions. To lift this limitation, Xavier Leroy reformulated these semantics using transition semantics (small-step operational semantics) for the low-level intermediate languages (RTL, LTL, Mach) and coinductive natural semantics (see section 6.4.2 ) for the source language Clight and the high-level intermediate languages C#minor and Cminor. Xavier Leroy then reworked the proofs of semantic preservation for every pass of the Compcert compiler, adapting them to the new semantics and extending them to the non-terminating case. This was a major overhaul of the Compcert development, requiring one third of its 40000 lines to be rewritten, but many of these rewrites were semi-systematic in nature and proof reuse was globally higher than expected.
In addition, two parts of the Compcert development that are potentially reusable in other projects were modularized and documented in articles submitted to the Journal of Automated Reasoning [Oops!] , [Oops!] . The first of these papers, by Sandrine Blazy and Xavier Leroy, describes the Coq formalization of the C-like memory model used throughout the Compcert development, and its uses to reason about program transformations that modify the memory behavior of the program. The second paper, by Laurence Rideau, Bernard Serpette and Xavier Leroy, focuses on the compilation algorithm for parallel assignments used in Compcert, and its surprisingly delicate Coq proof of correctness.
Verified translation validation
Certified translation validation provides an alternative to proving semantics preservation for the transformations involved in a certified compiler. Instead of proving that a given transformation is correct, we validate it a posteriori , i.e. we verify that the transformed program behaves like the original. The validation algorithm is described using the Coq proof assistant and proved correct, i.e. that it only accepts transformed programs semantically equivalent to the original. In contrast, the program transformation itself can be implemented in any language and does not need to be proved correct.
Jean-Baptiste Tristan, under the supervision of Xavier Leroy, is investigating this approach in the case of instruction scheduling transformations. Instruction scheduling is a family of low-level optimizations that reorder the program instructions so as to exploit instruction-level parallelism and reduce overall execution time. The validation algorithm for instruction scheduling is based on symbolic execution of the original and transformed programs  . This year, Jean-Baptiste Tristan successfully built and proved correct a validator for trace scheduling, a scheduling optimization that moves instructions across basic block boundaries. This result is detailed in a paper that will be presented at POPL 2008 [Oops!] . It provides evidence that verified translation validation is a viable alternative to the formal verification of program transformations.
We are now trying to extend this approach in two different directions. On one hand, we would like to show that we can apply this method on even more challenging program transformations: technically, when code modifications cross loop boundaries. On the other hand we would like to show that a validator can be reused for a family of transformations, thus reducing the cost of its formal verification. In this perspective, we are now trying to validate a family of transformations that globally eliminate partial redundancies.
Verification of a compiler front-end for Mini-ML
As part of her PhD thesis and under Xavier Leroy's supervision, Zaynah Dargaye investigates the development and formal verification of a translator from a small call-by-value functional language (Mini-ML) to Cminor. Mini-ML features functions as first-class values, constructed data types and shallow pattern-matching, making it an adequate target for Coq's program extraction facility.
Last year, Zaynah Dargaye developed and proved correct in Coq a prototype compiler from Mini-ML to Cminor, featuring lifting of function definitions to top-level and closure conversion, as well as one optimization pass: the transformation of curried functions into n -ary functions. A paper describing this optimization and its proof of correctness was presented at JFLA 2007 [Oops!] .
This year, Zaynah Dargaye attacked the issue of interfacing the generated code with an exact (non-conservative) garbage collector. This required extensive changes to the compiler and its proofs of correctness. In particular, the generated code must be instrumented to register memory roots with the garbage collector, and the correctness proofs must be re-done to account for the fact that memory blocks unreachable from these roots can be reclaimed at any allocation point. The need for root registration led her to investigate intermediate representations where all such roots are named and can be communicated to the garbage collector via a dynamically-maintained data structure.
The first such intermediate representation is continuation-passing style (CPS). Zaynah Dargaye and Xavier Leroy developed a CPS transformation and its Coq proof of correctness, utilizing a novel proof technique based on natural semantics. This result was presented at the LPAR 2007 conference [Oops!] .
Zaynah Dargaye and Xavier Leroy then developed an alternate named intermediate representation based on monadic form and inspired by ANF. Compared with ANF, this monadic intermediate representation has the advantage to remain compatible with direct-style function invocations. Zaynah Dargaye conducted Coq proofs of correctness of the transformation that puts programs in monadic form, and of the translation from this monadic form to a variant of the Cminor target language that features abstract notions of garbage collection and memory roots.
Verified garbage collection
High-level languages that automate memory management, such as ML or Java, are a good basis for developing high-assurance software systems. But to have confidence in systems built on top of garbage collection, we must have confidence in the garbage collector itself. The goal of this research is to produce a fully verified, realistic GC implementation, specifically for the a collector in written the Cminor intermediate language and linked into the existing Compcert compiler framework.
Verifying GC code is a special case of the more general problem of verifying pointer-based imperative programs. Andrew Tolmach has been exploring an approach to this problem based on a monadic encoding of imperative code within Gallina, Coq's term language (the calculus of inductive constructions). Code written in Gallina can be verified directly using the full power of Coq; it can then be extracted to an executable form. Coq's existing extraction mechanism only generates pure code, but it can be adjusted or replaced to generate imperative code instead. As an initial proof of concept, Tolmach has used this technique to verify and extract code for a number of simple imperative programs, including a very simple mark-and-sweep GC. Further work is required to determine whether this approach will scale to more realistic collectors, and to address the formal verification of the extraction process itself.
As part of his Master's internship [Oops!] and under the supervision of Xavier Leroy and Andrew Tolmach, Tahina Ramananandro investigated the formal verification of a “mark and sweep” garbage collector. To enable a future integration of this collector in the verified compiler from Mini-ML to Cminor described above, this garbage collector was written directly in the Cminor intermediate language. Its Coq proof of correctness is challenging, involving several layers of refinement from an abstract model of garbage collection down to the very concrete memory model of Cminor. Tahina Ramananandro investigated approaches to reason about code fragments directly written in Gallina (the specification language of the Coq proof assistant), and proving that these fragments do the same memory operations as the actual implementation code with respect to the semantics of Cminor. Tahina Ramananandro also modeled a concrete heap structure within the Compcert memory model.
Formal verification of register allocation algorithms
Benoît Robillard, as part of his Master's internship and under Sandrine Blazy's supervision, studied a new algorithm for register allocation and spilling, based on integer linear programming (ILP). A greedy graph coloring algorithm that is adapted to the Compcert register allocator has been specified in Coq. The optimality of the solution computed by this algorithm (when there is one) has also been proved in Coq. A paper describing these results was accepted for presentation at JFLA 2008 [Oops!] .
In the CompCert certified compiler, the register validation is performed by untrusted Caml code, whose results are validated a posteriori in Coq. Benoît Robillard and Sandrine Blazy developed an interface between a commercial ILP solver and the a posteriori validation of CompCert. Three mathematical programs modeling register allocation were implemented in this solver and tested on large examples provided by Andrew Appel. These encouraging results were presented at the Journées Graphes et Algorithmes [Oops!] . As part of the beginning of his PhD, Benoît Robillard currently works on improving these mathematical programs, based on graph reduction and also on cutting-plane algorithms.