Phoenix Compiler Backend
Compilers and Jitters are one class of application that can be built
with Phoenix. In fact, the functionality of the Phoenix framework is
focused on building tools that require the kinds of analysis and code
generation used for code generation and execution. With the Phoenix toolbox, it is possible to build
compilers, jitters, and ahead-of-time jitters for a variety of hardware
architectures. By choosing and, when appropriate, enhancing the analysis
and code generations of Phoenix, you can implement code generators with
specialized goals, such as support of multi-core processors or support
for specialized domain-specific optimization.

(Click for a larger
image.)
When you think about building a compiler with Phoenix, keep in mind that Phoenix
itself is a code generating tool that can accept any input for which a
reader has been written. Phoenix provides readers for binary code, the CIL used in Microsoft’s CLR, and the output of the Microsoft C++
frontend. You can write your own reader for specialized intermediate
forms and the Phoenix team is in the early stages of defining an AST
format suitable for use with Phoenix.
Using Phoenix for code generation for your own language requires writing
your own scanner and parser (perhaps using tools like lex and yacc) and
creating an intermediate form that can be consumed by Phoenix. From
there the analysis and code generation provided by Phoenix can be used
to target a particular hardware or virtual hardware architecture.
Suitable optimizations and code generation tools can then be selected
and when desired enhanced for the target architecture.

(Click for a larger
image.)
The Microsoft C++ compiler backend (C2.exe) provided with Phoenix
executes a number of analysis and code generation passes. The backend
has a plug-in model to allow substituting or adding privately written
phases that will execute along with the phases run for conventional code
generation.

(Click for a larger
image.)
An example of how to use Phoenix to provide optimization and code
generation for your own language is illustrated with a proposed
implementation of the Tiger language. In this implementation, lex and
yacc implementation of the Tiger language produced a compiler frontend
written in C++. That frontend (Tiger.exe) consumes a tiger source
program (Queens.tig) to produce a Phoenix compatible AST representation
of the Queens.tig program. Phoenix then consumes the AST and performs
conventional analysis and code generation to build an executable version
of the Queens.tig program that can run on the targeted hardware
platform.

(Click for a larger
image.)
For those situations where writing a new or replacement phase of the
compiler backend and integrating it into the Microsoft C++ backend is a
suitable way to solve your problem, the code to build a replacement
phase is fairly simple.
This “minimal plug-in” has all the code required to add a phase (FuncNamesPhase)
to the C2.exe compiler. The phase in this example is a trivial one with
simply displays the name of the function being processed. More complex
phases have full read and write access to the Phoenix intermediate form
and can alter the code generation process as appropriate for the
specific application.

(Click for a larger
image.)
|