Staged abstract interpreters: fast and modular whole-program analysis via meta-programming

It is well known that a staged interpreter is a compiler: specializing an interpreter to a given program produces an equivalent executable that runs faster. This connection is known as the first Futamura projection. It is even more widely known that an abstract interpreter is a program analyzer: tweaking an interpreter to run on abstract domains produces a sound static analysis. What happens when we combine these two ideas, and apply specialization to an abstract interpreter? In this paper, we present a unifying framework that naturally extends the first Futamura projection from concrete interpreters to abstract interpreters. Our approach derives a sound staged abstract interpreter based on a generic interpreter with type-level binding-time abstractions and monadic abstractions. By using different instantiations of these abstractions, the generic interpreter can flexibly behave in one of four modes: as an unstaged concrete interpreter, a staged concrete interpreter, an unstaged abstract interpreter, or a staged abstract interpreter. As an example of abstraction without regret, the overhead of these abstraction layers is eliminated in the generated code after staging. We show that staging abstract interpreters is practical and useful to optimize static analysis, all while requiring less engineering effort and without compromising soundness. We conduct three case studies, including a comparison with Boucher and Feeley’s abstract compilation, applications to various control-flow analyses, and a demonstration for modular analysis. We also empirically evaluate the effect of staging on the execution time. The experiment shows an order of magnitude speedup with staging for control-flow analyses.

[1]  Flemming Nielson,et al.  Two-Level Semantics and Code Generation , 1988, Theor. Comput. Sci..

[2]  Jacques Carette,et al.  Finally tagless, partially evaluated: Tagless staged interpreters for simpler typed languages , 2007, Journal of Functional Programming.

[3]  Roberto Giacobazzi,et al.  A²I: abstract² interpretation , 2019, Proc. ACM Program. Lang..

[4]  Marc Feeley,et al.  Abstract Compilation: A New Implementation Paradigm for Static Analysis , 1996, CC.

[5]  Carl Friedrich Bolz,et al.  Tracing the meta-level: PyPy's tracing JIT compiler , 2009, ICOOOLPS@ECOOP.

[6]  Paul Hudak,et al.  Monad transformers and modular interpreters , 1995, POPL '95.

[7]  Matthew Might,et al.  Systematic abstraction of abstract machines , 2011, Journal of Functional Programming.

[8]  Oleg Kiselyov The Design and Implementation of BER MetaOCaml - System Description , 2014, FLOPS.

[9]  Lars Bergstrom,et al.  Practical and effective higher-order optimizations , 2014, ICFP.

[10]  Markus Püschel,et al.  A practical construction for decomposing numerical abstract domains , 2017, Proc. ACM Program. Lang..

[11]  Simon L. Peyton Jones,et al.  Template meta-programming for Haskell , 2002, Haskell '02.

[12]  Walid Taha,et al.  Multi-Stage Programming: Its Theory and Applications , 1999 .

[13]  Flemming Nielson,et al.  Two-Level Semantics and Abstract Interpretation , 1989, Theor. Comput. Sci..

[14]  Flemming Nielson,et al.  Two-level functional languages , 1992, Cambridge tracts in theoretical computer science.

[15]  Nada Amin,et al.  Functional pearl: a SQL to C compiler in 500 lines of code , 2015, ICFP.

[16]  Matthew Might,et al.  Improving flow analyses via ΓCFA: abstract garbage collection and counting , 2006, ICFP '06.

[17]  Kunle Olukotun,et al.  Delite , 2014, ACM Trans. Embed. Comput. Syst..

[18]  Oleg Kiselyov Reconciling Abstraction with High Performance: A MetaOCaml approach , 2018, Found. Trends Program. Lang..

[19]  Patrick Cousot,et al.  Abstract interpretation: a unified lattice model for static analysis of programs by construction or approximation of fixpoints , 1977, POPL.

[20]  Matthew Might,et al.  Optimizing abstract abstract machines , 2012, ICFP.

[21]  David Darais,et al.  Abstracting definitional interpreters (functional pearl) , 2017, Proc. ACM Program. Lang..

[22]  Tiark Rompf,et al.  The Essence of Multi-stage Evaluation in LMS , 2016, A List of Successes That Can Change the World.

[23]  Matthew Might,et al.  Abstracting abstract machines , 2010, ICFP '10.

[24]  Tiark Rompf,et al.  Refunctionalization of abstract abstract machines: bridging the gap between abstract abstract machines and abstract definitional interpreters (functional pearl) , 2018, Proc. ACM Program. Lang..

[25]  Markus Püschel,et al.  Fast polyhedra abstract domain , 2017, POPL.

[26]  Dan Grossman,et al.  Taming the Static Analysis Beast , 2017, SNAPL.

[27]  Matthew Might,et al.  Pushdown control-flow analysis for free , 2016, POPL.

[28]  Walid Taha,et al.  Multi-stage programming with explicit annotations , 1997, PEPM.

[29]  Roberto Giacobazzi,et al.  Analyzing Program Analyses , 2015, POPL.

[30]  Daniel Damian,et al.  Partial Evaluation for Program Analysis , 1998 .

[31]  Paul Chiusano,et al.  Functional Programming in Scala , 2014 .

[32]  Torben Amtoft Partial Evaluation for Constraint-Based Program Analyses , 1999 .

[33]  Patrick Cousot,et al.  Systematic design of program analysis frameworks , 1979, POPL.

[34]  Dominique Devriese,et al.  Monadic abstract interpreters , 2013, PLDI.

[35]  Kunle Olukotun,et al.  Surgical precision JIT compilers , 2014, PLDI.

[36]  Kunle Olukotun,et al.  Flare: Optimizing Apache Spark with Native Compilation for Scale-Up Architectures and Medium-Size Data , 2018, OSDI.

[37]  Kunle Olukotun,et al.  Go Meta! A Case for Generative Programming and DSLs in Performance Critical Systems , 2015, SNAPL.

[38]  Matthias Felleisen,et al.  A calculus for assignments in higher-order languages , 1987, POPL '87.

[39]  David Darais,et al.  Galois transformers and modular abstract interpreters: reusable metatheory for program analysis , 2014, OOPSLA.

[40]  Harry G. Mairson,et al.  Deciding kCFA is complete for EXPTIME , 2008, ICFP.

[41]  Olivier Danvy,et al.  A functional correspondence between evaluators and abstract machines , 2003, PPDP '03.

[42]  Nada Amin,et al.  Collapsing towers of interpreters , 2017, Proc. ACM Program. Lang..

[43]  Philip Wadler,et al.  The essence of functional programming , 1992, POPL '92.

[44]  Thierry Coppey,et al.  Staged parser combinators for efficient data processing , 2014, OOPSLA.

[45]  Martin Odersky,et al.  Lightweight modular staging: a pragmatic approach to runtime code generation and compiled DSLs , 2010, GPCE '10.

[46]  David Darais,et al.  Constructive Galois connections: taming the Galois connection framework for mechanized metatheory , 2016, ICFP.

[47]  Yannis Smaragdakis,et al.  Porting doop to Soufflé: a tale of inter-engine portability for Datalog-based analyses , 2017, SOAP@PLDI.

[48]  Sumit Gulwani,et al.  Program analysis as constraint solving , 2008, PLDI '08.

[49]  Amr Sabry,et al.  The essence of compiling with continuations , 1993, PLDI '93.

[50]  R. Kent Dybvig,et al.  Flow-sensitive type recovery in linear-log time , 2011, OOPSLA '11.

[51]  Patrick Cousot,et al.  The calculational design of a generic abstract interpreter , 1999 .

[52]  Olin Shivers,et al.  The semantics of Scheme control-flow analysis , 1991, PEPM '91.

[53]  Jeremy Yallop,et al.  Staged generic programming , 2017, Proc. ACM Program. Lang..

[54]  Jacques Carette,et al.  Multi-stage programming with functors and monads: eliminating abstraction overhead from generic code , 2005, GPCE'05.

[55]  Matthew Might,et al.  Allocation characterizes polyvariance: a unified methodology for polyvariant control-flow analysis , 2016, ICFP.

[56]  Ben Hardekopf,et al.  Flow-sensitive pointer analysis for millions of lines of code , 2011, International Symposium on Code Generation and Optimization (CGO 2011).

[57]  Yannis Smaragdakis,et al.  Pointer Analysis , 2015, Found. Trends Program. Lang..

[58]  O. Danvy,et al.  Compiling Monads ∗ , 1991 .

[59]  David Darais,et al.  Galois Transformers and Modular Abstract Interpreters , 2014, ArXiv.

[60]  Jan Midtgaard,et al.  Control-flow analysis of functional programs , 2007, CSUR.

[61]  Patrick Cousot,et al.  Modular Static Program Analysis , 2002, CC.

[62]  Bernhard Scholz,et al.  Soufflé: On Synthesis of Program Analyzers , 2016, CAV.

[63]  Olin Shivers,et al.  Control flow analysis in scheme , 1988, PLDI '88.

[64]  Sebastian Erdweg,et al.  Compositional soundness proofs of abstract interpreters , 2018, Proc. ACM Program. Lang..

[65]  Neil D. Jones,et al.  What Not to Do When Writing an Interpreter for Specialisation , 1996, Dagstuhl Seminar on Partial Evaluation.

[66]  Emir Pasalic,et al.  DSL implementation using staging and monads , 1999, DSL '99.

[67]  Peter Sestoft,et al.  Partial evaluation and automatic program generation , 1993, Prentice Hall international series in computer science.

[68]  Olin Shivers,et al.  CFA2: A Context-Free Approach to Control-Flow Analysis , 2010, ESOP.

[69]  Kunle Olukotun,et al.  Forge: generating a high performance DSL implementation from a declarative specification , 2013, GPCE '13.

[70]  Mads Rosendahl,et al.  Abstract Interpretation as a Programming Language , 2013, Festschrift for Dave Schmidt.

[71]  R. Giacobazzi,et al.  A2I: Abstract2 Interpretation , 2019 .

[72]  Tiark Rompf,et al.  How to Architect a Query Compiler, Revisited , 2018, SIGMOD Conference.

[73]  Eugenio Moggi,et al.  Notions of Computation and Monads , 1991, Inf. Comput..

[74]  Stéphane Ducasse,et al.  Tracing vs. partial evaluation: comparing meta-compilation approaches for self-optimizing interpreters , 2015, OOPSLA.

[75]  Chung-chieh Shan,et al.  Shonan challenge for generative programming: short position paper , 2013, PEPM '13.

[76]  Yannis Smaragdakis,et al.  Stream fusion, to completeness , 2017, POPL.

[77]  Walid Taha,et al.  Implementing Multi-stage Languages Using ASTs, Gensym, and Reflection , 2003, GPCE.

[78]  Yoshihiko Futamura,et al.  Partial Evaluation of Computation Process--An Approach to a Compiler-Compiler , 1999, High. Order Symb. Comput..

[79]  Tiark Rompf,et al.  Staging for generic programming in space and time , 2017, GPCE.

[80]  John H. Reppy Type-sensitive control-flow analysis , 2006, ML '06.