A Provably Correct Compiler Generator

A Provably Correct Compiler Generator

A Provably Correct Compiler Generator Jens Palsberg palsberg@daimi, aau. dk Computer Science Department, Aarhus University Ny Munkegade, DK-8000 Aarhus C, Denmark Abstract the target language from being an independent product, for general use. We have designed, implemented, and proved the This paper addresses the use of independent, correctness of a compiler generator that accepts realistic target languages without type informa- action semantic descriptions of imperative pro- tion in the semantics. The paper also concerns gramming languages. The generated compilers the possibility of proving correctness of a com- emit absolute code for an abstract RISC machine piler generator, thus making correctness proof a language that currently is assembled into code for once-and-for-all effort. the SPAKC and the HP Precision Architecture. We have overcome these problems. We have Our marline language needs no run-time type- designed, implemented, and proved the correct- checking and is thus more realistic than those ness of a compiler generator, called Cantor, that considered in previous compiler proofs. We use accepts action semantic descriptions of program- solely algebraic specifications; proofs are given in ming languages. The generated compilers emit the initial model. absolute code for an abstract KISC [57] ma- chine language without run-time type-checking. The considered subset of action notation, see ap- 1 Introduction pendix A, is suitable for describing imperative programming languages featuring: The previous approaches to proving correctness of compilers for non-trivial languages all use tar- 9Complicated control flow; get code with run-time type-checking. The fol- lowing semantic rule is typical for these target 9Block structure; languages: 9Non-recursive abstractions, such as proce- (FIRST : C, (Vl, v2) : S) ~ (C, vl : S) dures and functions; and The rule describes the semantics of an instruc- 9Static typing. tion that extracts the first component of the For an example of a language description that has top-element of the stack, provided that the top- been processed by Cantor, see appendix B. The element is a pair. If not, then it is implicit that abstract RISC machine language can easily be the executor of the target language halts the ex- expanded into code for existing RISC processors. ecution. Hence, the executor has to do run-time Currently, implementations exist for the SPARC type-checking. [25] and the HP Precision Architecture [42]. Run-time type-checking imposes an unwelcome The technique needed 'for managing without penalty on execution time because more work has run-time type-checking in the target language is to be done by the executor of the target language. the following: It may be argued, though, that the executor can rely on the source language being statically type- 9 Definethe relationships between semantic checked, and thus avoid the run-time type-checks. values in the source and target languages This implies an unwelcome coupling of the source with respect to both a type and a machine and target languages, however, which prevents state. 419 Thus, we define an operation which given a tar- Mosses [35, 33, 34]. Unified algebras allows get value V, a machine state M, and a type T the algebraic specification of both abstract data will yield the sort of source values which have types and operational semantics in a way such type T and are represented by V and M. Here, that initial models are guaranteed to exist, except "sort" can be thought of as "set". For example, when axioms contradict constraints, in which an integer can represent a value of type truth- case no models of the specification exist. We have value-list by pointing to a heap where the list demonstrated that also a non-trivial compiler can components are represented. In this case, our op- be elegantly specified using unified algebras. In eration will yield a sort containing precisely that comparison with structural operational seman- truth-value-list, when given the integer, the type tics and natural semantics, we replace inference "truth-value-list", and the heap. rules by Horn clauses. The notational difference In contrast, for example Nielson and Nielson is minor, and only superficial differences appear [40] does not involve the machine state when re- in the proofs of theorems about unified specifica~ lating semantic values. Instead, they require tar- tions. Where Despeyroux [10] could prove lem- get values to be "self-contained". Hence, they mas by induction in the length of inference, we in- need to have several types of target values and a stead adopt an axiomatization of Horn logic and target machine that does run-time type checking. prove lemmas by induction in the number of oc- With our approach we can make do with just currences of "modus ponens" in the proof in the one type of target values, namely integer, thus initial model. avoiding run-time type-checking and getting close This paper gives an overview of the author's to the 32-bit words used in the SPARC. Note that forthcoming PhD thesis [44]. Most definitions we do not insert type tags in the run-time repre- and proofs are omitted. For an overview of our sentations of source values; no type information experiments with generating a compiler for a sub- is present at run-time. set of Ads, see [43]. The relationship between semantic values al- In the following section we examine the major lows the proof of a lemma expressing "code well- previous approaches to compiler generation and behavedness" which is essential when reasoning compiler correctness proofs. In section 3 we out- about executions of compiled code. The required line the structure of the Cantor system, includ- type information is useful during compilation, ing the abstract RISC machine language and the too; it is collected by the compiler in a separate action compiler, and we give some performance pass before the code generation. This pass also measures. In section 4 we state the correctness collects the information needed for generating ab- theorem, and finally in section 5 we survey our solute, rather than relative, code. approach to proving correctness in the absence The development of Cantor was guided by the of run-time type-checking in the target language. following principles: We also discuss why we do not treat recursion. The reader is assumed to be familiar with al- Correctness is more important than effi- gebraic specification [12], compilation of block ciency; and structured languages [64], and the notion of a RISC architecture [57]. Specification and proof must be completed before implementation begins. 2 Previous Work As a result, on the positive side, the Cantor im- plementation was quickly produced, and only a 2.1 Compiler Generation handful of minor errors (that had been overlooked in the proof!) had to be corrected before the sys- The problem of compiler generation is usually ap- tem worked. On the negative side, the generated proached by choosing a particular definition of a compilers emit code that run at least two orders specific target language [46]. The task is then to of magnitude slower than corresponding target write and prove the correctness of a compiler for programs produced by handwritten compilers. a notation for defining source languages. Such a The specification and proof of correctness of compiler can then be composed with a language the Cantor system is an experiment in using definition to yield a correct compiler for the lan- the framework of unified algebras, developed by guage, see figure 1. Compiler generators that 420 It appears that the poor performance charac- Language Source definition teristics of the classical compiler generators do P Intermediate language notation not simply stem from inefficient implementations of lambda notation. Mosses observed that deno- rational semantics intertwine model details with Compiler the semantic description, thus blurring the under- lying conceptual analysis [31]. Pleban and Lee further observed that not only a human reader Target but also an automatic compiler generator will language have difficulty in recovering the underlying anal- ysis [48]. Attempts to recover useful information Figure 1: Semantics-directed compiler genera- from lambda expressions include Schmidt's work tion. on detecting so-called single-threaded store ar- guments and stack single-threaded environment operate in this way are often called semantics- arguments [52, 54], and the binding-time analy- directed compiler generators. The Cantor sys- sis of Nielson and Nielson [41]. Despite that, it tem described in this paper is an example of a seems unlikely that the performance characteris- semantics-directed compiler generator. It accepts tics of compiler generators based on denotational language definitions written in action notation, semantics soon will be improved beyond that of and it outputs compilers that emit code in an existing such systems. abstract RISC machine language. A number of compiler generators have been The traditional approach to compiler genera- built that produce compilers of a quality that tion is based on denotational semantics [53]. Ex- compare well with commercially available com- amples of existing compiler generators based on pilers. Major examples are the CAT system of this idea include Mosses' Semantics Implementa- Schmidt and VSller [55, 56], the compiler gen- tion System (SIS) [29], Paulson's Semantics Pro- erator of Kelsey and Hudak [21], and the Mess cessor (PSP) [45, 46], and Wand's Semantic Pro- system of Pleban and Lee [47, 23, 49, 22]. These totyping System (SPS) [62]. In SIS, the lambda approaches are based on rather ad hoc notations expressions are executed by a direct implemen- for defining languages, and they lack correctness tation of beta-reduction; in PSP and SPS they proofs, like the classical systems. They indicate, are compiled into SECD and Scheme code, re- however, that better performance of the produced spectively. There are no considerations of the compiler is obtained when: possible correctness of either the implementation Some model details are omitted from a lan- of beta-reduction, the translations to SECD or guage definition; and Scheme code, or the implementation of SECD or Scheme.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    17 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us