Results 1 - 10
of
16
Space-Efficient Closure Representations
, 1994
"... Many modern compilers implement function calls (or returns) in two steps: first, a closure environment is properly installed to provide access for free variables in the target program fragment; second, the control is transferred to the target by a "jump with arguments (or results)." Closure conversi ..."
Abstract
-
Cited by 65 (12 self)
- Add to MetaCart
Many modern compilers implement function calls (or returns) in two steps: first, a closure environment is properly installed to provide access for free variables in the target program fragment; second, the control is transferred to the target by a "jump with arguments (or results)." Closure conversion, which decides where and how to represent closures at runtime, is a crucial step in compilation of functional languages. We have a new algorithm that exploits the use of compile-time control and data flow information to optimize closure representations. By extensive closure sharing and allocating as many closures in registers as possible, our new closure conversion algorithm reduces heap allocation by 36% and memory fetches for local/global variables by 43%; and improves the already-efficient code generated by the Standard ML of New Jersey compiler by about 17% on a DECstation 5000. Moreover, unlike most other approaches, our new closure allocation scheme satisfies the strong "safe for sp...
For a Better Support of Static Data Flow
- Functional Programming Languages and Computer Architecture
"... . This paper identifies and solves a class of problems that arise in binding time analysis and more generally in partial evaluation of programs: the approximation and loss of static information due to dynamic expressions with static subexpressions. Solving this class of problems yields substantial b ..."
Abstract
-
Cited by 58 (16 self)
- Add to MetaCart
. This paper identifies and solves a class of problems that arise in binding time analysis and more generally in partial evaluation of programs: the approximation and loss of static information due to dynamic expressions with static subexpressions. Solving this class of problems yields substantial binding time improvements and thus dramatically better results not only in the case of partial evaluation but also for static analyses of programs --- this last point actually is related to a theoretical result obtained by Nielson. Our work can also be interpreted as providing a solution to the problem of conditionally static data, the dual of partially static data. We point out which changes in the control flow of a source program may improve its static data flow. Unfortunately they require one to iterate earlier phases of partial evaluation. We show how these changes are subsumed by transforming the source program into continuation-passing style (CPS). The transformed programs get specializ...
Proper Tail Recursion and Space Efficiency
, 1998
"... The IEEE/ANSI standard for Scheme requires implementations to be properly tail recursive. This ensures that portable code can rely upon the space efficiency of continuation-passing style and other idioms. On its face, proper tail recursion concerns the efficiency of procedure calls that occur within ..."
Abstract
-
Cited by 53 (1 self)
- Add to MetaCart
The IEEE/ANSI standard for Scheme requires implementations to be properly tail recursive. This ensures that portable code can rely upon the space efficiency of continuation-passing style and other idioms. On its face, proper tail recursion concerns the efficiency of procedure calls that occur within a tail context. When examined closely, proper tail recursion also depends upon the fact that garbage collection can be asymptotically more space-efficient than Algol-like stack allocation. Proper tail recursion is not the same as ad hoc tail call optimization in stack-based languages. Proper tail recursion often precludes stack allocation of variables, but yields a well-defined asymptotic space complexity that can be relied upon by portable programs. This paper offers a formal and implementation-independent definition of proper tail recursion for Scheme. It also shows how an entire family of reference implementations can be used to characterize related safe-for-space properties, and proves ...
A Dynamic Extent Control Operator for Partial Continuations
- In Conference Record of the Eighteenth Annual ACM Symposium on Principles of Programming Languages
, 1991
"... : A partial continuation is a prefix of the computation that remains to be done. We propose in this paper a new operator which precisely controls which prefix is to be abstracted into a partial continuation. This operator is strongly related to the notion of dynamic extent which we denotationally ch ..."
Abstract
-
Cited by 30 (6 self)
- Add to MetaCart
: A partial continuation is a prefix of the computation that remains to be done. We propose in this paper a new operator which precisely controls which prefix is to be abstracted into a partial continuation. This operator is strongly related to the notion of dynamic extent which we denotationally characterize. Some programming examples are commented and we also show how to express previously proposed control operators. A suggested implementation is eventually discussed. Keywords: continuation, partial continuation, dynamic and indefinite extent, escape feature. Continuations were introduced within denotational semantics to express the "rest of the computation" in these cases where some constructs of a language can alter it. Non local exits or jumps (stop, goto), exception handling, failure semantics in Prolog-like languages are usually described with continuations [Stoy 77, Schmidt 86]. The Scheme language [Rees & Clinger 86] offers procedural first-class continuations with indefinit...
An Empirical and Analytic Study of Stack vs. Heap Cost for Languages with Closures
, 1993
"... We present a comprehensive analysis of all the components of creation, access, and disposal of heap-allocated and stack-allocated activation records. Among our results are: . Although stack frames are known to have a better cache read-miss rate than heap frames, our simple analytical model (backed ..."
Abstract
-
Cited by 29 (2 self)
- Add to MetaCart
We present a comprehensive analysis of all the components of creation, access, and disposal of heap-allocated and stack-allocated activation records. Among our results are: . Although stack frames are known to have a better cache read-miss rate than heap frames, our simple analytical model (backed up by simulation results) shows that the di#erence is too trivial to matter. . The cache write-miss rate of heap frames is very high; we show that a variety of miss-handling strategies (exemplified by specific modern machines) can give good performance, but not all can. . Stacks restrict the flexibility of closure representations (for higher-order functions) in important (and costly) ways. . The extra load placed on the garbage collector by heap-allocated frames is small. . The demands of modern programming languages make stacks complicated to implement e#ciently and correctly. Overall, the execution cost of stack-allocated and heap-allocated frames is similar; but heap frames are s...
Implementation strategies for first-class continuations
- Higher-Order and Symbolic Computation
, 1999
"... Abstract. Scheme and Smalltalk continuations may have unlimited extent. This means that a purely stack-based implementation of continuations, as suffices for most languages, is inadequate. We review several implementation strategies for continuations and compare their performance using instruction c ..."
Abstract
-
Cited by 20 (1 self)
- Add to MetaCart
Abstract. Scheme and Smalltalk continuations may have unlimited extent. This means that a purely stack-based implementation of continuations, as suffices for most languages, is inadequate. We review several implementation strategies for continuations and compare their performance using instruction counts for the normal case and continuation-intensive synthetic benchmarks for other scenarios, including coroutines and multitasking. All of the strategies constrain a compiler in some way, resulting in indirect costs that are hard to measure directly. We use related measurements on a set of benchmarks to calculate upper bounds for these indirect costs.
Compiling Standard ML For Efficient Execution On Modern Machines
, 1994
"... Many language theoreticians have taken great efforts in designing higher-level programming languages that are more elegant and more expressive than conventional languages. However, few of these new languages have been implemented very efficiently. The result is that most software engineers still pre ..."
Abstract
-
Cited by 18 (3 self)
- Add to MetaCart
Many language theoreticians have taken great efforts in designing higher-level programming languages that are more elegant and more expressive than conventional languages. However, few of these new languages have been implemented very efficiently. The result is that most software engineers still prefer to use conventional languages, even though the new higherlevel languages offer a better and simpler programming model. This dissertation concentrates on improving the performance of programs written in Standard ML (SML)---a statically typed functional language---on today's RISC machines. SML poses tough challenges to efficient implementations: very frequent function calls, polymorphic types, recursive data structures, higher-order functions, and first-class continuations. This dissertation presents the design and evaluation of several new compilation techniques that meet these challenges by taking advantage of some of the higher-level language features in SML. Type-directed compilation ...
Compiling Higher-Order Languages into Fully Tail-Recursive Portable C
, 1997
"... Two independently developed implementations of Scheme have been extended to compile into portable C code that implements full tail-recursion. Like other compilers for higher-order languages that implement full tail-recursion, measurements of these systems indicate a performance degradation of a fact ..."
Abstract
-
Cited by 15 (4 self)
- Add to MetaCart
Two independently developed implementations of Scheme have been extended to compile into portable C code that implements full tail-recursion. Like other compilers for higher-order languages that implement full tail-recursion, measurements of these systems indicate a performance degradation of a factor between two and three compared to the native code emitted by the same compilers. We describe the details of the compilation technique for a non-statically typed language (Scheme) and show that the performance difficulty arises largely from the cost of C function calls. In theory, these expensive calls can be eliminated. In practice, however, they are required to avoid excessively long compilation times by modern C compilers, and to support separate compilation. 1 Introduction Two independently-developed Scheme systems (MIT Scheme[7] and Gambit[4]) have been extended to produce portable C output code. The projects were undertaken completely independently with different design goals, yet h...
Shallow Binding Makes Functional Arrays Fast
- ACM SIGPLAN notices
, 1991
"... this paper is the first to make the connection with the literature on variable-binding environments. ..."
Abstract
-
Cited by 14 (2 self)
- Add to MetaCart
this paper is the first to make the connection with the literature on variable-binding environments.
Tail-Recursive Stack Disciplines for an Interpreter
, 1992
"... Many languages, including Scheme, ML, and Haskell, require that their implementations support tail-recursive calls to arbitrary depth. This requirement means that a traditional stack discipline cannot be used for these languages. This paper examines several different methods of implementing proper t ..."
Abstract
-
Cited by 4 (2 self)
- Add to MetaCart
Many languages, including Scheme, ML, and Haskell, require that their implementations support tail-recursive calls to arbitrary depth. This requirement means that a traditional stack discipline cannot be used for these languages. This paper examines several different methods of implementing proper tail recursion in a stack-based interpeter, including passing arguments in a heap, copying arguments to tail-recursive calls, and garbage collecting the stack. Benchmark timings and other run-time statistics are used to compare the different methods. The results show that using a stack is a good idea, and that the overhead of the interpreter largely overshadows the differences in performance of the various stack disciplines. This is a slightly enhanced version of Technical Report NU-CCS-93-03, College of Computer Science, Northeastern University, 1992. 1 The Problem A programming language implementation is properly tail recursive if unbounded iterative computations that are expressed recursi...

