scispace - formally typeset
Search or ask a question

Showing papers on "Program transformation published in 1992"


Journal ArticleDOI
TL;DR: This classical formal framework for abstract interpretation of programs can be applied in extenso to logic programs and is recalled, using a variant of SLD-resolution as the ground operational semantics.
Abstract: interpretation is a theory of semantics approximation that is used for the construction of semantic-based program analysis algorithms (sometimes called “data flow analysis”), the comparison of formal semantics (e.g., construction of a denotational semantics from an operational one), design of proof methods, etc. Automatic program analysers are used for determining statistically conservative approximations of dynamic properties of programs. Such properties of the run-time behavior of programs are useful for debugging (e.g., type inference), code optimization (e.g., compile-time garbage collection, useless occur-check elimination), program transformation (e.g., partial evaluation, parallelization), and even program correctness proofs (e.g., termination proof). After a few simple introductory examples, we recall the classical framework for abstract interpretation of programs. Starting from a ground operational semantics formalized as a transition system, classes of program properties are first encapsulated in collecting semantics expressed as fixpoints on partial orders representing concrete program properties. We consider invariance properties characterizing descendants of the initial states (corresponding to top/down or forward analyses), ascendant states of the final states (corresponding to bottom/up or backward analyses) as well as a combination of the two. Then we choose specific approximate abstract properties to be gathered about program behaviors and express them as elements of a poset of abstract properties. The correspondence between concrete and abstract properties is established by a concretization and abstraction function that is a Galois connection formalizing the loss of information. We can then constructively derive the abstract program properties from the collecting semantics by a formal computation leading to a fixpoint expression in terms of abstract operators on the domain of abstract properties. The design of the abstract interpreter then involves the choice of a chaotic iteration strategy to solve this abstract fixpoint equation. We insist on the compositional design of this abstract interpreter, which is formalized by a series of propositions for designing Galois connections (such as Moore families, decomposition by partitioning, reduced product, down-set completion, etc.). Then we recall the convergence acceleration methods using widening and narrowing allowing for the use of very expressive infinite domains of abstract properties. We show that this classical formal framework can be applied in extenso to logic programs. For simplicity, we use a variant of SLD-resolution as the ground operational semantics. The first example is groundness analysis, which is a variant of Mellish mode analysis. It is extended to a combination of top/down and bottom/up analyses. The second example is the derivation of constraints among argument sizes, which involves an infinite abstract domain requiring the use of convergence accelaration methods. We end up with a short thematic guide to the literature on abstract interpretation of logic programs.

671 citations


Journal ArticleDOI
TL;DR: A fundamental analis step in an ad',nced optimizing compiler (as well as many other software tools) is data dependence analysis f o r arrays, which determines whether two references to an array can refer to the same e lement and under what conditions.
Abstract: ndamental analis step in an ad',nced optimizing compiler (as well as many other software tools) is data dependence analysis f o r arrays. This means deciding i f two references to an array can refer to the same e lement and i f so, under what conditions. This information is used to determine allowable program transformations and optimizations. For example, we can determine that in the fo l lowing code fragment , no location o f the array is both read and written. Once we also verify that no location is writ ten more than once, we know that the writes can be done in any order. for i = 1 to 100 do f o r j -i to 100 do A[i, j + 11 = A[100,j]

590 citations


Proceedings ArticleDOI
01 Feb 1992
TL;DR: A program transformation that allows languages with polymorphic typing to be implemented with unboxed, multi-word data representations with coercions between various representations, based on a typing derivation is presented.
Abstract: This paper presents a program transformation that allows languages with polymorphic typing (e.g. ML) to be implemented with unboxed, multi-word data representations. The transformation introduces coercions between various representations, based on a typing derivation. A prototype ML compiler utilizing this transformation demonstrates important speedups.

243 citations


Journal ArticleDOI
TL;DR: The authors extend the notion of structural testing criteria to concurrent programs and propose a hierarchy of supporting structural testing techniques, suitable for Ada or CSP-like languages.
Abstract: Although structural testing techniques are among the weakest available with regard to developing confidence in sequential programs, they are not without merit. The authors extend the notion of structural testing criteria to concurrent programs and propose a hierarchy of supporting structural testing techniques. Coverage criteria described include concurrency state coverage, state transition coverage and synchronization coverage. Requisite support tools include a static concurrency analyzer and either a program transformation system or a powerful run-time monitor. Also helpful is a controllable run-time scheduler. The techniques proposed are suitable for Ada or CSP-like languages. Best results are obtained for programs having only static naming of tasking objects. >

217 citations


Journal ArticleDOI
TL;DR: An informal tutorial for program synthesis is presented, with an emphasis on deductive methods, based on the deductive-tableau system, a theorem-proving framework particularly suitable forprogram synthesis.
Abstract: An informal tutorial for program synthesis is presented, with an emphasis on deductive methods. According to this approach, to construct a program meeting a given specification, the authors prove the existence of an object meeting the specified conditions. The proof is restricted to be sufficiently constructive, in the sense that, in establishing the existence of the desired output, the proof is forced to indicate a computational method for finding it. That method becomes the basis for a program that can be extracted from the proof. The exposition is based on the deductive-tableau system, a theorem-proving framework particularly suitable for program synthesis. The system includes a nonclausal resolution rule, facilities for reasoning about equality, and a well-founded induction rule. >

165 citations


Journal ArticleDOI
01 Dec 1992
TL;DR: An efficient macro system is described that prevents inadvertent capturing while maintaining the correlation between source and object code.
Abstract: Naive program transformations can have surprising effects due to the interaction between introduced identifier references and previously existing identifier bindings, or between introduced bindings and previously existing references. These interactions can result in inadvertent binding, or capturing, of identifiers. A further complication is that transformed programs may have little resemblance to original programs, making correlation of source and object code difficult. This article describes an efficient macro system that prevents inadvertent capturing while maintaining the correlation between source and object code. The macro system allows the programmer to define program transformations using an unrestricted, general-purpose language. Previous approaches to the capturing problem have been inadequate, overly restrictive, or inefficient, and the problem of source-object correlation has been largely unaddressed. The macro system is based on a new algorithm for implementing syntactic transformations and a new representation for syntactic expressions.

162 citations


Journal ArticleDOI
TL;DR: An approach to automated concept recognition and its application to maintenance-related program transformations are described, with a unique characteristic that transformations of code can be expressed as transformations of abstract concepts.
Abstract: The automated recognition of abstract high-level conceptual information or concepts, which can greatly aid the understanding of programs and therefore support many software maintenance and reengineering activities, is considered. An approach to automated concept recognition and its application to maintenance-related program transformations are described. A unique characteristic of this approach is that transformations of code can be expressed as transformations of abstract concepts. This significantly elevates the level of transformation specifications. >

137 citations


Journal ArticleDOI
TL;DR: A single method for normalizing the control-flow of programs to facilitate program transformations, program analysis, and automatic parallelization is presented, which obviates the control dependence graph and is simpler in their syntax and structure than with previous methods.
Abstract: A single method for normalizing the control-flow of programs to facilitate program transformations, program analysis, and automatic parallelization is presented. While previous methods result in programs whose control flowgraphs are reducible, programs normalized by this technique satisfy a stronger condition than reducibility and are therefore simpler in their syntax and structure than with previous methods. In particular, all control-flow cycles are normalized into single-entry, single-exit while loops and all GOTOs are eliminated. Furthermore, the method avoids problems of code replication that are characteristic of node-splitting techniques. This restructuring obviates the control dependence graph, since afterwards control dependence relations are manifest in the syntax tree of the program. Transformations that effect this normalization are presented, and the complexity of the method is studied. >

85 citations


Journal ArticleDOI
TL;DR: Equations representing the execution time performance of noninlined and inlined versions of a program have been developed and the accuracy of the equations' description of inlined program execution time behavior was demonstrated.
Abstract: Equations representing the execution time performance of noninlined and inlined versions of a program have been developed. The accuracy of the equations' description of inlined program execution time behavior was demonstrated on four computer systems. Using the equations, understanding of how certain factors influence the speed of inlined code was gained. Contrary to a number of published reports in the literature, the increased size of inlined code was not found to affect its execution time performance on demand-paged virtual memory machines. On such systems, neither the use of an inlining algorithm that includes program size constraints nor the substitution of interprocedural data flow analysis for inlining is warranted. A modest improvement in the caching and paging behavior of test programs' inlined versions was also observed. >

73 citations


Journal ArticleDOI
TL;DR: The problem of allocating vector registers on supercomputers is addressed in the context of compiling vector languages, and techniques described extend naturally to scalar machines by observing that a scalar register is simply a vector register of length one.
Abstract: The problem of allocating vector registers on supercomputers is addressed in the context of compiling vector languages. Two subproblems must be solved to achieve good vector register allocation. First, the vector operations in the source program must be subdivided into sections that fit the hardware of the target machine. Second, the locality of reference of the vector operations must be improved via aggressive program transformations. Solutions to both of these problems, based on the use of novel aspects of data dependence, are presented. The techniques described extend naturally to scalar machines by observing that a scalar register is simply a vector register of length one. >

70 citations


Proceedings ArticleDOI
09 Nov 1992
TL;DR: The method by which the previously developed theoretical approach has been interpreted to provide the means to address the reverse engineering of real-world programs of medium size, written in IBM 370 Assembler is presented.
Abstract: An outline of the principles and design features of the Maintainer's Assistant is presented. The main results presented concern the method by which the previously developed theoretical approach has been interpreted to provide the means to address the reverse engineering of real-world programs of medium size, written in IBM 370 Assembler. In particular, the use of appropriate metrices to guide the user during the process of program transformation is described. Results are given to show the success of the tool when it has been applied to real code. >

Journal ArticleDOI
TL;DR: The design and a prototypical implementation of COMPLEX, which is a logic-based system extended with concepts from the object-oriented paradigm and is intended as a tool for the development of knowledge-based applications, are described.
Abstract: The design and a prototypical implementation of COMPLEX, which is a logic-based system extended with concepts from the object-oriented paradigm and is intended as a tool for the development of knowledge-based applications, are described. The system supports a logic language, called Complex-Datalog (C-Datalog), enhanced by semantic constructs to provide facility for data abstraction. Its implementation is based on a bottom-up computational model that guarantees a fully declarative style of programming. However, the user is also given the possibility of running a query using a top-down model of computation. Efficiency of execution is the result of the integration of different novel technologies for the compilation and the execution of queries. >

Journal ArticleDOI
TL;DR: The system provides a high-level specification language to let programmers specify what they want to know about their program's execution and automatically generates an augmented program whose execution produces both the results of the original program and answers to the specified questions.
Abstract: Program monitoring and measuring is the activity of collecting information about the execution characteristics of a program. Although this activity is occasionally supported by special-purpose hardware, it is normally done by adding instrumentation code to the program so that it collects interesting data as it runs. Unfortunately, this alteration is itself a difficult task involving all the complexities of programming. Given some questions to be answered, the programmer must determine what data must be collected, determine where in the program those data can be collected, and add code to the program to collect that data and to process it to produce the desired results. The goal of the work described is to automate the process. A high-level program monitoring and measuring system is presented. The system provides a high-level specification language to let programmers specify what they want to know about their program's execution. It automatically generates an augmented program whose execution produces both the results of the original program and answers to the specified questions. >

01 Jan 1992
TL;DR: In this paper, a program transformation that transforms every program into a program for which only the calls to the built-in unification predicate need to be resolved by a unification algorithm with the occur-check is presented.
Abstract: In most PROLOG implementations, for efficiency occur-check is omitted from the unification algorithm. This paper provides natural syntactic conditions that allow the occur-check to be safely omitted. The established results apply to most well-known PROLOG programs, including those that use difference lists, and seem to explain why this omission does not lead in practice to any complications. When applying these results to general programs, we show their usefulness for proving absence of floundering. Finally, we propose a program transformation that transforms every program into a program for which only the calls to the built-in unification predicate need to be resolved by a unification algorithm with the occur-check.

Journal ArticleDOI
TL;DR: Students and professional programmers were asked to make either simple or complex modifications to programs that had been generated using each of three different program structures, suggesting that problem structure, problem content, complexity of modification, and programmer experience all play a crucial role in determining performance and the representation formed.
Abstract: A number of claims have been made by the developers of program design methodologies, including the claim that the code produced by following the methodologies will be more understandable and more easily maintained than code produced in other ways. However, there has been little empirical research to test these claims. In this study, student and professional programmers were asked to make either simple or complex modifications to programs that had been generated using each of three different program structures. Data on the programmers' modification performance, cognitive representations formed of the programs and subjective reactions to the programs suggested that problem structure (as created by the different methodologies), problem content, complexity of modification, and programmer experience all play a crucial role in determining performance and the representation formed.

Journal ArticleDOI
TL;DR: This paper defines a single-conclusion consequence relation between finite sets of constraints and assertions, and establishes several metatheoretic properties of constrained equivalence and the formal system, including soundness, completeness, and a comparison of the equivalence relations on various fragments.

Proceedings Article
01 Jan 1992
TL;DR: This work considers partial evaluation of the pragmatic oriented imperative C programming language, defines a Core C language, derive a two-level Core Clanguage with explicit binding times, and formulate well-annotatedness conditions.
Abstract: A partial evaluator is an automatic program transformation tool. Given as input a general program and part of its input, it can produce a specialized version. If the partial evaluator is self-applicable, program generators can be made. The goal is efficiency : the specialized program often runs an order of magnitude faster than the general one. We consider partial evaluation of the pragmatic oriented imperative C programming language. New problems studied includes partially static data structures, non-local static side-effects under dynamic control, and a restricted use of pointers. We define a Core C language, derive a two-level Core C language with explicit binding times, and formulate well-annotatedness conditions. Function specialization and code generation is described in terms of the two-level Core C language. An implementation of the C partial evaluator has been made. Some experimental results are given.

Proceedings ArticleDOI
01 Jul 1992
TL;DR: Alphonse is a program transformation system that uses dynamic dependency analysis and incremental computation techniques to automatically generate efficient dynamic implementations from simple exhaustive imperative program specifications.
Abstract: Alphonse is a program transformation system that uses dynamic dependency analysis and incremental computation techniques to automatically generate efficient dynamic implementations from simple exhaustive imperative program specifications.

Journal ArticleDOI
TL;DR: In this article, the authors present techniques for incrementally incorporating changes into globally optimized code, and an algorithm is given for determining which optimizations are no longer safe after a program change and for discovering which new optimizations can be performed in order to maintain a high level of optimization.
Abstract: Although optimizing compilers have been quite successful in producing excellent code, two factors that limit their usefulness are the accompanying long compilation times and the lack of good symbolic debuggers for optimized code. One approach to attaining faster recompilations is to reduce the redundant analysis that is performed for optimization in response to edits, and in particulars, small maintenance changes, without affecting the quality of the generated code. Although modular programming with separate compilation aids in eliminating unnecessary recompilation and reoptimization, recent studies have discovered that more efficient code can be generated by collapsing a modular program through procedure inlining. To avoid having to reoptimize the resultant large procedures, this paper presents techniques for incrementally incorporating changes into globally optimized code. An algorithm is given for determining which optimizations are no longer safe after a program change, and for discovering which new optimizations can be performed in order to maintain a high level of optimization. An intermediate representation is incrementally updated to reflect the current optimizations in the program. Analysis is performed in response to changes rather than in preparation for possible changes, so analysis is not wasted if an edit has no far-reaching effects. The techniques developed in this paper have also been exploited to improve on the current techniques for symbolic debugging of optimized code.

Patent
13 Jan 1992
TL;DR: In this article, a plurality of program components, which do not have matching interfaces, are combined together automatically to generate a larger new program, where a mediating program generator detects a mismatch of the interface specifications between at least two program components which are being combined and generates mediating programs in accordance with the program transformation rule and the data type transformation rule, which mediates program enables the two programs and their data to communicate.
Abstract: A plurality of program components, which do not have matching interfaces, are combined together automatically to generate a larger new program. An interface specifications' database registers the interface specifications corresponding to each of the program components. A program transformation rule memory stores transformation rules for controlling the reconciliation of the non-matching interface specifications of the program components. A data type memory stores data type transformation rules for reconciling non matching data specifications. A mediating program generator detects a mismatch of the interface specifications between at least two program components which are being combined and generates a mediating program in accordance with the program transformation rule and the data type transformation rule which mediating program enables the two programs and their data to communicate. A components composer generates the larger new program from the program components in the program components' database and the generated mediating program.

Book ChapterDOI
01 Jan 1992
TL;DR: Transformation schemata as mentioned in this paper are predefined abstract transformations of logic programs: input programs are transformed into output program schems, each transformation schema represents one transformation strategy, for example a particular sequence of applications of the unfold/fold rules, or the introduction of an accumulator data structure.
Abstract: Transformation schemata are predefined abstract transformations of logic programs: input program schemata are transformed into output program schemata. Each transformation schema represents one transformation strategy, for example a particular sequence of applications of the unfold/fold rules, or the introduction of an accumulator data structure. The transformation of logic programs with the help of transformation schemata proceeds in three steps: abstraction of the programs to program schemata, selection of a transformation schema with these schemata as input and a suitable schema as output, and specialization of the output schema to the transformed program. Once the transformation schemata are available, user intervention is required only during the selection step. For standard transformation situations one can even envisage eliminating user interaction altogether by heuristics.

Journal ArticleDOI
TL;DR: The analysis-synthesis approach contrasts with previous methods using template matching and induces a constructive method which is better suited to mechanisation, although its implementation is not considered here.

Journal ArticleDOI
TL;DR: A unified approach to the development of algorithms tailored to various classes of parallel computer architecture is presented to identify a small set of higher-order functions that can be implemented efficiently on the target architecture and which can be used to express parallel algorithms.
Abstract: A unified approach to the development of algorithms tailored to various classes of parallel computer architecture is presented. The central theme is to identify a small set of higher-order functions that can be implemented efficiently on the target architecture and which can be used to express parallel algorithms - in general via mechanised program transformation from some higher-level specification. Such higher-order functions enable generic programs to be written in which much parallelism may be explicit. Although the analysis uses purely functional languages, it is the functional paradigm that is important and not the particular syntax. The proposed methodology is illustrated with a numerical problem which is solved directly by a non-recursive program. We also describe schemes that map programs onto both static and dynamic MIMD architectures which have communication links which are fixed and changeable at run-time respectively.

Journal ArticleDOI
TL;DR: This work presents a method for synthesising recursive inverses for first-order functions that is more generally applicable than previous approaches to this type of optimis tion, and in general induces more mechanisable transformation systems.
Abstract: We present a method for synthesising recursive inverses for first-order functions. Since inverse functions are not, in general, single-valued, we introduce a powerdomain to define their semantics, in terms of which we express their transformation into recursive form. First, inverses that require unification at run-time are synthesised and these are then optimised by term-rewriting based on a set of axioms that facilitates a form of compile-time unification. The optimisations reduce the dependency on run-time unification, in many instances removing it entirely to give a recursive inverse. The efficiency of the use of relations in two modes is thereby improved, so enhencing extended functional languages endowed with logical variables and narrowing semantics. Our function-level, axiomatised system is more generally applicable than previous approaches to this type of optimis tion, and in general induces more mechanisable transformation systems.

Journal ArticleDOI
TL;DR: The design of procedural and object-oriented programming languages is considered with respect to how easily programs written in those languages can be formally manipulated, and three main areas of language design are identified as being of concern.
Abstract: The design of procedural and object-oriented programming languages is considered with respect to how easily programs written in those languages can be formally manipulated. Current procedural languages such as Pascal, Modula-2 and Ada; generally support such program manipulations, except for some annoying anomalies and special cases. Three main areas of language design are identified as being of concern from a manipulation viewpoint: the interface between concrete and abstract syntax; the relationship between the abstract syntax and static semantics naming, scoping and typing; and the ability to express basic transformations (folding and unfolding). Design principles are suggested so that the problems identified for current languages can be avoided in the future. >

Book ChapterDOI
06 Jul 1992
TL;DR: Profiling tools, which measure and display the dynamic space and time behaviour of programs, are essential for identifying execution bottlenecks for non-strict functional languages.
Abstract: Profiling tools, which measure and display the dynamic space and time behaviour of programs, are essential for identifying execution bottlenecks. A variety of such tools exist for conventional languages, but almost none for non-strict functional languages. There is a good reason for this: lazy evaluation means that the program is executed in an order which is not immediately apparent from the source code, so it is difficult to relate dynamically-gathered statistics back to the original source.

Journal ArticleDOI
TL;DR: To master software development, the whole process is split into smaller steps by introducing formal specifications for (parts of) the problem and then stepwisely deriving efficient programs by correctness-preserving transformations.
Abstract: The task of software production is to build software systems which are to fulfil certain requirements. For years the approach has been to build up by trial and error a program which, having satisfied carefully prepared test data, offers a plausible solution to the problem. But is it correct? Even for toy examples this is not obvious. In particular, it is often not even clear whether the original problem has been fully understood. The reason for this dilemma is that the transition from the informal problem statement to the final program is too big to be intellectually managable. To master these problems, we advocate a software development method where the whole process is split into smaller steps by introducing formal specifications for (parts of) the problem and then stepwisely deriving efficient programs by correctness-preserving transformations.

Journal ArticleDOI
01 Oct 1992
TL;DR: A new modeling, using symbols and functional notations, is introduced, called PEI (as Parallel Equations Interpretor), which could unify the classical approaches of program parallelization, according to the sorts of problems and the target computation schemes.
Abstract: The aim of this paper is to introduce a new modeling, using symbols and functional notations, called the language PEI (as Parallel Equations Interpretor), which could unify the classical approaches of program parallelization, according to the sorts of problems and the target computation schemes. Due to its fundamental structure, disconnected from concrete drawings, this modeling offers a straightforward generalization to adress convex or non-convex computation domains, synchronous or asynchronous computations. This sort of programming formalism allows a powerful structuration of statements and a stepwise tranformation technique based on a semantical equivalence definition and a refinement calculus. From initial problem statements, transformations of expressions lead to various definition structures, which can match given computation models.

Journal ArticleDOI
TL;DR: Although tremendous advances have been made in dependence theory and in the development of a “toolkit” of transformations, parallel systems are used most effectively when the programmer interacts in the optimization process.
Abstract: The exploitation of today's high-performance computer systems requires the effective use of parallelism in many forms and at numerous levels. This survey article discusses program analysis and restructuring techniques that target parallel architectures. We first describe various categories of architectures that are oriented toward parallel computation models: vector architectures, shared-memory multiprocessors, massively parallel machines, message-passing architectures, VLIWs, and multithreaded architectures. We then describe a variety of optimization techniques that can be applied to sequential programs to effectively utilize the vector and parallel processing units. After an overview of basic dependence analysis, we present restructuring transformations on DO loops targeted both to vectorization and to concurrent execution, interprocedural and pointer analysis, task scheduling, instruction-level parallelization, and compiler-assisted data placement. We conclude that although tremendous advances have been made in dependence theory and in the development of a “toolkit” of transformations, parallel systems are used most effectively when the programmer interacts in the optimization process.