CS912 Semester Project


The goal of the project is to perform an in-depth investigation of a particular "advanced compiler design" topic. The project can be student-designed, but your project plan must be approved in advance. The project might be programming-based, or it might be a design or research project whose final "deliverable" is a document. A list of possible projects is given below.

Students are encouraged to discuss (by phone, e-mail or in person) their project plans informally with me. Ask for feedback about your preliminary ideas, ask for more details about one of the project suggestions, etc. My role is to help you settle on something that is interesting to you but also contains a substantial learning opportunity.

All students are required to submit a formal project plan via e-mail no later than October 4. First, the plan must specify the project scope and goals. In particular, what exactly do you plan to do? What do you plan to learn? Second, the plan should establish a schedule for completing the project subtasks. You should investigate the selected project to estimate the required effort to complete each subtask. You should also determine how you will be able to complete the subtasks given the particular constraints on your time during the Fall semester. Each plan must include the scheduling of a formal meeting with me at an intermediate checkpoint for a project review. The intermediate checkpoint must be performed prior to November 8.

The project plan can be amended as the semester progresses by sending e-mail to me with the reasons for the change. (However, you cannot change the project option that you initially choose.) The project plan itself will be worth 20% of the project grade. Project plans will be graded at the end of the semester primarily based upon how seriously you took the planning process. The key goal is to have no surprises at the end of the semester. If you are struggling with the project during the semester, I want to know right away, so that I can provide advice and assistance.

Each student will be required to present a final project report in class on December 6 or December 13. You may also be required to meet with me for a one-on-one final review.

An essential part of the project is a self-evaluation to be performed at the end of the semester. What was actually accomplished? How well did you meet the project goals? What are the strengths of your work? What are the weaknesses? What would you do differently if you were to start again? This self-evaluation should be written down and submitted for grading, and it should also be summarized during your final project presentation.

Project Suggestions

  1. Complete and Robust Code Selector.

    Continue your work with the Alpha code selector to thoroughly test both your code selector and java2c. (In fact, it is very likely that this project will require you to debug and repair java2c.) Test language features, like exception handling, that are not tested by the Hennessy benchmark suite. (An extended Hyperion test program exists to help you with the testing.) You will be required also to come up with a strategy for making your Alpha output code executable. This requires that you come up with a simple strategy for doing register allocation. This could include using small test programs so that the register demands are minimal, making modifications to java2c to indicate the live ranges of temporaries, or doing some more complex register allocation strategy. The goal of this project would be to learn the details of the Hyperion implementation strategy. The deliverable for the project would be a suite of test programs that thoroughly test the HYP-IC for Alpha implementation.

  2. Register Allocation.

    Construct a register allocator for the HYP-IC system based upon the graph coloring scheme proposed by Chaitin (Register Allocation & Spilling via Graph Coloring, 1982 Compiler Construction Conference, in ACM SIGPLAN Notices Vol. 17, Num. 6).

    Use your code selector to provide the input. The graph coloring algorithm will then map the Alpha pseudo registers to actual registers.

    The register allocator should work at the method level. Your register allocator should allocate the Alpha "temporary" registers ($1-$8, $22-$25; $f10-$f15, $f22-$f30).

    This project is logically divided into four phases.

    First, you must build a control flow graph from the stream of instructions provided by the baseline code generator for a given method. Each node in the graph is a basic block. Basic blocks are delimited by labels and branch/jump instructions (but not subroutine calls). The edges in the graph are directed and connect branch/jump instructions to their destinations or indicate "fall-through" execution semantics.

    Second, you must calculate the live ranges of all pseudo registers. This requires that an iterative data-flow algorithm be executed upon the control flow graph. For debugging purposes, and for grading purposes, print out the results of this data-flow phase. In particular, print the LIVE set calculated for each basic block.

    Third, you must build a pseudo register interference graph. The graph is constructed with one more traversal of the control flow graph and with the aid of the data-flow information calculated earlier. For debugging purposes, and for grading purposes, print out a concise representation (perhaps the edges?) of the interference graph.

    Fourth, use the approach of Chaitin to color the interference graph and to assign real registers to the pseudo registers. You have some flexibility in the exact heuristics that you use: either faithfully reproduce Chaitin's approach, or use improvements suggested in the more recent literature, or try out some reasonable variant of your own. (For partial credit you can assume that you will never need to spill.) Implementing subsumption is not required. For debugging purposes, and for grading purposes, print out the results of the coloring algorithm. That is, print out which real register is assigned to each pseudo register.

    Whichever variant you use should include some cost metric for trying to determine the best pseudo register to spill. This metric should include both the degree of the register's node in the interference graph and the number of use and definition points.

    The graph coloring phase should also, of course, use the calculated coloring to modify the code in each basic block.

    The debugging outputs should all be optional, but I will want to be able to see these outputs when grading this project. Of course, the ultimate output of this project is the modified output code.

    The primary test data for this project are the Hennessy benchmarks (plus pi.java). You, of course, will also want to perform additional tests. And, when testing, you will want to constrain the register resources in order to test your spill/reload handling. For fun, try to find the minimum number of registers necessary to handle the Hennessy benchmarks.

  3. Instruction Scheduling.

    Construct an instruction scheduler for the Java/Alpha system based upon the approach of Gibbons and Muchnick (Efficient Instruction Scheduling for a Pipelined Architecture, 1986 Compiler Construction Conference, in ACM SIGPLAN Notices Vol. 21, Num. 7).

    This project is logically divided into three phases.

    First, for a given method you must build a control flow graph from the stream of instructions provided by your Alpha code selector. See the description above in the Register Allocation section.

    Second, your instruction scheduler should process one basic block at a time, building a dependency graph. Nodes in the dependency graph correspond to instructions in the basic block. Edges are directed and represent serialization dependencies between instructions. That is, if an edge is drawn from A to B, then A must execute prior to B. For debugging, and grading, purposes you should be capable of displaying the dependency graph for each basic block.

    Third, you should use the dependency graph to schedule the instructions in the basic block using an algorithm based upon the approach of Gibbons and Muchnick. You should insert the .set noreorder directive to keep the DEC assembler from doing further instruction scheduling. Schedule instructions first for "result latency" and second for "multiple instruction issue". See Appendix A Section 2 of the Alpha Architecture Reference Manual for guidelines on scheduling.

    The debugging output should be optional, but I will want to be able to see this output when grading the project. Of course, the ultimate output of the project is the modified output code.

    The primary test data for this project are the Hennessy benchmarks (plus pi.java). You, of course, will also want to perform additional tests. First, be sure your scheduler is generating correct programs. Next, compare the performance of the test programs using your instruction scheduler, using the Tru64 Unix assembler's scheduler, and using no scheduler.

    The Alpha systems include a disassembly tool called "dis". This might be useful for comparing the code sequences produced by your scheduler and by the DEC scheduler.

  4. Garbage Collection.

    Construct a garbage collector for the Java/Alpha system. A good reference for garbage collection is by Wilson, Uniprocessor Garbage Collection Techniques. Also see the Garbage Collection Page.

    You must first study the Hyperion run-time system. (Use the C version, not the HYP-IC version.) What is its support for garbage collection? Then decide upon a garbage collection strategy. Some strategies may require changes to the run-time system.

    Bugs in a garbage collector are notoriously hard to detect, since the garbage collector seems to run asynchronously. Attempt to develop testing strategies and debugging displays that will aid in demonstrating the correctness of your garbage collector. Also, study the performance of your garbage collector. You may need to develop synthetic benchmarks since the Hennessy benchmarks make minimal demands on memory.

  5. Garbage Collection in Parallel, Option I.

    Hyperion is designed for the execution of Java program in parallel, using clusters. Hyperion includes a rudimentary concurrent garbage collector, which is not yet debugged. This project would involve studying this existing collector, debugging it, and evaluating it.

  6. Garbage Collection in Parallel, Option II.

    Design a "state-of-the-art" concurrent garbage collector for Hyperion. This project would first involve a careful review of the current literature on garbage collection. Then prepare a thorough design document for the implementation of a concurrent garbage collector for Hyperion. The design must be complete enough that a programmer could be expected to simply sit down and code, without further reference to the garbage collection literature. Include with this design a discussion of the rationale for the garbage collection techniques chosen. What are their strengths? What are their weaknesses? What were the alternative techniques, and why weren't they chosen?

  7. Java Optimization.

    Design an optimization for the guaranteed-safe removal of array-bounds checks in HYP-IC programs. First, carefully research array-bounds check removal. How can safety be guaranteed? Identify and study other projects where this optimization has been done. Then prepare a thorough design document for the implementation of array-bounds check removal for HYP-IC programs. What supporting analysis is required? What data structures are necessary for representing the program as it is analyzed and transformed? Should the optimization be performed before or after the HYP-IC code is generated? The design must be complete enough that a programmer could be expected to simply sit down and code, without further reference to the optimization literature.

  8. Hyperion Run-Time Library, Option I.

    Implement and perform a preliminary evaluation of an alternative approach for the Hyperion distributed-shared-memory (DSM) subsystem. In particular, modify the Hyperion page-fault based DSM to use the "twin-and-diff" approach to tracking modifications to cached pages. Compare this to the bitmap-based version that is currently used by Hyperion. Do the evaluation using a set of available multithreaded Java programs.

  9. Hyperion Run-Time Library, Option II.

    Implement and perform a preliminary evaluation of an alternative approach for the Hyperion distributed-shared-memory (DSM) subsystem. In particular, modify the Hyperion page-fault based DSM to use write-protection to detect updates to cached pages. Also implement the sending of modifications immediately to the home node. Compare this approach, with and without the immediate sending of modifications, to the bitmap-based version that is currently used by Hyperion. Do the evaluation using a set of available multithreaded Java programs.

  10. Hyperion Run-Time Library, Option III.

    Design and do a preliminary implementation of an object-based, segfault-based, home-based DSM for Hyperion. Design the necessary data structures for tracking the location of objects. Choose a method for tracking modifications to remote objects. If time allows, evaluate your approach by comparing to the page-based DSMs that are currently available.

  11. Hyperion Run-Time Library, Option IV.

    Add support for volatile variables to Hyperion. This may require modifications to both java2c and to the Hyperion run-time library. Be sure to first carefully study the Java requirements for volatile variables. Develop test programs to test your implementation.

  12. Hyperion Run-Time Library, Option V.

    Design an extension of Hyperion to support dynamic class loading. This will require that you investigate thoroughly Java's support for dynamic class loading. Also carefully study Hyperion's support for reflection. And, learn the rudiments of dynamic linking in Unix. Finally, put it all together to write a detailed design specification for the extension.

  13. Hyperion Performance Evaluation.

    Evaluate the Hyperion system on serial benchmarks by comparing Java and C implementations of the Hennessy benchmark programs. Try to identify the sources of any performance differences. This project will most likely require a careful comparison of the assembly language code produced by compiling hand-written C to the assembly language code produced by compiling the C code generated by Hyperion's java2c.

  14. Code Generation and Optimization Tools.

    Investigate the use of the SUIF compiler system to build an efficient HYP-IC to Alpha code generator.

    Optimistically, this will be a straightforward task that simply involves mapping the HYP-IC operations into SUIF operations, since SUIF tools for the Alpha already exist. If this is the case then go ahead and build the HYP-IC to Alpha code generator.

    Pessimistically, the learning curve for using SUIF might be rather steep. Are the SUIF tools too complicated for a novice, such as a CS912 student, to quickly master? Are there other problems inherent in mapping HYP-IC to SUIF? If this is the case, then the project goal is a careful study of SUIF with the project deliverable being a detailed design for using SUIF with HYP-IC.

  15. Peephole Optimization.

    Build a peephole optimizer for HYP-IC. This should optimize such cases as these: addition of zero (remove); branch to branch (replace with a direct branch); and, other forms of "constant folding", such as the load of a constant followed by a test against a constant value (replace test with a direct branch). Either optimize the HYP-IC code or the Alpha code produced by your Alpha code selector. Measure and analyze the effectiveness of your optimizer. Does it improve the performance of the Hennessy benchmarks? Why or why not?

  16. Student-Designed Project.

    Make a suggestion for your own student-designed project. Start an e-mail (or in-person) discussion with me to work out the details. The earlier you do this the better! All projects must have my full approval.


Last modified on August 11, 2000.

Comments and questions should be directed to pjh@cs.unh.edu