The GRIN project: A highly optimising back end for lazy functional languages
Low level optimisations from conventional compiler technology often give very poor results when applied to code from lazy functional languages, mainly because of the completely different structure of the code, unknown control flow, etc. A novel approach to compiling laziness is needed.
We describe a complete back end for lazy functional languages, which uses various interprocedural optimisations to produce highly optimised code. The main features of our new back end are the following. It uses a monadic intermediate code, called GRIN (Graph Reduction Intermediate Notation). This code has a very “functional flavour”, making it well suited for analysis and program transformations, but at the same time provides the “low level” machinery needed to express many concrete implementation concerns. Using a heap points-to analysis, we are able to eliminate most unknown control flow due to evals (i.e., forcing of closures) and applications of higher order functions, in the program. A transformation machinery uses many, each very simple, GRIN program transformations to optimise the intermediate code. Eventually, the GRIN code is translated into RISC machine code, and we apply an interprocedural register allocation algorithm, followed by many other low level optimisations. The elimination of unknown control flow, made earlier, will help a lot in making the low level optimisations work well.
Preliminary measurements look very promising: we are currently twice as fast as the Glasgow Haskell Compiler for some small programs. Our approach still gives us many opportunities for further optimisations (though yet unexplored).
KeywordsCall Graph Register Allocation High Order Function Graph Reduction Lazy Evaluation
Unable to display preview. Download preview PDF.
- [AJ89]A. W. Appel and T. Jim. Continuation-passing, closure-passing style. In Conference Record of the 16th Annual ACM Symposium on Principles of Programming Languages, pages 293–302, Austin, TX, January 1989.Google Scholar
- [App92]A. W. Appel. Compiling With Continuations. Cambridge University Press, 1992.Google Scholar
- [ASU86]A. V. Aho, R. Sethi, and J. D. Ullman. Compilers: Principles, Techniques, Tools. Addison-Wesley Publishing Company, Reading, Mass., 1986.Google Scholar
- [BCKT89]Preston Briggs, Keith D. Cooper, Ken Kennedy, and L. Torczon. Coloring heuristics for register allocation. In Proceedings of the ACM SIGPLAN '89 Conference on Programming Language Design and Implementation, volume 24, pages 275–284, Portland, OR, June 1989.Google Scholar
- [Boq95a]Urban Boquist. Interprocedural Register Allocation for Lazy Functional Languages. In Proceedings of the 1995 Conference on Functional Programming Languages and Computer Architecture, La Jolla, California, June 1995. URL: http://www.cs.chalmers.se/~boquist/fpca95.ps.Google Scholar
- [Boq95b]Urban Boquist. Interprocedural Register Allocation for Lazy Functional Languages. Licentiate Thesis, Chalmers University of Technology, Mars 1995. URL: http://wWw.cs.chalmers.se/∼boquist/lic.ps.Google Scholar
- [CFR+91]Ron Cytron, Jeanne Ferrante, Barry K. Rosen, Mark N. Wegman, and F. Kenneth Zadeck. Efficiently computing static single assignment form and the control dependence graph. ACM Transactions on Programming Languages and Systems, 13(4), October 1991.Google Scholar
- [Cho88]Fred C. Chow. Minimizing Register Usage Penalty at Procedure Calls. In Proceedings of the SIGPLAN '88 Conference on Programming Language Design and Implementation, June 1988.Google Scholar
- [CKT86]Keith D. Cooper, Ken Kennedy, and Linda Torczon. The impact of interprocedural analysis and optimizations in the R(n) programming environment. ACM Transactions on Programming Languages and Systems, 8(4):419–523, October 1986.Google Scholar
- [Fax95]Karl-Filip Faxén. Optimizing lazy functional programs using flowinference. In A. Mycroft, editor, Static Analysis Symposium (SAS), volume 883 of LNCS. Springer Verlag, September 1995. URL: http://www.it.kth.se/~kff/fvSAS.ps.Google Scholar
- [Fax96]Karl-Filip Faxén. Flow Inference, Code generation, and Garbage Collection for Lazy Functional Languages. Licentiate Thesis, Department of Teleinformatics, Royal Institute of Technology, Stockholm, January 1996. URL: http://www.it.kth.se/~kff/TRITA-IT-9601.ps.Google Scholar
- [FW87]J. Fairbairn and S. C. Wray. TIM: A simple, lazy abstract machine to execute supercombinators. In Proceedings of the 1987 Conference on Functional Programming Languages and Computer Architecture, Portland, Oregon, September 1987.Google Scholar
- [GM86]P.B. Gibbons and Steven S. Muchnick. Efficient instruction scheduling for a pipelined architecture. In Proceedings of the ACM SIGPLAN '86 Symposium on Compiler Construction, volume 21, pages 11–16, Palo Alto, CA, June 1986.Google Scholar
- [Joh84]T. Johnsson. Efficient Compilation of Lazy Evaluation. In Proceedings of the SIGPLAN '84 Symposium on Compiler Construction, pages 58–69, Montreal, 1984. Available from http://www.cs.chalmers.se/∼johnsson.Google Scholar
- [Joh91]Thomas Johnsson. Analysing Heap Contents in a Graph Reduction Intermediate Language. In S.L. Peyton Jones, G. Hutton, and C.K. Holst, editors, Proceedings of the Glasgow Functional Programming Workshop, Ullapool 1990, Workshops in Computing, pages 146–171. Springer Verlag, August 1991. Available from http://www.cs.chalmers.se/~johnsson.Google Scholar
- [KH89]R. Kelsey and P. Hudak. Realistic compilation by program transformation. In Conference Record of the 16th Annual ACM Symposium on Principles of Programming Languages, pages 281–292, Austin, TX, January 1989.Google Scholar
- [PJ92]S. L. Peyton Jones. Implementing lazy functional languages on stock hardware: the Spineless Tagless G-machine. Journal of Functional Programming, 2(2), April 1992.Google Scholar
- [PJ96]Simon Peyton Jones. Compiling Haskell by program transformation: a report from the trenches. In Proceedings of the European Symposium on Programming, Linköping, April 1996.Google Scholar
- [PJL91]Simon L. Peyton Jones and John Launchbury. Unboxed values as first class citizens in a non-strict functional language. In Functional Programming and Computer Architecture, Sept 1991.Google Scholar
- [PJPS96]Simon Peyton Jones, Will Partain, and André Santos. Let-floating: moving bindings to give faster programs. In Proceedings of the International Conference on Functional Programming, Philadelphia, 1996.Google Scholar
- [SH89]Peter A. Steenkiste and John L. Hennessy. A Simple Interprocedural Register Allocation and Its Effectiveness for LISP. ACM Transactions on Programming Languages and Systems, 11(1):1–32, January 1989.Google Scholar
- [SH97]Marc Shapiro and Susan Horwitz. Fast and Accurate Flow-Insensitive Points-To Analysis. In Conference Record of POPL'97: 24nd ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, Paris, France, January 1997.Google Scholar
- [SNVGP91]Sjaak Smetsers, Erik Nöcker, John van Groningen, and Rinus Plasmeyer. Generating efficient code for lazy functional languages. In Proceedings of the 1991 Conference on Functional Programming Languages and Computer Architecture, Cambridge, Massachusetts, July 1991.Google Scholar
- [Wad92]P. Wadler. The essence of functional programming. In Proceedings 1992 Symposium on principles of Programming Languages, pages 1–14, Albuquerque, New Mexico, 1992.Google Scholar
- [Wal86]David W. Wall. Global Register Allocation at Link Time. In Proceedings of the SIGPLAN '86 Symposium on Compiler Construction, pages 264–275, New York, 1986.Google Scholar