566 research outputs found
Implementing and reasoning about hash-consed data structures in Coq
We report on four different approaches to implementing hash-consing in Coq
programs. The use cases include execution inside Coq, or execution of the
extracted OCaml code. We explore the different trade-offs between faithful use
of pristine extracted code, and code that is fine-tuned to make use of OCaml
programming constructs not available in Coq. We discuss the possible
consequences in terms of performances and guarantees. We use the running
example of binary decision diagrams and then demonstrate the generality of our
solutions by applying them to other examples of hash-consed data structures
Unboxed data constructors -- or, how cpp decides a halting problem
We propose a new language feature for ML-family languages, the ability to
selectively *unbox* certain data constructors, so that their runtime
representation gets compiled away to just the identity on their argument.
Unboxing must be statically rejected when it could introduce *confusions*,
that is, distinct values with the same representation.
We discuss the use-case of big numbers, where unboxing allows to write code
that is both efficient and safe, replacing either a safe but slow version or a
fast but unsafe version.
We explain the static analysis necessary to reject incorrect unboxing
requests.
We present our prototype implementation of this feature for the OCaml
programming language, discuss several design choices and the interaction with
advanced features such as Guarded Algebraic Datatypes.
Our static analysis requires expanding type definitions in type expressions,
which is not necessarily normalizing in presence of recursive type definitions.
In other words, we must decide normalization of terms in the first-order
lambda-calculus with recursion. We provide an algorithm to detect
non-termination on-the-fly during reduction, with proofs of correctness and
completeness.
Our termination-monitoring algorithm turns out to be closely related to the
normalization strategy for macro expansion in the `cpp` preprocessor.Comment: Author version, to appear at POPL 202
An efficient implementation of lazy functional programming languages based on the generalized intensional transformation
Αυτή η εργασία διερευνά θεωρητικά και πρακτικά ζητήματα της αλληλεπίδρασης
μεταξύ (ευρέως γνωστών και νέων) τεχνικών μεταγλώττισης, όπως ο γενικευμένος
νοηματικός μετασχηματισμός, ο μετασχηματισμός σε συναρτησιακά αντικείμενα, η
ξεχωριστή μεταγλώττιση και η λάμβδα άρση. Ένας πειραματικός μεταγλωττιστής για
τη γλώσσα Haskell (GIC), ο οποίος χρησιμοποιεί τις τεχνικές αυτές, δίνει τη
δυνατότητα σε νέες ιδέες να υλοποιηθούν και να αξιολογηθούν μέσα σε ένα
πρακτικό πλαίσιο. Ως μέρος αυτής της δουλειάς πραγματοποιήθηκαν διάφορες
προσθήκες και αλλαγές στο μεταγλωττιστή, είτε προκειμένου να γίνει ο
μεταγλωττιστής πληρέστερος είτε προκειμένου να βελτιωθεί ο τελικός κώδικας που
παράγεται από το LAR back-end του μεταγλωττιστή.This dissertation investigates theoretical and practical issues of the
integration between (well-known and novel) compilation techniques, such as the
generalized intensional transformation, defunctionalization, separate
compilation, and lambda lifting. An experimental Haskell compiler (GIC), which
incorporates these techniques, serves as a workbench allowing ideas to be
demonstrated and evaluated in a practical context. Within the scope of this
work, several additions and changes were made to the compiler either towards
enchancing the tool’s robustness or towards the optimization of the code
generated by the compiler’s LAR back-end
Comparing Tag Scheme Variations Using an Abstract Machine Generator
In this paper we study, in the context of a WAM-based abstract machine for Prolog, how variations in the encoding of type information in tagged words and in their associated basic operations impact performance and memory usage. We use a high-level language to specify encodings and the associated operations. An automatic generator constructs both the abstract machine using this encoding and the associated Prolog-to-byte code compiler. Annotations in this language make it possible to impose constraints on the final representation of tagged words, such as the effectively addressable space (fixing, for example, the word size of the target processor /architecture), the layout of the tag and value bits inside the tagged word, and how the basic operations are implemented. We evaluate large number of combinations of the different parameters in two scenarios: a) trying to obtain an optimal general-purpose abstract machine and b) automatically generating a specially-tuned abstract machine for a particular program. We conclude that we are able to automatically generate code featuring all the optimizations present in a hand-written, highly-optimized abstract machine and we canal so obtain emulators with larger addressable space and better performance
Hybrid eager and lazy evaluation for efficient compilation of Haskell
Thesis (Ph. D.)--Massachusetts Institute of Technology, Dept. of Electrical Engineering and Computer Science, 2002.Includes bibliographical references (p. 208-220).This electronic version was submitted by the student author. The certified thesis is available in the Institute Archives and Special Collections.The advantage of a non-strict, purely functional language such as Haskell lies in its clean equational semantics. However, lazy implementations of Haskell fall short: they cannot express tail recursion gracefully without annotation. We describe resource-bounded hybrid evaluation, a mixture of strict and lazy evaluation, and its realization in Eager Haskell. From the programmer's perspective, Eager Haskell is simply another implementation of Haskell with the same clean equational semantics. Iteration can be expressed using tail recursion, without the need to resort to program annotations. Under hybrid evaluation, computations are ordinarily executed in program order just as in a strict functional language. When particular stack, heap, or time bounds are exceeded, suspensions are generated for all outstanding computations. These suspensions are re-started in a demand-driven fashion from the root. The Eager Haskell compiler translates Ac, the compiler's intermediate representation, to efficient C code. We use an equational semantics for Ac to develop simple correctness proofs for program transformations, and connect actions in the run-time system to steps in the hybrid evaluation strategy.(cont.) The focus of compilation is efficiency in the common case of straight-line execution; the handling of non-strictness and suspension are left to the run-time system. Several additional contributions have resulted from the implementation of hybrid evaluation. Eager Haskell is the first eager compiler to use a call stack. Our generational garbage collector uses this stack as an additional predictor of object lifetime. Objects above a stack watermark are assumed to be likely to die; we avoid promoting them. Those below are likely to remain untouched and therefore are good candidates for promotion. To avoid eagerly evaluating error checks, they are compiled into special bottom thunks, which are treated specially by the run-time system. The compiler identifies error handling code using a mixture of strictness and type information. This information is also used to avoid inlining error handlers, and to enable aggressive program transformation in the presence of error handling.by Jan-Willem Maessen.Ph.D
Dynamic Compilation for Functional Programs
Diese Arbeit behandelt die dynamische, zur Laufzeit stattfindende Übersetzung und Optimierung funktionaler Programme. Ziel der Optimierung ist die erhöhte Laufzeiteffizient der Programme, die durch die compilergesteuerte Eliminierung von Abstraktionen der Programmiersprache erreicht wird. Bei der Implementierung objekt-orientierter Programmiersprachen werden bereits seit mehreren Jahrzehnten Compiler-Techniken zur Laufzeit eingesetzt, um objekt-orientierte Programme effizient ausführen zu können. Spätestens seit der Einführung der Programmiersprache Java und ihres auf einer abstrakten Maschine basierenden Ausführungsmodells hat sich die Praktikabilität dieser Implementierungstechnik gezeigt. Viele Eigenschaften moderner Programmiersprachen konnten erst durch den Einsatz dynamischer Transformationstechniken effizient realisiert werden, wie zum Beispiel das dynamische Nachladen von Programmteilen (auch über Netzwerke), Reflection sowie verschiedene Sicherheitslösungen (z.B. Sandboxing). Ziel dieser Arbeit ist zu zeigen, dass rein funktionale Programmiersprachen auf ähnliche Weise effizient implementiert werden können, und sogar Vorteile gegenüber den allgemein eingesetzten objekt-orientierten Sprachen bieten, was die Effizienz, Sicherheit und Korrektheit von Programmen angeht. Um dieses Ziel zu erreichen, werden in dieser Arbeit Implementierungstechniken entworfen bzw. aus bestehenden Lösungen weiterentwickelt, welche die dynamische Kompilierung und Optimierung funktionaler Programme erlauben: zum einen präsentieren wir eine Programmzwischendarstellung (getypte dynamische Continuation-Passing-Style-Darstellung), welche sich zur dynamischen Kompilierung und Optimierung eignet. Basierend auf dieser Darstellung haben wir eine Erweiterung zur verzögerten und selektiven Codeerzeugung von Programmteilen entwickelt. Der wichtigste Beitrag dieser Arbeit ist die dynamische Spezialisierung zur Eliminierung polymorpher Funktionen und Datenstrukturen, welche die Effizienz funktionaler Programme deutlich steigern kann. Die präsentierten Ergebnisse experimenteller Messungen eines prototypischen Ausführungssystems belegen, dass funktionale Programme effizient dynamisch kompiliert werden können.This thesis is about dynamic translation and optimization of functional programs. The goal of the optimization is increased run-time efficiency, which is obtained by compiler-directed elimination of programming language abstractions. Object-oriented programming languages have been implemented for several decades using run-time compilation techniques. With the introduction of the Java programming language and its virtual machine-based execution model, the practicability of this implementation method for real-world applications has been proved. Many aspects of modern programming languages, such as dynamic loading and linking of code (even across networks), reflection and security solutions (e.g., sandboxing) can be realized efficiently only by using dynamic transformation techniques. The goal of this work is to show that functional programming languages can be efficiently implemented in a similar way, and that these languages even offer advantages when compared to more common object-oriented languages. Efficiency, security and correctness of programs is easier to ensure in the functional setting. Towards this goal, we design and develop implementation techniques to enable dynamic compilation and optimization of functional programming languages: we describe an intermediate representation for functional programs (typed dynamic continuation-passing style), which is well suited for dynamic compilation. Based on this representation, we have developed an extension for incremental and selective code generation. The main contribution of this work shows how dynamic specialization of polymorphic functions and data structures can increase the run-time efficiency of functional programs considerably. We present the results of experimental measurements for a prototypical implementation, which prove that functional programs can efficiently be dynamically compiled
- …