johnson@cs.uiuc.edu (Ralph Johnson) (08/01/90)
David Chase argued that it was already known how to find instructions that matched complicated patterns in the original program. I am familiar with about half of the papers that he mentioned, so perhaps I am missing something, but it was my understanding that these techniques were not very good for matching instructions with loops in them, like block moves. Further, the incompleteness of arithmetic says that it may not be possible to canonicalize all input patterns. The tree matching techniques are very good at finding complex addressing modes, but they are not the end-all and be-all of code generation. I would love to be proven wrong, because we have built our own code generator (in Smalltalk, which is why we didn't use someone else's), and are always looking for ways to improve it. By the way, the GNU compilers use a pattern matching code generator. Also, I agree that those who are interested in this area should take a look at Robert Henry's UWCODEGEN. Ralph Johnson - University of Illinois at Urbana-Champaign -- Send compilers articles to compilers@esegue.segue.boston.ma.us {spdcc | ima | lotus| world}!esegue. Meta-mail to compilers-request@esegue.
moss@cs.umass.edu (08/07/90)
I'm jumping into this thread without having seen what went before, and I'm also at home so I can't use my bookshelf to double check my memory, but I seem to recall that someone did a PhD thesis in the last ten years that indeed could match patterns for rather complex instructions, though I am not sure about loops (I do think it tried for block moves and such, so maybe loops are included?). My recollection comes up with Rick Cattell's thesis, but I could be wrong about that. Further comments? (And maybe I'll try to find his thesis among my books when I'm next in my office ....) Eliot -- J. Eliot B. Moss, Assistant Professor Department of Computer and Information Science Lederle Graduate Research Center University of Massachusetts Amherst, MA 01003 (413) 545-4206; Moss@cs.umass.edu -- Send compilers articles to compilers@esegue.segue.boston.ma.us {spdcc | ima | lotus| world}!esegue. Meta-mail to compilers-request@esegue.
pd@complex.Eng.Sun.COM (Peter C. Damron) (08/15/90)
I have been following with interest the postings on recognition of idioms/complex instructions. I have included a brief summary of the relevant discussion at the end of this posting. I have been working on a dissertation with Robert Henry from University of Washington. The tentative title is: "Code Generation for Complex Instructions using Graph Parsing" I can't really summarize the whole dissertation here, but let me try to cover a few salient points. Goal ---- Be able to recognize instances of "complex instructions" embedded in the intermediate representation of a source program. Where, complex instructions are things like "block copy", "string search", "polynomial evaluation", etc. Method ------ Use the program dependence graph (PDG) as the intermediate representation, thus bringing related computations into connected sub-graphs. Use a graph grammar to encode the computations of the complex instructions into graph patterns. Use graph parsing (or graph pattern matching) to find instances of pattern graphs (complex instructions) in a given subject PDG. Results and Comments -------------------- 1. Code Generation ------------------ It is possible to devise techniques to recognize instances of "complex instructions" and generator code for them. Historically, there have been a number of approaches to this problem. They can be roughly categorized as: A. Assembly language code B. Library routines (that get in-lined) C. Peephole or other special purpose optimizations D. Code generators Probably the most successful technique is to use library routines, and in-line them when appropriate. Peephole optimization techniques tend to be non-portable and difficult to develop or extend. Code generators have so far been limited to recognizing tree patterns (and DAG patterns to some degree). The tree patterns may be used to "encode" or describe arbitrarily large expressions (as noted by chased@Eng.Sun.COM (David Chase)). However, tree pattern matchers typically operate on ordered (as in left, then right) binary trees. One problem with this type of representation is the arbitrary order imposed on unordered operations (e.g. sequences of statements that are not dependent on each other). Perhaps tree pattern matchers can be extended to handle this problem. Another problem involves recognizing control flow (or dependence) constructs (as noted by johnson@cs.uiuc.edu (Ralph Johnson)). It does seem that structured control flow would be encodable into a tree form, but loops may still be a problem because of the associated data flow (or dependence). This causes the program representation to form a more general directed graph. It would be interesting to study further whether tree (or dag) based pattern matchers could be used to recognize instances of complex instructions in structured programs. I considered the more general problem of recognizing complex instructions in the presence of arbitrary control and data flow (really control and data dependence). The most relevant references that I know of are: %T Analyzing Exotic Instructions for a Retargetable Code Generator %A Thomas M. Morgan %A Lawrence A. Rowe %P 197-204 %J CCC82 (Sigplan Compiler Construction Conf.) %D 1982 %X This work develops techniques for transforming high-level language constructs into machine language constructs. Emphasis in on determining equivalence. Not really suitable for code generation. Summary of Morgan's dissertation work. %T Analysis Techniques for Exotic Machine Instructions and Their Use in Retargetable Compilers %A T. M. Morgan %R PhD Dissertation %I UCBCS %D JUN 1982 %A Lawrence Snyder %K larry %T Recognition and Selection of Idioms for Code Optimization %J ACTA %V 17 %P 327-348 %D 1982 %X This is basically a tree pattern matching algorithm for APL that uses dynamic programming to select patterns/idioms. A pre-cursor to later tree pattern matching work. 2. Use of the PDG ----------------- It is possible to use the program dependence graph as an intermediate representation, and generate code directly. Whether it is possible to optimize on the PDG is another question to which I think the answer is yes. After all, after flow analysis, all types of intermediate representations end up being dependence graphs. The only thing special about the PDG is that the dependence edges are more explicit, and control dependence is used instead of control flow. I would like to thank Karl Ottenstein from Los Alamos National Lab, and Tom Reps from Univ. of Wisconsin for providing front-ends to produce PDG's. 3. Graph Parsing and Graph Pattern Matching ------------------------------------------- It is possible to describe graphs as complex as PDG's using a (a new type of) graph grammar. It is possible to parse PDG's based on graph grammars of this type. However, graph parsing is pretty slow (worst case exponential for PDG graphs, in practice it looks like about n**2 as far out as I've tried). Also, graph parsers are quite difficult to describe, though the basic concepts of the construction are quite simple. Overall, this is not likely to be a useful technique for production compilers. Hope I wasn't too long winded, Peter. ---------------------------- Peter C. Damron Sun Microsystems, Inc. Advanced Languages, MS 12-40 2550 Garcia Ave. Mtn. View, CA 94043 pdamron@eng.sun.com ---------------------------- Well, let me see if I can summarize the discussion so far. It all started out with some discussion about implementing special functions efficiently. I believe that cik@l.cc.purdue.edu (Herman Rubin) was one of the one who suggested that nint() was a candidate for a function best written in assembler. Then ok@mudla.cs.mu.OZ (Richard O'Keefe) suggested the code: > double nint(double x) { > return ceil(x + 0.5) - (fmod(x*0.5 + 0.25, 1.0) != 0); > } Then, cik@l.cc.purdue.edu (Herman Rubin) comments: > I do not see how a compiler can recognize that the complicated body of code > can be replaced by a single instruction and make that substitution. One > could put that one in, but another will arise, and another. And these will > continue to crop up as long as the language primitives are restricted as > they now are. Now, chased@Eng.Sun.COM (David Chase) enters the picture with: > Sounds to me like another case of someone who hasn't done their homework. > Besides peephole optimization (mentioned by Preston Briggs), there's also > Graham-Glanville style code-generation, which has been adapted in recent > years to take advantage of improvements in tree-pattern matching... > > To make a long story short, you just write down the patterns, and ... > the tree-pattern-matcher generator spits out tables for you. > Find a new pattern, just add it to the list of patterns with a cost and code > generation rule, and you're set. There's a bit of additional work required > to canonicalize the input patterns (think of all the horrible ways that > > ceil(x + 0.5) - (fmod(x*0.5 + 0.25, 1.0) != 0) > > could be permuted), but similar transformations are already done to assist in > the recognition of loop-invariant and inductive computations (for example). > People have proposed optimizing APL in a similar fashion ... > > Do people build code generators like this today? Yes. Write to Robert > Henry, rrh@cs.washington.edu, and ask for UWCODEGEN. Then, johnson@cs.uiuc.edu (Ralph Johnson) points out: > David Chase argued that it was already known how to find instructions that > matched complicated patterns in the original program. I am familiar with > about half of the papers that he mentioned, so perhaps I am missing > something, but it was my understanding that these techniques were not very > good for matching instructions with loops in them, like block moves. > Further, the incompleteness of arithmetic says that it may not be possible to > canonicalize all input patterns. The tree matching techniques are very good > at finding complex addressing modes, but they are not the end-all and be-all > of code generation. > > By the way, the GNU compilers use a pattern matching code generator. Also, I > agree that those who are interested in this area should take a look at Robert > Henry's UWCODEGEN. Also, moss@cs.umass.edu (J. Eliot B. Moss) mentions: > ... I seem to recall that someone did a PhD thesis in the last ten years > that indeed could match patterns for rather complex instructions, though I > am not sure about loops (I do think it tried for block moves and such, so > maybe loops are included?). My recollection comes up with Rick Cattell's > thesis... Also of note is a comment by the moderator johnl@esegue.segue.boston.ma.us (John R. Levine) in response to a posting with a nice review intermediate representations by preston@rice.edu (Preston Briggs). > [Anybody tried program dependency graphs, per Ferrante et al. at IBM. From > the articles I've seen, they look pretty neat. -John] -- Send compilers articles to compilers@esegue.segue.boston.ma.us {ima | spdcc | world}!esegue. Meta-mail to compilers-request@esegue.