title: Experimental Results from Dynamic Slicing of C Program

abstract: Program slicing is a program analysis technique that has been studied in the context of several different applications in the construction, optimization, maintenance, testing, and debugging of programs. Algorithms are available for constructing slices for a particular execution of a program (dynamic slices), as well as to approximate a subset of the behavior over all possible executions of a program (static slices). However, these algorithms have been studied only in the context of small abstract languages. Program slicing is bound to remain an academic exercise unless one can not only demonstrate the feasibility of building a slicer for nontrivial programs written in a real programming language, but also verify that a type of slice is sufficiently thin, on the average, for the application for which it is chosen. In this article, we present results from using SLICE , a dynamic program slicer for C programs, designed and implemented to experiment with several different kinds of program slices and to study them both qualitatively and quantitatively. Several application programs, ranging in size (i.e., number of lines of code) over two orders of magnitude, were sliced exhaustively to obtain average worst-case metrics for the size of program slices.


venue: toplas

title: A Complete Calculus for the Multialgebraic and Functional Semantics of Nondeterminism

authors:
Michal Walicki
Sigurd Meldal

abstract: The current algebraic models for nondeterminism focus on the notion of possibility rather than necessity and consequently equate (nondeterministic) terms that one would intuitively not consider equal. Furthermore, existing models for nondeterminism depart radically from the standard models for (equational) specifications of deterministic operators. One would prefer that a specification language for nondeterministic operators be based on an extension of the standard model concepts, preferably in such a way that the reasoning system for (possibly nondeterministic) operators becomes the standard equational one whenever restricted to the deterministic operators—the objective should be to minimize the departure from the standard frameworks. In this article we define a specification language for nondeterministic operators and multialgebraic semantics. The first complete reasoning system for such specifications is introduced. We also define a transformation of specifications of nondeterministic operators into derived specifications of deterministic ones, obtaining a “computational” semantics of nondeterministic specification by adopting the standard semantics of the derived specification as the semantics of the original one. This semantics turns out to be a refinement of multialgebra semantics. The calculus is shown to be sound and complete also with respect to the new semantics.


title: Optimization of Functional Programs by Grammar Thinning

abstract: We describe a new technique for optimizing first-order functional programs. Programs are represented as graph grammars, and optimization proceeds by counterexample: when a graph generated by the grammar is found to contain an unnecessary computation, the optimizer attempts to reformulates the grammar so that it never again generates any graph that contains that counterexample. This kind of program reformulation corresponds to an interesting problem on context-free grammars. Our reformulation technique is derived from an (approximate) solution to this CFG problem. An optimizer called Thinner is the proof of concept for this technique. Thinner is a fully automatic, source-to-source optimizer for a Lisp-like language of purely functional, first-order programs. Thinner rediscovers a wide variety of common compiler optimizations. It also finds other more exotic transformations, including the well-known Fibonacci reformulation and the Knuth-Morris-Pratt optimization.


title: A Worst Case of Circularity Test Algorithms for Attribute Grammars

authors:
Pei-Chi Wu
Feng-Jian Wang

abstract: Although the circularity test problem for attribute grammars (AGs) has been proven to be intrinsically exponential, to date, a worst case for the existing circularity test algorithms has yet to be presented. This note presents a worst-case AG in which the number of incomparable dependency graphs induced at the root is exponential. The worst case can help to clarify the complexity of the problem.


title: On Subtyping and Matching

authors:
Martín Abadi
Luca Cardelli

abstract: A relation between recursive object types, called matching , has been proposed as a generalization of subtyping. Unlike subtyping, matching does not support subsumption, but it does support inheritance of binary methods. We argue that matching is a good idea, but that it should not be regarded as a form of F-bounded subtyping (as was originally intended). We show that a new interpretation of matching as higher-order subtyping has better properties. Matching turns out to be a third-order construction, possibly the only one to have been proposed for general use in programming.


title: A Natural Semantics for Eiffel Dynamic Binding

authors:
Isabelle Attali
Denis Caromel
Sidi O. Ehmety

abstract: This article formally defines Eiffel dynamic binding in presence of renaming and redefinition. Message passing, inheritance, and polymorphism are expressed in an operational style using natural semantics. From the formal specification, we derive an algorithm to determine the appropriate version of a feature to apply to a given object. This algorithm, based only on the class hierarchy and not using any intermediate structure, gives a practical approach to the understanding of inheritance, renaming, and redefinition in Eiffel.


title: Global Analysis of Constraint Logic Programs

authors:
Maria J. García de la Banda
Manuel V. Hermenegildo
Maurice Bruynooghe
Veroniek Dumortier
Gerda Janssens
Wim Simoens

abstract: This article presents and illustrates a practical approach to the dataflow analysis of constraint logic programming languages using abstract interpretation. It is first argued that, from the framework point of view, it suffices to propose relatively simple extensions of traditional analysis methods which have already been proved useful and practical and for which efficient fixpoint algorithms exist. This is shown by proposing a simple extension of Bruynooghe's traditional framework which allows it to analyze constraint logic programs. Then, and using this generalized framework, two abstract domains and their required abstract functions are presented: the first abstract domain approximates definiteness information and the second one freeness. Finally, an approach for combining those domains is proposed. The two domains and their combination have been implemented and used in the analysis of CLP( R ) and Prolog-III applications. Results form this implementation showing its performance and accuracy are also presented.


title: Conditional Attribute Grammars

abstract: Attribute grammars are a useful formalism for the specification of computations on structured terms. The classical definition of attribute grammars, however, has no way of treating conditionals nonstrictly. Consequently, the natural way of expressing many otherwise well-behaved computations involves a circularity. This article presents conditional attribute grammars , and extension of attribute grammars that enables more precise analysis of conditionals. In conditional attribute grammars, attribute equations may have guards. Equations are active only when their guards are satisfied. The standard attribute grammar evaluation classes are definable for conditional attribute grammars, and the corresponding evaluation techniques can be easily adapted. However, determining membership in standard evaluation classes such as 1-SWEEP, OAG, and SNC is NP-hard.


title: On the Optimality of Change Propagation for Incremental Evaluation of Hierarchical Attribute Grammars

authors:
Alan Carle
Lori L. Pollock

abstract: Several new attribute grammar dialects have recently been developed, all with the common goal of allowing large, complex language translators to be specified through a modular composition of smaller attribute grammars. We refer to the class of dialects as hierarchical attribute grammars . In this short article, we present a characterization of optimal incremental evaluation that indicates the unsuitability of change propagation as the basis of an optimal incremental evaluator for hierarchical attribute grammars. This result lends strong support to the use of incremental evaluators based on more applicative approaches to attribute evaluation, such as Carle and Pollock's evaluator based on more applicative approaches to attribute evaluation, such as Carle and Pollock's evaluator based on caching of partially attributed subtree, Pugh's evaluator based on function caching of semantic functions, and Swierstra and Vogt's evaluator based on functions, and Swierstra and Vogt's evaluator based on function caching of visit sequences.


title: Eta-Expansion Does The Trick

authors:
Olivier Danvy
Karoline Malmkjær
Jens Palsberg

abstract: Partial-evaluation folklore has it that massaging one's source programs can make them specialize better. In Jones, Gomard, and Sestoft's recent textbook, a whole chapter is dedicated to listing such “binding-time improvements”: nonstandard use of continuation-passing style, eta-expansion, and a popular transformation called “The Trick.” We provide a unified view of these binding-time improvements, from a typing perspective. Just as a proper treatment of product values in partial evaluation requires partially static values, a proper treatment of disjoint sums requires moving static contexts across dynamic case expressions. This requirement precisely accounts for the nonstandard use of continuation-passing style encountered in partial evaluation. Eta-expansion thus acts as a uniform binding-time coercion between values and contexts, be they of function type, product type, or disjoint-sum type. For the latter case, it enables “The Trick.” In this article, we extend Gomard and Jones' partial evaluator for the λ-calculus, λ-Mix, with products and disjoint sums; we point out how eta-expansion for (finite) disjoint sums enable The Trick; we generalize our earlier work by identifying the eta-expansion can be obtained in the binding-time analysis simple by adding two coercion rules; and we specify and prove the correctness of our extension to λ-Mix.


title: Principles and Practice of Unification Factoring

authors:
Steven Dawson
C. R. Ramakrishnan
Steven Skiena
Terrance Swift

abstract: The efficiency of resolution-based logic programming languages, such as Prolog, depends critically on selecting and executing sets of applicable clause heads to resolve against subgoals. Traditional approaches to this problem have focused on using indexing to determine the smallest possible applicable set. Despite their usefulness, these approaches ignore the nondeterminism inherent in many programming languages to the extent that they do not attempt to optimize execution after the applicable set has been determined. Unification factoring seeks to rectify this omission by regarding the indexing and unification phases of clause resolution as a single process. This article formalizes that process through the construction of factoring automata . A polynomial-time algorithm is given for constructing optimal factoring automata that preserve the clause selection strategy of Prolog. More generally, when the clause selection strategy is not fixed, constructing such an optimal automaton is shown to be NP-complete, solving an open trie minimization problem. Unification factoring is implemented through a source code transformation that preserves the full semantics of Prolog. This transformation is specified in the article, and using it, several well-known programs show significant performance improvements across several different systems. A prototype of unification factoring is available by anonymous ftp.


title: Compositional Parallel Programming Languages

abstract: In task-parallel programs, diversee activities can take place concurrently, and communication and synchronization patterns are complex and not easily predictable. Previous work has identifiedcompositionalityas an important design principle for task-parallel programs. In this article, we discuss alternative approaches to the realization of this principle, which holds that properties of program components should be preserved when those co ponents are composed in parallel with other program components. We review two programming languages, Strand and Program Composition Notation, that support compositionality via a small number of simple concepts, namely, monotone operations on shared opbects, a uniform addressing mechanism, and parallel composition. Both languages have been used extensively for large-scale application development, allowing us to provide an informed assessment of both their strengths and their weaknesses. We observe that while compositionality simplifies development of complex applications, the use of specialized languages hinders reuse of existing code and tools and the specification of domain decomposition strategies. This suggests an alternative approach based on small extensions to existing sequential languages. We conclude the article with a discussion of two languages that realized this strategy.


title: Iterated Register Coalescing

authors:
Lal George
Andrew W. Appel

abstract: An important function of any register allocator is to target registers so as to eliminate copy instructions. Graph-coloring register allocation is an elegant approach to this problem. If the source and destination of a move instruction do not interfere, then their nodes can be coalesced in the interference graph. Chaitin's coalescing heuristic could make a graph uncolorable (i.e., introduce spills); Briggs et al. demonstrated a conservative coalescing heuristic that preserves colorability. But Briggs's algorithm is too conservative and leaves too many move instructions in our programs. We show how to interleave coloring reductions with Briggs's coalescing heuristic, leading to an algorithm that is safe but much more aggressive.


title: Symbolic Analysis for Parallelizing Compilers

authors:
Mohammad R. Haghighat
Constantine D. Polychronopoulos

abstract: The notion of dependence captures that most important properties of a program for efficient execution on parallel computers. The dependence structure of a program defines that necessary constraints of the order of execution of the program components and provides sufficient information for the exploitation of the available parallelism. Static discovery and management of the dependence structure of programs save a tremendous amount of execution time, and dynamic utilization of dependence information results in a significant performance gain on parallel computers. However, experiments with parallel computers indicate that existing multiprocessing environments are unable to deliver the desired performance over a wide range of real applications, mainly due to lack of precision of their dependence information. This calls for an effective compilation scheme capable of understanding the dependence structure of complicated application programs. This article describes a methodology for capturing analyzing program properties that are essential in the effective detection and efficient exploitation of parallelism on parallel computers. Based on this methodology, a symbolic analysis framework is developed for the Parafrase-2 parallelizing compiler. This framework extends the scope of a variety of important program analysis problems and solves them in a unified way. The attained solution space of these problems is much larger than that handled by existing compiler technology. Such a powerful approach is required for the effective compilation of a large class of application programs.


title: Type Classes in Haskell

authors:
Cordelia V. Hall
Kevin Hammond
Simon L. Peyton Jones
Philip Wadler

abstract: This article defines a set of type inference rules for resolving overloading introduced by type classes, as used in the functional programming language Haskell. Programs including type classes are transformed into ones which may be typed by standard Hindley-Milner inference rules. In contrast to other work on type classes, the rules presented here relate directly to Haskell programs. An innovative aspect of this work is the use of second-order lambda calculus to record type information in the transformed program.


title: Handling Floating-Point Exceptions in Numeric Programs

abstract: There are a number of schemes for handling arithmetic exceptions that can be used to improve the speed (or alternatively the reliability) of numeric code. Overflow and underflow are the most troublesome exceptions, and depending on the context in which the exception can occur, they may be addressed either: (1) through a “brute force” reevaluation with extended range, (2) by reevaluating using a technique known as scaling , (3) by substituting an infinity or zero, or (4) in the case of underflow, with gradual underflow. In the first two of these cases, the offending computation is simply reevaluated using a safer but slower method. The latter two cases are cheaper, more automated schemes that ideally are built in as options within the computer system. Other arithmetic exceptions can be handled with similar methods. These and some other techniques are examined with an eye toward determining the support programming languages and computer systems ought to provide for floating-point exception handling. It is argued that the cheapest short-term solution would be to give full support to most of the required (as opposed to recommended) special features of the IEC/IEEE Standard for Binary Floating-Point Arithmetic. An essential part of this support would include standardized access from high-level languages to the exception flags defined by the standard. Some possibilities outside the IEEE Standard are also considered, and a few thought on possible better-structured support within programming languages are discussed.


title: Reconciling Responsiveness with Performance in Pure Object-Orieted Languages

authors:
Urs Hölzle
David M. Ungar

abstract: Dynamically dispatched calls often limit the performance of object-oriented programs, since opject-oriented programming encourages factoring code into small, reusable units, thereby increasing the frequency of these expensive operations. Frequent calls not only slow down execution with the dispatch overhead per se, but more importantly they hinder optimization by limiting the range and effectiveness of standard global optimizations. In particular, dynamically dispatched calles prevent standard interprocedual optimizations that depend on the availability of a static call graph. The SELF implementation described here offers tow novel approaches to optimization. Type feedback speculatively inlines dynamically dispatched calls based on profile information that predicts likely receiver classes. Adaptive optimization reconciles optimizing compilation with interactive performance by incrementally optimizing only the frequently executed parts of a program. When combined, these two techniques result in a system that can execute programs significantly faster than previous systems while retaining much of the interactiveness of an interpreted system.


title: Parallelism for Free: Efficient and Optimal Bitvector Analyses for Parallel Programs

authors:
Jens Knoop
Bernhard Steffen
Jürgen Vollmer

abstract: We consider parallel programs with shared memory and interleaving semantics, for which we show how to construct for unidirectional bitvector problems optimal analysis algorithms that are as efficient as their purely sequential counterparts and that can easily be implemented. Whereas the complexity result is rather obvious, our optimality result is a consequence of a new Kam/Ullman-style Coincidence Theorem. Thus using our method, the standard algorithms for sequential programs computing liveness, availability, very busyness, reaching definitions, definition-use chains, or the analyses for performing code motion, assignment motion, partial dead-code elimination or strength reduction, can straightforward be transferred to the parallel setting at almost no cost.


title: Storage Assignment to Decrease Code Size

authors:
Stan Y. Liao
Srinivas Devadas
Kurt Keutzer
Steven W. K. Tjiang
Albert R. Wang

abstract: DSP architectures typically provide indirect addressing modes with autoincrement and decrement. In addition, indexing mode is generally not available, and there are usually few, if any, general-purpose registers. Hence, it is necessary to use address registers and perform address arithmetic to access automatic variables. Subsuming the address arithmetic into autoincrement and decrement modes improves the size of the generated code. In this article we present a formulation of the problem of optimal storage assignment such that explicit instructions for address arithmetic are minimized. We prove that for the case of a single address register the decision problem is NP-complete, even for a single basic block. We then generalize the problem to multiple address registers. For both cases heuristic algorithms are given, and experimental results are presented.


title: Improving Data Locality with Loop Transformations

authors:
Kathryn S. McKinley
Steve Carr
Chau-Wen Tseng

abstract: In the past decade, processor speed has become significantly faster than memory speed. Small, fast cache memories are designed to overcome this discrepancy, but they are only effective when programs exhibit data locality . In the this article, we present compiler optimizations to improve data locality based on a simple yet accurate cost model. The model computes both temporal and spatial reuse of cache lines to find desirable loop organizations. The cost model drives the application of compound transformations consisting of loop permutation, loop fusion, loop distribution, and loop reversal. To validate our optimization strategy, we implemented our algorithms and ran experiments on a large collection of scientific programs and kernels. Experiments illustrate that for kernels our model and algorithm can select and achieve the best loop structure for a nest. For over 30 complete applications, we executed the original and transformed versions and simulated cache hit rates. We collected statistics about the inherent characteristics of these programs and our ability to improve their data locality. To our knowledge, these studies are the first of such breadth and depth. We found performance improvements were difficult to achieve bacause benchmark programs typically have high hit rates even for small data caches; however, our optimizations significanty improved several programs.


title: Probabilistic Predicate Transformers

authors:
Carroll Morgan
Annabelle McIver
Karen Seidel

abstract: Probabilistic predicates generalize standard predicates over a state space; with probabilistic predicate transformers one thus reasons about imperative programs in terms of probabilistic pre- and postconditions. Probabilistic healthiness conditions generalize the standard ones, characterizing “real” probabilistic programs, and are based on a connection with an underlying relational model for probabilistic execution; in both contexts demonic nondeterminism coexists with probabilistic choice. With the healthiness conditions, the associated weakest-precondition calculus seems suitable for exploring the rigorous derivation of small probabilistic programs.


title: Iteration Abstraction in Sather

authors:
Stephan Murer
Stephen M. Omohundro
David Stoutamire
Clemens A. Szyperski

abstract: Sather extends the notion of an iterator in a powerful new way. We argue that iteration abstractions belong in class interfaces on an equal footing with routines. Sather iterators were derived from CLU iterators but are much more flexible and better suited for object-oriented programming. We retain the property that iterators are structured , i.e., strictly bound to a controlling structured statement. We motivate and describe the construct along with several simple examples. We compare it with iteration based on CLU iterators, cursors, riders, streams, series, generators, coroutines, blocks, closures, and lambda expressions. Finally, we describe experiences with iterators in the Sather compiler and libraries.


title: Constrained Types and Their Expressiveness

authors:
Jens Palsberg
Scott F. Smith

abstract: A constrained type consists of both a standard type and a constraint set. Such types enable efficient type inference for object-oriented languages with polymorphism and subtyping, as demonstrated by Eifrig, Smith, and Trifonov. Until now, it has been unclear how expressive constrained types are. In this article we study constrained types without universal quantification. We prove that they accept the same programs as the type system of Amadio and Cardelli with subtyping and recursive types. This result gives a precise connection between constrained types and the standard notion of types.


title: Indirect Distributed Garbage Collection: Handling Object Migration

abstract: In new distributed systems, object mobility is usually allowed and is sometimes used by the underlying object manager system to benefit from object access locality. On the other hand, in-transit references to objects can exist at any moment in asynchronous distributed systems. In the presence of object mobility and in-transit references, many garbage collector (GC) algorithms fail to operate correctly. Others need to use the system's object finder to find the objects while performing their work. As a general principle, a GC should never interfere with object manager polices (such as forcing migration or fixing an object to a given processor). However, if the GC uses the object finder, it will change the access pattern of the system, and eventually it could foul the global allocation policy. In this article we propose a new GC family, Indirect Garbage Collectors, allowing to separate the problems of object management (placement, replication, and retrieval) from garbage collection. This property allows our algorithms to be implemented on top of almost any existent distributed object system, without having to use the object finder.


title: Demand-Driven Register Allocation

authors:
Todd A. Proebsting
Charles N. Fischer

abstract: A new global register allocation technique,demand-driven register allocation, is described. Demand-driven register allocation quantifies the costs and benefits of allocating variables to registers over live ranges so that high-quality allocations can be made. Local allocation is done first, and then global allocation is done iteratively beginning in the most deeply nested loops. Because local allocation precedes global allocation, demand-driven allocation does not interfere with the use of well-known, high-quality local register allocation and instruction-scheduling techniques.


title: Total Correctness by Local Improvement in the Transformation of Functional Programs

abstract: The goal of program transformation is to improve efficiency while preserving meaning. One of the best-known transformation techniques is Burstall and Darlington's unfold-fold method. Unfortunately the unfold-fold method itself guarantees neither improvement in efficiency nor total correctness. The correctness problem for unfold-fold is an instance of a strictly more general problem: transformation by locally equivalence-preserving steps does not necessarily preserve (global) equivalence. This article presents a condition for the total correctness of transformations on recursive programs, which, for the first time, deals with higher-order functional languages (both strict and nonstrict) including lazy data structures. The main technical result is an improvement theorem which says that if the local transformation steps are guided by certain optimization concerns (a fairly natural condition for a transformation), then correctness of the transformation follows. The improvement theorem makes essential use of a formalized improvement theory; as a rather pleasing corollary it also guarantees that the transformed program is a formal improvement over the original. The theorem has immediate practical consequences: it is a powerful tool for proving the correctness of existing transformation methods for higher-order functional programs, without having to ignore crucial factors such as memoization or folding , and it yields a simple syntactic method for guiding and constraining the unfold-fold method in the general case so that total correctness (and improvement) is always guaranteed.


title: Using Dataflow Analysis Techniques to Reduce Ownership Overhead in Cache Coherence Protocols

authors:
Jonas Skeppstedt
Per Stenström

abstract: In this article, we explore the potential of classical dataflow analysis techniques in removing overhead in write-invalidate cache coherence protocols for shared-memory multiprocessors. We construct the compiler algorithms with varying degree of sophistication that detect loads followed by stores to the same address. Such loads are marked and constitute a hint to the cache to obtain an exclusive copy of the block so that the subsequent store does not introduce access penalties. The simplest of the three compiler algorithms analyzes the existence of load-store sequences within each basic blocks of code whereas the other two analyze load-store sequences across basic blocks at the intraprocedural level. The algorithms have been incorporated into an optimizing C compiler, and we have evaluated their efficiencies by compiling and executing seven parallel programs on a simulated multiprocessor. Our results show that the detection efficiency of the most aggressive algorithm is 96% or higher for four of the seven programs studied. We also compare the efficiency of these static algorithms with that of dynamic hardware-based algorithms that reduce ownership overhead. We find that the static analysis using classical dataflow analysis results in similar performance improvements as dynamic hardware-based approaches.


title: Polymorphic typing of Variables and References

authors:
Geoffrey Smith
Dennis M. Volpano

abstract: In this article we consider the polymorphic type checking of an imperative language. Our language contains variables , first-class references (pointers), and first-class functions. Variables, as in traditional imperative languages, are implicitly dereferenced, and their addresses ( L -values) are not first-class values. Variables are easier to type check than references and, in many cases, lead to more general polymorphic types. We present a polymorphic type system for our language and prove that it is sound. Programs that use variables sometimes require weak types, as in Tofte's type system for Standard ML, but such weak types arise far less frequently with variables than with references


title: Identifying Loops Using DJ Graphs

authors:
Vugranam C. Sreedhar
Guang R. Gao
Yong-Fong Lee

abstract: Loop identification is a necessary step in loop transformations for high-performance architectures. One classical technique for detecting loops is Tarjan's interval-finding algorithm. The intervals identified by Tarjan's method are single-entry, strongly connected subgraphs that closely reflect a program's loop structure. We present a simple algorithm for identifying both reducible and irreducible loops using DJ graphs. Our method is a generalization of Tarjan's method, as it identifies nested intervals (or loops) even in the presence of irreducibility.


title: An Incremental Algorithm for Satisfying Hierarchies of Multiway Dataflow Constraints

abstract: One-way dataflow constraints have gained popularity in many types of interactive systems because of their simplicity, efficiency, and manageability. Although it is widely acknowledged that multiway dataflow constraint could make it easier to specify certain relationships in these applications, concerns about their predictability and efficiency have impeded their acceptance. Constraint hierarchies have been developed to address the predictability problem, and incremental algorithms have been developed to address the efficiency problem. However, existing incremental alogrithms for satisfying constraint hierarchies encounter two difficulties : (1) they are incapable of guaranteeing an acylic solution if a constraint hierarchy has one or more cyclic solutions and (2) they require worst-case exponential time to satisfy systems of multioutput constriants. This article surmounts these difficulties by presenting an incremental algorithm called QuickPlan that satisfies in worst-case O(N 2 ) time any hierarchy of multiway, multiout-put dataflow constraint that has at least one acyclic solution, where N is the number of constraints. With benchmarks and real problems that can be solved efficiently using exisitng algorithms, its performance is competitive or superior. With benchmarks and real problems that cannot be solved using exisitng algorithms or that cannot be solved efficiently, QuickPlan finds solutions and does so efficiently, typically in O(N) time or less. QuickPlan is based on the strategy of propagation of degrees of freedom. The only restriction it imposes is that every constraint method must use all of the variables in the constraint as either an input or an output variable. This requirement is met in every constraint-based, interactive application that we have developed or seen.


title: Parameter Passing and Control Stack Management in Prolog Implementation Revisited

abstract: Parameter passing and control stack management are two of the crucial issues in Prolog implementation. In the Warren Abstract Machine (WAM), the most widely used abstract machine for Prolog implementation, arguments are passed through argument registers, and the information associated with procedure calls is stored in possibly two frames. Although accessing registers is faster than accessing memory, this scheme requires the argument registers to be saved and restored for back tracking and makes it difficult to implement full tail recursion elimination. These disadvantages may far outweigh the advantage in emulator-based implementations because registers are actually simulated by using memory. In this article, we reconsider the two crucial issues and describe a new abstract machine called ATOAM (yet Another Tree-Oriented Abstract Machine). The ATOAM differs from the WAM mainly in that (1) arguments are passed directly into stack frames, (2) only one frame is used for each procedure call, and (3) procedures are translated into matching trees is possible, and clauses in each procedure are indexed on all input arguments. The above-mentioned inefficiencies of the WAM do not exist in to he ATOAM because backtracking requires less bookkeeping operations, and tail recursion can be handled in most cases like a loop statement in procedural languages. An ATOAM-emulator-based Prolog system called B-Prolog has been implemented, which is available through anonymous ftp from ftp.kyutech.ac.jp (131.206.1.101) in the directory pub/Language/prolog .B-Prolog is comparable in performance with and can sometimes be significatly faster than emulated SICStus-Prolog. By measuring the numbers of memory and register references made in both systems, we found that passing arguments in stack is no worse than passing arguments in registers even if accessing memory is four times as expensive as accessing registers.


title: Implementing Signatures for C++

authors:
Gerald Baumgartner
Vincent F. Russo

abstract: We outline the design and detail the implementation of a language extension for abstracting types and for decoupling subtyping and inheritance in C++. This extension gives the user more of the flexibility of dynamic typing while retaining the efficiency and security of static typing. After a brief discussion of syntax and semantics of this language extension and examples of its use, we present and analyze three different implementation techniques: a preprocessor to a C++ compiler, an implementation in the front end of a C++ compiler, and a low-level implementation with back-end support. We follow with an analysis of the performance of the three implementation techniques and show that our extension actually allows subtype polymorphism to be implemented more efficiently than with virtual functions. We conclude with a discussion of the lessons we learned for future programming language design.


title: Toward a Complete Transformational Toolkit for Compilers

authors:
Jan A. Bergstra
T. B. Dinesh
John Field
Jan Heering

abstract: PIM is an equational logic designed to function as a “transformational toolkit” for compilers and other programming tools that analyze and manipulate imperative languages. It has been applied to such problems as program slicing, symbolic evaluation, conditional constant propagation, and dependence analysis. PIM consists of the untyped lambda calculus extended with an algebraic data type that characterizes the behavior of lazy stores and generalized conditionals. A graph form of PIM terms is by design closely related to several intermediate representations commonly used in optimizing compilers. In this article, we show that PIM's core algebraic component, PIM t , possesses a complete equational axiomatization (under the assumption of certain reasonable restrictions on term formation). This has the practical consequence of guaranteeing that every semantics-preserving transformation on a program representable in PIM t can be derived by application of PIM t rules. We systematically derive the complete PIM t logic as the culmination of a sequence of increasingly powerful equational systems starting from a straightforward “interpreter” for closed PIM t terms. This work is an intermediate step in a larger program to develop a set of well-founded tools for manipulation of imperative programs by compilers and other systems that perform program analysis.


title: Proving Concurrent Constraint Programs Correct

authors:
Frank S. de Boer
Maurizio Gabbrielli
Elena Marchiori
Catuscia Palamidessi

abstract: We introduce a simple compositional proof system for proving (partial) correctness of concurrent constraint programs (CCP). The proof system is based on a denotational approximation of the strongest postcondition semantics of CCP programs. The proof system is proved to be correct for full CCP and complete for the class of programs in which the denotational semantics characterizes exactly the strongest postcondition. This class includes the so-called confluent CCP, a special case of which is constraint logic programming with dynamic scheduling.


title: A Refinement Calculus for the Synthesis of Verified Hardware Descriptions in VHDL

authors:
Peter T. Breuer
Carlos Delgado Kloos
Andrés Marín López
Natividad Martínez Madrid
Luis Sánchez Fernández

abstract: A formal refinement calculus targeted at system-level descriptions in the IEEE standard hardware description language VHDL is described here. Refinement can be used to develop hardware description code that is “correct by construction”. the calculus is closely related to a Hoare-style programming logic for VHDL and real-time systems in general. That logic and a semantics for a core subset of VHDL are described. The programming logic and the associated refinement calculus are shown to be complete. This means that if there is a code that can be shown to implement a given specification, then it will be derivable from the specification via the calculus.


title: Evidence-Based Static Branch Prediction Using Machine Learning

authors:
Brad Calder
Dirk Grunwald
Michael P. Jones
Donald C. Lindsay
James H. Martin
Michael Mozer
Benjamin G. Zorn

abstract: Correctly predicting the direction that branches will take is increasingly important in today's wide-issue computer architectures. The name program-based branch prediction is given to static branch prediction techniques that base their prediction on a program's structure. In this article, we investigate a new approach to program-based branch prediction that uses a body of existing programs to predict the branch behavior in a new program. We call this approach to program-based branch prediction evidence-based static prediction , or ESP. The main idea of ESP is that the behavior of a corpus of programs can be used to infer the behavior of new programs. In this article, we use neural networks and decision trees to map static features associated with each branch to a prediction that the branch will be taken. ESP shows significant advantages over other prediction mechanisms. Specifically, it is a program-based technique; it is effective across a range of programming languages and programming styles; and it does not rely on the use of expert-defined heuristics. In this article, we describe the application of ESP to the problem of static branch prediction and compare our results to existing program-based branch predictors. We also investigate the applicability of ESP across computer architectures, programming languages, compilers, and run-time systems. We provide results showing how sensitive ESP is to the number and type of static features and programs included in the ESP training sets, and we compare the efficacy of static branch prediction for subroutine libraries. Averaging over a body of 43 C and Fortran programs, ESP branch prediction results in a miss rate of 20%, as compared with the 25% miss rate obtained using the best existing program-based heuristics.


title: On the Use of Regular Expressions for Searching Text

authors:
Charles L. A. Clarke
Gordon V. Cormack

abstract: The use of regular expressions for text search is widely known and well understood. It is then surprising that the standard techniques and tools prove to be of limited use for searching structured text formatted with SGML or similar markup languages. Our experience with structured text search has caused us to reexamine the current practice. The generally accepted rule of “leftmost longest match” is an unfortunate choice and is at the root of the difficulties. We instead propose a rule which is semantically cleaner. This rule is generally applicable to a variety of text search applications, including source code analysis, and has interesting properties in its own right. We have written a publicly available search tool implementing the theory in the article, which has proved valuable in a variety of circumstances.


title: Verifying Parameterized Networks

authors:
Edmund M. Clarke
Orna Grumberg
Somesh Jha

abstract: This article describes a technique based on network grammars and abstraction to verify families of state-transition systems. The family of state-transition systems is represented by a context-free network grammar. Using the structure of the network grammar our technique constructs a process invariant that simulates all the state-transition systems in the family. A novel idea introduced in this article is the use of regular languages to express state properties. We have implemented our techniques and verified two nontrivial examples.


title: Complementation in Abstract Interpretation

authors:
Agostino Cortesi
Gilberto Filé
Roberto Giacobazzi
Catuscia Palamidessi
Francesco Ranzato

abstract: Reduced product of abstract domains is a rather well-known operation for domain composition in abstract interpretation. In this article, we study its inverse operation, introducing a notion of domain complementation in abstract interpretation. Complementation provides as systematic way to design new abstract domains, and it allows to systematically decompose domains. Also, such an operation allows to simplify domain verification problems, and it yields space-saving representations for complex domains. We show that the complement exists in most coses, and we apply complementation to three well-know abstract domains, notably to Cousot and Cousot's interval domain for integer variable analysis, to Cousot and Cousot's domain for comportment analysis of functional languages, and to the domain Sharing for aliasing analysis of logic languages.


title: Abstract Interpretation of Reactive Systems

authors:
Dennis Dams
Rob Gerth
Orna Grumberg

abstract: The advent of ever more complex reactive systems in increasingly critical areas calls for the development of automated verification techniques.Model checking is one such technique, which has proven quite successful.However, the state-explosion problem remains a major stumbling block.Recent experience indicates that solutions are to be found in the application of techniques for property-preserving abstraction and successive approximation of models.Most such applications have so far been based solely on the property-preserving characteristics of simulation relations.A major drawback of all these results is that they do not offer a satisfactory formalization of the notion of precision of abstractions.The theory of Abstract Interpretation offers a framework for the definition and justification of property-preserving abstractions.Furthermore, it provides a method for the effective computation of abstract models directly from the text of a program, thereby avoiding the need for intermediate storage of a full-blown model.Finally, it formalizes the notion of optimality, while allowing to trade precision for speed by computing suboptimal approximations.For a long time, applications of Abstract Interpretation have mainly focused on the analysis of universal safety properties, i.e., properties that hold in all states along every possible execution path.In this article, we extend Abstract Interpretation to the analysis of both existential and universal reactive properties, as expressible in the modal µ-calculus.It is shown how abstract models may be constructed by symbolic execution of programs.A notion of approximation between abstract models is defined while conditions are given under which optimal models can be constructed.Examples are given to illustrate this.We indicate conditions under which also falsehood of formulae is preserved.Finally, we compare our approach to those based on simulation relations.


title: Interprocedural Control Flow Analysis of First-Order Programs with Tail-Call Optimization

authors:
Saumya K. Debray
Todd A. Proebsting

abstract: Knowledge of low-level control flow is essential for many compiler optimizations. In systems with tail-call optimization, the determination of interprocedural control flow is complicated by the fact that because of tail-call optimization, control flow at procedure returns is not readily evident from the call graph of the program. This article shows how interprocedural control-flow analysis of first-order programs can be carried out using well-known concepts from parsing theory. In particular, we show that context-insensitive ( or zeroth-order) control-flow analysis corresponds to the notion of FOLLOW sets in context-free grammars, while context-sensitive (or first-order) control-flow analysis corresponds to the notion of LR(1) items. The control-flow information so obtained can be used to improve the precision of interprocedural dataflow analyses as well as to extend certain low-level code optimizations across procedure boundaries.


title: A Practical Framework for Demand-Driven Interprocedural Data Flow Analysis

authors:
Evelyn Duesterwald
Rajiv Gupta
Mary Lou Soffa

abstract: The high cost and growing importance of interprocedural data flow analysis have led to an increased interest in demand-driven algorithms. In this article, we present a general framework for developing demand-driven interprocedural data flow analyzers and report our experience in evaluating the performance of this approach. A demand for data flow information is modeled as a set of queries. The framework includes a generic demand-driven algorithm that determines the response to query by iteratively applying a system of query propagation rules. The propagation rules yield precise responses for the class of distributive finite data flow problems. We also describe a two-phase framework variation to accurately handle nondistributive problems. A performance evaluation of our demand-driven approach is presented for two data flow problems, namely, reaching-definitions and copy constant propagation. Our experiments show that demand-driven analysis performs well in practice, reducing both time and space requirements when compared with exhaustive analysis.


title: Utilizing Symmetry when Model-Checking under Fairness Assumptions: An Automata-Theoretic Approach

authors:
E. Allen Emerson
A. Prasad Sistla

abstract: One useful technique for combating the state explosion problem is to exploit symmetry when performing temporal logic model checking. In previous work it is shown how, using some basic notions of group theory, symmetry may be exploited for the full range of correctness properties expressible in the very expressive temporal logic CTL*. Surprisingly, while fairness properties are readily expressible in CTL*, these methods are not powerful enough to admit any amelioration of state explosion, when fairness assumptions are involved. We show that it is nonetheless possible to handle fairness efficiently by trading some group theory for automata theory. Our automata-theoretic approach depends on detecting fair paths subtly encoded in a quotient structure whose arcs are annotated with permutations, by using a threaded structure that reflects coordinate shifts caused by the permutations.


title: Slicing Real-Time Programs for Enhanced Schedulability

authors:
Richard Gerber
Seongsoo Hong

abstract: In this article we present a compiler-based technique to help develop correct real-time systems. The domain we consider is that of multiprogrammed real-time applications, in which periodic tasks control physical systems via interacting with external sensors and actuators. While a system is up and running, these operations must be performed as specified—otherwise the system may fail. Correctness depends not only on each program individually, but also on the time-multiplexed behavior of all of the programs running together. Errors due to overloaded resources are exposed very late in a development process, and often at runtime. They are usually remedied by human-intensive activities such as instrumentation, measurement, code tuning and redesign. We describe a static alternative to this process, which relies on well-accepted technologies from optimizing compilers and fixed-priority scheduling. Specifically, when a set of tasks are found to be overloaded, a scheduling analyzer determines candidate tasks to be transformed via program slicing. The slicing engine decomposes each of the selected tasks into two fragments: one that is “time critical” and the other “unobservable.” The unobservable part is then spliced to the end of the time-critical code, with the external semantics being maintained. The benefit is that the scheduler may postpone the unobservable code beyond its original deadline, which can enhance overall schedulability. While the optimization is completely local, the improvement is realized globally, for the entire task set.


title: Nesting of Reducible and Irreducible Loops

abstract: Recognizing and transforming loops are essential steps in any attempt to improve the running time of a program. Aggressive restructuring techniques have been developed for single-entry (reducible) loops, but restructurers and the dataflow and dependence analysis they rely on often give up in the presence of multientry (irreducible) loops. Thus one irreducible loop can prevent the improvement of all loops in a procedure. This article give an algorithm to build a loop nesting tree for a procedure with arbitrary control flow. The algorithm uses definitions of reducible and irreducible loops which allow either kind of loop to be nested in the other. The tree construction algorithm, an extension of Tarjan's algorithm for testing reducibility, runs in almost linear time. In the presence of irreducible loops, the loop nesting tree can depend on the depth-first spanning tree used to build it. In particular, the header node representing a reducible loop in one version of the loop nesting tree can be the representative of an irreducible loop in another. We give a normalization method that maximizes the set of reducible loops discovered, independent of the depth-first spanning tree used. The normalization require the insertion of at most one node and one edge per reducible loop.


title: Precise Flow-Insensitive May-Alias Analysis is NP-Hard

abstract: Determining aliases is one of the foundamental static analysis problems, in part because the precision with which this problem is solved can affect the precision of other analyses such as live variables, available expressions, and constant propagation. Previous work has investigated the complexity of flow-sensitive alias analysis. In this article we show that precise flow- insensitive may-alias analysis is NP-hard given arbitrary levels of pointers and arbitrary pointer dereferencing.


title: Formal Derivation of Efficient Parallel Programs by Construction of List Homomorphisms

authors:
Zhenjiang Hu
Hideya Iwasaki
Masato Takeichi

abstract: It has been attracting much attention to make use of list homomorphisms in parallel programming because they ideally suit the divide-and-conquer parallel paradigm. However, they have been usually treated rather informally and ad hoc in the development of efficient parallel programs. What is worse is that some interesting functions, e.g., the maximum segment sum problem, are basically not list homomorphisms. In this article, we propose a systematic and formal way for the construction of a list homomorphism for a given problem so that an efficient parallel program is derived. We show, with several well-known but nontrivial problems, how a straightforward, and “obviously” correct, but quite inefficient solution to the problem can be successfully turned into a semantically equivalent “almost list homomorphism.” The derivation is based on two transformations, namely tupling and fusion, which are defined according to the specific recursive structures of list homomorphisms.


title: Making Graphs Reducible with Controlled Node Splitting

authors:
Johan Janssen
Henk Corporaal

abstract: Several compiler optimizations, such as data flow analysis, the exploitation of instruction-level parallelism (ILP), loop transformations, and memory disambiguation, require programs with reducible control flow graphs. However, not all programs satisfy this property. A new method for transforming irreducible control flow graphs to reducible control flow graphs, called Controlled Node Splitting (CNS), is presented. CNS duplicates nodes of the control flow graph to obtain reducible control flow graphs. CNS results in a minimum number of splits and a minimum number of duplicates. Since the computation time to find the optimal split sequence is large, a heuristic has been developed. The results of this heuristic are close to the optimum. Straightforward application of node splitting resulted in an average code size increase of 235% per procedure of our benchmark programs. CNS with the heuristic limits this increase to only 3%. The impact on the total code size of the complete programs is 13.6% for a straightforward application of node splitting. However, when CNS is used, with the heuristic the average growth in code size of a complete program dramatically reduces to 0.2%


title: Disjunctive Program Analysis for Algebraic Data Types

abstract: We describe how binding-time, data-flow, and strictness analyses for languages with higher-order functions and algebraic data types can be obtained by instantiating a generic program logic and axiomatization of the properties analyzed for. A distinctive feature of the analyses is that disjunctions of program properties are represented exactly. This yields analyses of high precision and provides a logical characterization of abstract interpretations involving tensor products and uniform properties of recursive data structures. An effective method for proving properties of a program based on fixed-point iteration is obtained by grouping logically equivalent formulae of the same type into equivalence classes, obtaining a lattice of properties of that type, and then defining an abstract interpretation over these lattices. We demonstrate this in the case of strictness analysis by proving that the strictness abstract interpretation of a program is the equivalence class containing the strongest property provable of the program in the strictness logic.


title: Kleene Algebra with Tests

abstract: We introduce Kleene algebra with tests, an equational system for manipulating programs. We give a purely equational proof, using Kleene algebra with tests and commutativity conditions, of the following classical result: every while program can be simulated by a while program can be simulated by a while program with at most one while loop. The proof illustrates the use of Kleene algebra with tests and commutativity conditions in program equivalence proofs.


title: Parallelizing Nonnumerical Code with Selective Scheduling and Software Pipelining

authors:
Soo-Mook Moon
Kemal Ebcioglu

abstract: Instruction-level parallelism (ILP) in nonnumerical code is regarded as scarce and hard to exploit due to its irregularity. In this article, we introduce a new code-scheduling technique for irregular ILP called “selective scheduling” which can be used as a component for superscalar and VLIW compilers. Selective scheduling can compute a wide set of independent operations acrossallexecution paths based on renaming and forward-substitution and can compute available operations across loop iterations if combined with software pipelining. This scheduling approach has better heuristics for determining the usefulness of moving one operation versus moving another and can successfully find useful code motions without resorting to branch profiling. The compile-time overhead of selective scheduling is low due to its incremental computation technique and its controlled code duplication. We parallelized the SPEC integer benchmarks and five AIX utilities without using branch probabilities. The experiments indicate that a fivefold speedup is achievable on realistic resources with a reasonable overhead in compilation time and code expansion and that a solid speedup increase is also obtainable on machines with fewer resources. These results improve previously known characteristics of irregular ILP.


title: Optimal Control Dependence Computation and the Roman Chariots Problem

authors:
Keshav Pingali
Gianfranco Bilardi

abstract: The control dependence relation plays a fundamental role in program restructuring and optimization. The usual representation of this relation is the control dependence graph (CDG), but the size of the CDG can grow quadratically with the input programs, even for structured programs. In this article, we introduce the augmented postdominator tree (APT) , a data structure which can be constructed in space and time proportional to the size of the program and which supports enumeration of a number of useful control dependence sets in time proportional to their size. Therefore, APT provides an optimal representation of control dependence. Specifically, the APT data structure supports enumeration of the set cd(e), which is the set of statements control dependent on control-flow edge e, of the set conds (w), which is the set of edges on which statement w is dependent, and of the set cdequiv ( w ), which is the set of statements having the same control dependences as w . Technically, APT can be viewed as a factored representation of the CDG where queries are processed using an approach known as filtering search.


title: Pure Versus Impure Lisp

abstract: The aspect of purity versus impurity that we address involves the absence versus presence of mutation: the use of primitives (RPLACA and RPLACD in Lisp, set-car! and set-cdr! in Scheme ) that change the state of pairs without creating new pairs.It is well known that cyclic list structures can be created by impure Lisp, but not by pure Lisp.In this sense, impure Lisp is "more powerful" than pure Lisp.If the inputs and outputs are restricted to be sequences of atomic symbols, however, this difference in computability disappears.We show that if the temporal sequence of input and output operations must be maintained (that is, if computations must be "on-line"), then a difference in complexity remains.We do this by comparing the power of pure and impure "Lisp machines."We show that what an impure Lisp machine does in n steps (executions of primitive operations), a pure Lisp machine can do in O(n log n) steps, and that in some cases ⍀(n log n) steps are necessary.


title: Combinatory Formaulations of Concurrent Languages

authors:
N. Raja
R. K. Shyamasundar

abstract: We design a system with six Basic Combinators and prove that it is powerful enough to embed the full asynchronous π-calculus, including replication. Our theory for constructing Combinatory Versions of concurrent languages is based on a method, used by Quine and Bernays, for the general elimination of variables in linguistic formalisms. Our combinators are designed to eliminate the requirement of names that are bound by an input prefix . They also eliminate the need for input prefix, output prefix, and the accompanying mechanism of substitution . We define a notion of bisimulation for the combinatory version and show that the combinatory version preserves the semantics of the original calculus. One of the distinctive features of the approach is that it can be used to rework several process algebras in order to derive equivalent combinatory versions.


title: Specifying Representations of Machine Instructions

authors:
Norman Ramsey
Mary F. Fernandez

abstract: We present SLED, a specification language for Encoding and Decoding, which describes, abstract, binary, and assembly-language representations of machine instructions. Guided by a SLED specification, the New Jersey Machine-Code Toolkit generates bit-manipulating code for use in applications that process machine code. Programmers can write such applications at an assembly language level of abstraction, and the toolkit enables the applications to recognize and emit the binary representations used by the hardware. SLED is suitable for describing both CISC and RISC machines; we have specified representations of MIPS R3000, SPARC, Alpha, and Intel Pentium instructions, and toolkit users have written specifications for the Power PC and Motorola 68000. The article includes representative excerpts from our SPARC and Pentium specifications. SLED uses four elements; fields and tokens describe parts of instructions; patterns describe binary representations of instructions or group of instructions; and constructors map between the abstract and binary levels. By combining the elements in different ways, SLED supports machine-independent implementations of machine-level concepts like conditional assembly, span-dependent instructions, relocatable addresses, object code, sections, and relocation. SLED specifications can be checked automatically for consistency with existing assemblers. The implementation of the toolkit is largely determined by our representations of patterns and constructors. We use a normal form that facilitates construction of encoders and decoders. The article describes the normal form and its use. The toolkit has been used to help build several applications. We have built a retargetable debugger and a retargetable, optimizing linker. Colleagues have built a dynamic code generator, a decompiler, and an execution-time analyzer. The toolkit generates efficient code; for example, the linker emits binary up to 15% faster than it emits assembly language, making it 1.7-2 times faster to produce an a.out directly than by using the assembler.


title: Commutativity Analysis: A New Analysis Technique for Parallelizing Compilers

authors:
Martin C. Rinard
Pedro C. Diniz

abstract: This article presents a new analysis technique, commutativity analysis, for automatically parallelizing computations that manipulate dynamic, pointer-based data structures. Commutativity analysis views the computation as composed of operations on objects. It then analyzes the program at this granularity to discover when operations commute (i.e., generate the same final result regardless of the order in which they execute). If all of the operations required to perform a given computation commute, the compiler can automatically generate parallel code. We have implemented a prototype compilation system that uses commutativity analysis as its primary analysis technique. We have used this system to automatically parallelize three complete scientific computations: the Barnes-Hut N-body solver, the Water liquid simulation code, and the String seismic simulation code. This article presents performance results for the generated parallel code running on the Stanford DASH machine. These results provide encouraging evidence that commutativity analysis can serve as the basis for a successful parallelizing compiler.


title: Mobile Objects in Distributed Oz

authors:
Peter Van Roy
Seif Haridi
Per Brand
Gert Smolka
Michael Mehl
Ralf Scheidhauer

abstract: Some of the most difficult questions to answer when designing a distributed application are related to mobility: what information to transfer between sites and when and how to transfer it. Network-transparent distribution, the property that a program's behavior is independent of how it is partitioned among sites, does not directly address these questions. Therefore we propose to extend all language entities with a network behavior that enables efficient distributed programming by giving the programmer a simple and predictable control over network communication patterns. In particular, we show how to give objects an arbitrary mobility behavior that is independent of the objects definition. In this way, the syntax and semantics of objects are the same regardless of whether they are used as stationary servers, mobile agents, or simply as caches. These ideas have been implemented in Distributed Oz, a concurrent object-oriented language that is state aware and has dataflow synchronization. We prove that the implementation of objects in Distributed Oz is network transparent. To satisfy the predictability condition, the implementation avoids forwarding chains through intermediate sites. The implementation is an extension to the publicly available DFKI Oz 2.0 system.


title: A Reflection on Call-by-Value

authors:
Amr Sabry
Philip Wadler

abstract: One way to model a sound and complete translation from a source calculus into a target calculus is with an adjoint or a Galois connection . In the special case of a reflection , one also has that the target calculus is isomorphic to a subset of the source. We show that three widely studied translations form reflections. We use as our source language Moggi's computational lambda calculus, which is an extension of Plotkin's call-by-value calculus. We show that Plotkin's CPS translation, Moggi's monad translation, and Girard's translation to linear logic can all be regarded as reflections form this source language, and we put forward the computational lambda calculus as a model of call-by-value computation that improves on the traditional call-by-value calculus. Our work strengthens Plotkin's and Moggi's original results and improves on recent work based on equational correspondence , which uses equations rather than reductions.


title: Formally Based Profiling for Higher-Order Functional Languages

authors:
Patrick M. Sansom
Simon L. Peyton Jones

abstract: We present the first source-level profiler for a compiled, nonstrict, higher-order, purely functional language capable of measuring time as well as space usage. Our profiler is implemented in a production-quality optimizing compiler for Haskell and can successfully profile large applications. A unique feature of our approach is that we give a formal specification of the attribution of execution costs to cost centers. This specification enables us to discuss our design decisions in a precise framework, prove properties about the attribution of costs, and examine to effects of different program transformations on the attribution of costs. Since it is not obvious how to map this specification onto a particular implementation, we also present an implementation-oriented operational semantics, and prove it equivalent to the specification.


title: Incremental Computation of Dominator Trees

authors:
Vugranam C. Sreedhar
Guang R. Gao
Yong-Fong Lee

abstract: In this article, we present a new algorithm for incrementally maintaining the dominator tree of an arbitrary flowgraph.Previous work most relevant to this article includes only the Carroll-Ryder algorithm and the Ramalingam-Reps algorithm.Both these methods are restricted to reducible flowgraphs.By contrast, our approach can handle irreducible as well as reducible flowgraphs.For the case where an edge is inserted, our incremental algorithm is also faster than previous incremental algorithms in the worst case.For the deletion case, our algorithm has a quadratic time complexity in the worst case.


title: Lightweight Closure Conversion

authors:
Paul Steckler
Mitchell Wand

abstract: We consider the problem of lightweight closure conversion, in which multiple procedure call protocols may coexist in the same code. A lightweight closure omits bindings for some of the free variables of the procedure that is represents. Flow analysis is used to match the protocol expected by each procedure and the protocol used at its possible call sites. We formulate the flow analysis as a deductive system that generates a labeled transition system and a set of constraints. We show that any solution to the constraints justifies the resulting transformation. Some of the techniques used are similar to those of abstract interpretation, but others appear to be novel.


title: An Approach for Exploring Code-Improving Transformations

authors:
Deborah Whitfield
Mary Lou Soffa

abstract: Although code transformations are routinely applied to improve the performance of programs for both scalar and parallel machines, the properties of code-improving transformations are not well understood. In this article we present a framework that enables the exploration, both analytically and experimentally, of properties of code-improving transformations. The major component of the framework is a specification language, Gospel, for expressing the conditions needed to safely apply a transformation and the actions required to change the code to implement the transformation. The framework includes a technique that facilitates an analytical investigation of code-improving transformations using the Gospel specifications. It also contains a tool, Genesis, that automatically produces a transformer that implements the transformations specified in Gospel. We demonstrate the usefulness of the framework by exploring the enabling and disabling properties of transformations. We first present analytical results on the enabling and disabling properties of a set of code transformations, including both traditional and parallelizing transformations, and then describe experimental results showing the types of transformations and the enabling and disabling interactions actually found in a set of programs.


title: A Practical Soft Type System for Scheme

authors:
Andrew K. Wright
Robert Cartwright

abstract: Asoft type systeminfers types for the procedures and data structures of dynamically typed programs. Like conventional static types, soft types express program invariants and thereby provide valuable information for program optimization and debugging. A soft typecheckeruses the types inferred by a soft type system to eliminate run-time checks that are provably unnecessary; any remaining run-time checks are flagged as potential program errors.Soft Schemeis a practical soft type checker for R4RS Scheme. Its underlying type system generalizes conventional Hindley-Milner type inference by incorporating recursive types and a limited form of union type. Soft Scheme accommodates all of R4RS Scheme including uncurried procedures of fixed and variable arity, assignment, and continuations.


title: Symboloc Model Checking for Event-Driven Real-Time Systems

authors:
Jin Yang
Aloysius K. Mok
Farn Wang

abstract: In this article, we consider symbolic model checking for event-driven real-time systems.We first propose a Synchronous Real-Time Event Logic (SREL) for capturing the formal semantics of synchronous, event-driven real-time systems.The concrete syntax of these systems is given in terms of a graphical programming language called Modechart, by Jahanian and Mok, which can be translated into SREL structures.We then present a symbolic model-checking algorithm for SREL.In particular, we give an efficient algorithm for constructing OBDDs (Ordered Binary Decision Diagrams) for linear constraints among integer variables.This is very important in a BDD-based symbolic model checker for real-time systems, since timing and event occurrence constraints are used very often in the specification of these systems.We have incorporated our construction algorithm into the SMV v2.3 from Carnegie-Mellon University and have been able to achieve one to two orders of magnitude in speedup and space saving when compared to the implementation of timing and event-counting functions by integer arithmetics provided by SMV.


title: Protocol Specifications and Component Adaptors

authors:
Daniel M. Yellin
Robert E. Strom

abstract: In this article we examine the augmentation of application interfaces with enhanced specifications that include sequencing constraints called protocols.Protocols make explicit the relationship between messages (methods) supported by the application.These relationships are usually only given implicitly, either in the code or in textual comments.We define notions of interface compatibility based upon protocols and show how compatibility can be checked, discovering a class of errors that cannot be discovered via the type system alone.We then define software adaptors that can be used to bridge the difference between applications that have functionally compatible but type-and protocol-incompatible interfaces.We discuss what it means for an adaptor to be well formed.Leveraging the information provided by protocols, we show how adaptors can be automatically generated from a high-level description, called an interface mapping.


title: A Note on "On the Conversion of Indirect to Direct Recursion"

authors:
Ting Yu
Owen Kaser

abstract: In the article “On the Conversion of Indirect to Direct Recursion”( ACM Lett. Program. Lang. 2, 1-4. pp. 151-164), a method was introduced to convert indirect to direct recursion. It was claimed that for any call graph, there is a mutual-recursion elimination sequence if and only if no strongly connected component contains two node-disjoint circuits. We first give a counterexample and then provide a correction.


title: Partial Evaluation of Functional Logic Programs

authors:
María Alpuente
Moreno Falaschi
Germán Vidal

abstract: Languages that integrate functional and logic programming with a complete operational semantics are based on narrowing, a unification-based goal-solving mechanism which subsumes the reduction principle of functional languages and the resolution principle of logic languages. In this article, we present a partial evaluation scheme for functional logic languages based on an automatic unfolding algorithm which builds narrowing trees. The method is formalized within the theoretical framework established by Lloyd and Shepherdson for the partial deduction of logic programs, which we have generalized for dealing with functional computations. A generic specialization algorithm is proposed which does not depend on the eager or lazy nature of the narrower being used. To the best of our knowledge, this is the first generic algorithm for the specialization of functional logic programs. We also discuss the relation to work on partial evaluation in functional programming, term-rewriting systems, and logic programming. Finally, we present some experimental results with an implementation of the algorithm which show in practice that the narrowing-driven partial evaluator effectively combines the propagation of partial data structures (by means of logical variables and unification) with better opportunities for optimization (thanks to the functional dimension).


title: Finitary Fairness

authors:
Rajeev Alur
Thomas A. Henzinger

abstract: Fairness is a mathematical abstraction: in a multiprogramming environment, fairness abstracts the details of admissible (“fair”) schedulers; in a distributed environment, fairness abstracts the relative speeds of processors. We argue that the standard definition of fairness often is unnecessarily weak and can be replaced by the stronger, yet still abstract, notion of finitary fairness. While standard weak fairness requires that no enabled transition is postponed forever, finitary weak fairness requires that for every computation of a system there is an unknown bound k such that no enabled transition is postponed more than k consecutive times. In general, the finitary restriction fin ( F ) of any given fairness requirement F is the union of all ω-regular safety properties contained in F . The adequacy of the proposed abstraction is shown in two ways. Suppose we prove a program property under the assumption of finitary fairness. In a multiprogramming environment, the program then satisfies the property for all fair finite-state schedulers. In a distributed environment, the program then satisfies the property for all choices of lower and upper bounds on the speeds (or timings) of processors. The benefits of finitary fairness are twofold. First, the proof rules for verifying liveness properties of concurrent programs are simplified: well-founded induction over the natural numbers is adequate to prove termination under finitary fairness. Second, the fundamental problem of consensus in a faulty asynchronous distributed environment can be solved assuming finitary fairness.


title: Alma-O: An Imperative Language That Supports Declarative Programming

authors:
Krzysztof R. Apt
Jacob Brunekreef
Vincent Partington
Andrea Schaerf

abstract: We describe here an implemented small programming language, called Alma-O, that augments the expressive power of imperative programming by a limited number of features inspired by the logic programming paradigm. These additions encourage declarative programming and make it a more attractive vehicle for problems that involve search. We illustrate the use of Alma-O by presenting solutions to a number of classical problems, including α-β search, STRIPS planning, knapsack, and Eight Queens. These solutions are substantially simpler than their counterparts written in the imperative or in the logic programming style and can be used for different purposes without any modification. We also discuss here the implementation of Alma-O and an operational, executable, semantics of a large subset of the language.


title: A Practical and Flexible Flow Analysis for Higher-Order Languages

authors:
J. Michael Ashley
R. Kent Dybvig

abstract: A flow analysis collects data-flow and control-flow information about programs. A compiler can use this information to enable optimizations. The analysis described in this article unifies and extends previous work on flow analysis for higher-order languages supporting assignment and control operators. The analysis is abstract interpretation based and is parameterized over two polyvariance operators and a projection operator. These operators are used to regulate the speed and accuracy of the analysis. An implementation of the analysis is incorporated into and used in a production Scheme compiler. The analysis can process any legal Scheme program without modification. Others have demonstrated that a 0CFA analysis can enables the optimizations, but a 0CFA analysis is O ( n ) 3 ). An O ( n ) instantiation of our analysis successfully enables the optimization of closure representations and procedure calls. Experiments with the cheaper instantiation show that it is as effective as 0CFA for these optimizations.


title: Synthesis of Concurrent Systems with Many Similar Processes

authors:
Paul C. Attie
E. Allen Emerson

abstract: Methods for synthesizing concurrent programs from temporal logic specifications based on the use of a decision procedure for testing temporal satisfiability have been proposed by Emerson and Clarke and by Manna and Wolper. An important advantage of these synthesis methods is that they obviate the need to manually compose a program and manually construct a proof of its correctness. One only has to formulate a precise problem specification; the synthesis method then mechanically constructs a correct solution. A serious drawback of these methods in practice, however, is that they suffer from the state explosion problem. To synthesize a concurrent system consisting of K sequential processes, each having N states in its local transition diagram, requires construction of the global product-machine having about N K global states in general. This exponential growth in K makes it infeasible to synthesize systems composed of more than 2 or 3 processes. In this article, we show how to synthesize concurrent systems consisting of many (i.e., a finite but arbitrarily large number K of) similar sequential processes. Our approach avoids construction of the global product-machine for K processes; instead, it constructs a two-process product-machine for a single pair of generic sequential processes. The method is uniform in K , providing a simple template that can be instantiated for each process to yield a solution for any fixed K . The method is also illustrated on synchronization problems from the literature.


title: A New, Simpler Linear-Time Dominators Algorithm

authors:
Adam L. Buchsbaum
Haim Kaplan
Anne Rogers
Jeffery R. Westbrook

abstract: We present a new linear-time algorithm to find the immediate dominators of all vertices in a flowgraph. Our algorithm is simpler than previous linear-time algorithms: rather than employ complicated data structures, we combine the use of microtrees and memoization with new observations on a restricted class of path compressions. We have implemented our algorithm, and we report experimental results that show that the constant factors are low. Compared to the standard, slightly superlinear algorithm of Lengauer and Tarjan, which has much less overhead, our algorithm runs 10-20% slower on real flowgraphs of reasonable size and only a few percent slower on very large flowgraphs.


title: Dynamic Currency Determination in Optimized Programs

authors:
Dhananjay M. Dhamdhere
K. V. Sankaranarayanan

abstract: Compiler optimizations pose many problems to source-level debugging of an optimized program due to reordering, insertion, and deletion of code. On such problem is to determine whether the value of a varible is current at a breakpoint—that is, whether its actual value is the same as its expected value. We use the notion of dynamic currency of a variable in source-level debugging and propose the use of a minimal unrolled graph to reduce the run-time overhead of dynamic currency determination. We prove that the minimal unrolled graph is an adequate basis for performing bit-vector data flow analyses at a breakpoint. This property is used to perform dynamic currency determination. It is also shown to help in recovery of a dynamically noncurrent variable.


title: A Systematic Study of Functional Language Implementations

authors:
Rémi Douence
Pascal Fradet

abstract: We introduce a unified framework to describe, relate, compare, and classify functional language implementations. The compilation process is expressed as a succession of program transformations in the common framework. At each step, different transformations model fundamental choices. A benefit of this approach is to structure and decompose the implementation process. The correctness proofs can be tackled independently for each step and amount to proving program transformations in the functional world. This approach also paves the way to formal comparisons by making it possible to estimate the complexity of individual transformations or compositions of them. Our study aims at covering the whole known design space of sequential functional language implementations. In particular, we consider call-by-value, call-by-name, call-by-need reduction strategies as well as environment- and graph-based implementations. We describe for each compilation step the diverse alternatives as program transformations. In some cases, we illustrate how to compare or relate compilation techniques, express global optimizations, or hybrid implementations. We also provide a classification of well-known abstract machines.


title: Fast Algorithms for Compressed Multimethod Dispatch Table Generation

authors:
Eric Dujardin
Eric Amiel
Eric Simon

abstract: The efficiency of dynamic dispatch is a major impediment to the adoption of multimethods in object-oriented languages. In this article, we propose a simple multimethod dispatch scheme based on compressed dispatch tables. This scheme is applicable to any object-oriented language using a method precedence order that satisfies a specific monotonous property (e.g., as Cecil and Dylan) and guarantees that dynamic dispatch is performed in constant time, the latter being a major requirement for some languages and applications. We provide efficient algorithms to build the dispatch tables, provide their worst-case complexity, and demonstrate the effectiveness of our scheme by real measurements performed on two large object-oriented applications. Finally, we provide a detailed comparison of our technique with other existing techniques.


title: Within ARM's Reach: Compilation of Left-Linear Rewrite Systems via Minimal Rewrite Systems

authors:
Wan J. Fokkink
Jasper Kamperman
Pum Walters

abstract: A new compilation technique for left-linear term-rewriting systems is presented, where rewrite rules are transformed into so-called minimal rewrite rules. These minimal rules have such a simple form that they can be viewed as instructions for an abstract rewriting machine (ARM).


title: A Logical Model for Relational Abstract Domains

authors:
Roberto Giacobazzi
Francesca Scozzari

abstract: In this article we introduce the notion of Heyting completion in abstract interpretation. We prove that Heyting completion provides a model for Cousot's reduced cardinal power of abstract domains and that it supplies a logical basis to specify relational domains for program analysis and abstract interpretation. We study the algebraic properties of Heyting completion in relation with other well-known domain transformers, like reduced product and disjunctive completion. This provides a uniform algebraic setting where complex abstract domains can be specified by simple logic formulas, or as solutions of recursive abstract domain equations, involving few basic operations for domain construction, all characterized by a clean logical interpretation. We apply our framework to characterize directionality and condensing and in downward closed analysis of (constraint) logic programs.


title: Cost-Optimal Code Motion

abstract: We generalize Knoop et al.'s Lazy Code Motion (LCM) algorithm for partial redundancy elimination so that the generalized version also performs strength reduction. Although Knoop et al. have themselves extended LCM to strength reduction with their Lazy Strength Reduction algorithm, our approach differs substantially from theirs and results in a broader class of candidate expressions, stronger safety guarantees, and the elimination of the potential for performance loss instead of gain. Also, our general framework is not limited to traditional strength reduction, but rather can also handle a wide variety of optimizations in which data-flow information enables the replacement of a computation with a less expensive one. As a simple example, computations can be hoisted to points where they are constant foldable. Another example we sketch is the hoisting of polymorphic operations to points where type analysis provides leverage for optimization. Our general approach consists of placing computations so as to minimize their cost, rather than merely their number. So long as the cost differences between flowgraph nodes obey a certain natural constraint, a cost-optimal code motion transformation that does not unnecessarily prolong the lifetime of temporary varibles can be found using techniques completely analogous to LCM. Specifically, the cost differences can be discovered using a wide variety of forward data-flow analyses in a manner which we describe.


title: A Task- and Data-Parallel Programming Language Based on Shared Objects

authors:
Saniya Ben Hassen
Henri E. Bal
Ceriel J. H. Jacobs

abstract: Many programming languages support either task parallelism, but few languages provide a uniform framework for writing applications that need both types of parallelism or data parallelism. We present a programming language and system that integrates task and data parallelism using shared objects. Shared objects may be stored on one processor or may be replicated. Objects may also be partitioned and distributed on several processors.Task parallelism is achieved by forking processes remotely and have them communicate and synchronize through objects. Data parallelism is achieved by executing operations on partitioned objects in parallel. Writing task-and data-parallel applications with shared objects has several advantages. Programmers use the objects as if they were stored in a memory common to all processors. On distributed-memory machines, if objects are remote, replicated, or partitioned, the system takes care of many low-level details such as data transfers and consistency semantics. In this article, we show how to write task-and data-parallel programs with our shared object model. We also desribe a portable implementation of the model. To assess the performance of the system, we wrote several applications that use task and data parallelism and excuted them on a collection of Pentium Pros connected by Myrinet. The performance of these applications is also discussed in this article.


title: Isomorph-Free Model Enumeration: A New Method for Checking Relational Specifications

authors:
Daniel Jackson
Somesh Jha
Craig Damon

abstract: Software specifications often involve data structures with huge numbers of value, and consequently they cannot be checked using standard state exploration or model-checking techniques. Data structures can be expressed with binary relations, and operations over such structures can be expressed as formulae involving relational variables. Checking properties such as preservation of an invariant thus reduces to determining the validity of a formula or, equivalently, finding a model (of the formula's negation). A new method for finding relational models is presented. It exploits the permutation invariance of models—if two interpretations are isomorphic, then neither is a model, or both are—by partitioning the space into equivalence classes of symmetrical interpretations. Representatives of these classes are constructed incrementally by using the symmetry of the partial interpretation to limit the enumeration of new relation values. The notion of symmetry depends on the type structure of the formula; by picking the weakest typing, larger equivalence classes (and thus fewer representatives) are obtained. A more refined notion of symmetry that exploits the meaning of the relational operators is also described. The method typically leads to exponential reductions; in combination with other, simpler, reductions it makes automatic analysis of relational specifications possible for the first time.


title: Compositional Verification of Concurrent Systems Using Petri-Net-Based Condensation Rules

authors:
Eric Y. T. Juan
Jeffrey J. P. Tsai
Tadao Murata

abstract: The state-explosion problem of formal verification has obstructed its application to large-scale software systems. In this article, we introduce a set of new condensation theories: IOT-failure equivalence, IOT-state equivalence, and firing-dependence theory to cope with this problem. Our condensation theories are much weaker than current theories used for the compositional verification of Petri nets. More significantly, our new condensation theories can eliminate the interleaved behaviors caused by asynchronously sending actions. Therefore, our technique provides a much more powerful means for the compositional verification of asynchronous processes. Our technique can efficiently analyze several state-based properties: boundedness, reachable markings, reachable submarkings, and deadlock states. Based on the notion of our new theories, we develop a set of condensation rules for efficient verification of large-scale software systems. The experimental results show a significant improvement in the analysis large-scale concurrent systems.


title: Optimizing Compilation of CLP(R)

authors:
Andrew D. Kelly
Kim Marriott
Andrew D. Macdonald
Peter J. Stuckey
Roland H. C. Yap

abstract: Constraint Logic Programming (CLP) languages extend logic programming by allowing the use of constraints from different domains such as real numbers or Boolean functions. They have proved to be ideal for expressing problems that require interactive mathematical modeling and complex combinatorial optimization problems. However, CLP languages have mainly been considered as research systems, useful for rapid prototyping, by not really competitive with more conventional programming languages where efficiency is a more important consideration. One promising approach to improving the performance of CLP systems is the use of powerful program optimizations to reduce the cost of constraint solving. We extend work in this area by describing a new optimizing compiler for the CLP language CLP(ℛ). The compiler implements six powerful optimizations: reordering of constraints, removal of redundant variables, and specialization of constraints which cannot fail. Each program optimization is designed to remove the overhead of constraint solving when possible and keep the number of constraints in the store as small as possible. We systematically evaluate the effectiveness of each optimization in isolation and in combination. Our empirical evaluation of the compiler verifies that optimizing compilation can be made efficient enough to allow compilation of real-world programs and that it is worth performing such compilation because it gives significant time and space performance improvements.


title: Automatic Data Layout for Distributed-Memory Machines

authors:
Ken Kennedy
Ulrich Kremer

abstract: The goal of languages like Fortran D or High Performance Fortran (HPF) is to provide a simple yet efficient machine-independent parallel programming model. After the algorithm selection, the data layout choice is the key intellectual challenge in writing an efficient program in such languages. The performance of a data layout depends on the target compilation system, the target machine, the problem size, and the number of available processors. This makes the choice of a good layout extremely difficult for most users of such languages. If languages such as HPF are to find general acceptance, the need for data layout selection support has to be addressed. We beleive that the appropriate way to provide the needed support is through a tool that generates data layout specifications automatically. This article discusses the design and implementation of a data layout selection tool that generates HPF-style data layout specifications automatically. Because layout is done in a tool that is not embedded in the target compiler and hence will be run only a few times during the tuning phase of an application, it can use techniques such as integer programming that may be considered too computationally expensive for inclusion in production compilers. The proposed framework for automatic data layout selection builds and examines search spaces of candidate data layouts. A candidate layout is an efficient layout for some part of the program. After the generation of search spaces, a single candidate layout is selected for each program part, resulting in a data layout for the entire program. A good overall data layout may require the remapping of arrays between program parts. A performance estimator based on a compiler model, an execution model, and a machine model are needed to predict the execution time of each candidate layout and the costs of possible remappings between candidate data layouts. In the proposed framework, instances of NP-complete problems are solved during the construction of candidate layout search spaces and the final selection of candidate layouts from each search space. Rather than resorting to heuristics, the framework capitalizes on state-of-the-art 0-1 integer programming technology to compute optimal solutions of these NP-complete problems. A prototype data layout assistant tool based on our framework has been implemented as part of the D system currently under development at Rice University. The article reports preliminary experimental results. The results indicate that the framework is efficient and allows the generation of data layouts of high quality.


title: A Partially Deadlock-Free Typed Process Calculus

abstract: We propose a novel static type system for a process calculus, which ensures both partial deadlockfreedom and partial confluence.The key novel ideas are (1) introduction of the order of channel use as type information, and (2) classification of communication channels into reliable and unreliable channels based on their usage and a guarantee of the usage by the type system.We can ensure that communication on reliable channels never causes deadlock and also that certain reliable channels never introduce nondeterminism.After presenting the type system and formal proofs of its correctness, we show encodings of the λ-calculus and typical concurrent objects in the deadlockfree fragment of the calculus and demonstrate how type information can be used for reasoning about program behavior.