Reference. Deriving efficient program transformations from rewrite rules
An efficient optimizing compiler can perform many cascading rewrites in a single pass, using auxiliary data structures such as variable binding maps, delayed substitutions, and occurrence counts. Such optimizers often perform transformations according to relatively simple rewrite rules, but the subtle interactions between the data structures needed for efficiency make them tricky to write and trickier to prove correct. We present a system for semi-automatically deriving both an efficient program transformation and its correctness proof from a list of rewrite rules and specifications of the auxiliary data structures it requires. Dependent types ensure that the holes left behind by our system (for the user to fill in) are filled in correctly, allowing the user low-level control over the implementation without having to worry about getting it wrong. We implemented our system in Coq (though it could be implemented in other logics as well), and used it to write optimization passes that perform uncurrying, inlining, dead code elimination, and static evaluation of case expressions and record projections. The generated implementations are sometimes faster, and at most 40% slower, than hand-written counterparts on a small set of benchmarks; in some cases, they require significantly less code to write and prove correct.
Cite
Cites 33 works (2 here)
With notes (2)
CakeML: A verified implementation of ML kumar_cakeml_2014
We have developed and mechanically verified an ML system called CakeML, which supports a substantial subset of Standard ML. CakeML is implemented as an interactive read-eval-print loop (REPL) in x86-64 machine code. Our correctness theorem ensures that this REPL implementation prints only those results permitted by the semantics of CakeML. Our verification effort touches on a breadth of topics including lexing, parsing, type checking, incremental and dynamic compilation, garbage collection, arbitraryprecision arithmetic, and compiler bootstrapping.
Finding and Understanding Bugs in C Compilers yangFindingUnderstandingBugs
Compilers should be correct. To improve the quality of C compilers, we created Csmith, a randomized test-case generation tool, and spent three years using it to find compiler bugs. During this period we reported more than 325 previously unknown bugs to compiler developers. Every compiler we tested was found to crash and also to silently generate wrong code when presented with valid input. In this paper we present our compiler-testing tool and the results of our bug-hunting study. Our first contribution is to advance the state of the art in compiler testing. Unlike previous tools, Csmith generates programs that cover a large subset of C while avoiding the undefined and unspecified behaviors that would destroy its ability to automatically find wrong-code bugs. Our second contribution is a collection of qualitative and quantitative results about the bugs we have found in open-source C compilers.
External (31)
- The MetaCoq Project (2020)
- The Third International Workshop on Coq for Programming Languages (CoqPL) (2017)
- Shrink fast correctly! (2017)
- Learning Syntactic Program Transformations from Examples (2016)
- Optimization with Flambda (OCaml manual, chapter 21) (2016)
- Pilsner: a compositionally verified compiler for a higher-order imperative language (2015)
- Specifying and verifying program transformations with PTRANS (PhD thesis) (2014)
- Verified heap theorem prover by paramodulation (2012)
- The CompCert verified compiler (2012)
- Equations: A Dependent Pattern-Matching Compiler (2010)
- Generating compiler optimizations from proofs (2010)
- Compiling with continuations, continued (2007)
- Operational semantics for multi-language programs (2007)
- Cobalt: A Language for Writing Provably-Sound Compiler Optimizations (2005)
- Automated soundness proofs for dataflow analyses and transformations via local rules (2005)
- EDUCATIONAL PEARL: A Nanopass framework for compiler education (2005)
- Shrinking Reductions in SML.NET (2004)
- Secrets of the Glasgow Haskell Compiler inliner (2002)
- Pattern Guards and Transformational Patterns (2001)
- Imperative Program Transformation by Rewriting (2001)
- Shrinking lambda expressions in linear time (1997)
- An approach for exploring code improving transformations (1997)
- Functional pearl: The Zipper (1997)
- Loop headers in λ-calculus or CPS (1994)
- Sharlit—a tool for building optimizers (1992)
- Standard ML of New Jersey (1991)
- Efficiently computing static single assignment form and the control dependence graph (1991)
- Macro-by-example: Deriving syntactic transformations from their specifications (1987)
- Symp. on Compiler Construction), 21 (1986)
- Rabbit: a compiler for Scheme (1978)
- Domain-specific program generation