The issues for retargetting the compiler are far too numerous to be covered
by this document. What follows is a brief description of each of the seven
phases of the compiler and its MCU dependency.
- Parsing the source and building the annotated parse tree. This phase is
largely MCU independent (except for the language extensions). Syntax &
semantic checks are also done in this phase , along with some initial optimizations
like back patching labels and the pattern matching optimizations like bit-rotation
- The second phase involves generating an intermediate code which can be
easy manipulated during the later phases. This phase is entirely MCU independent.
The intermediate code generation assumes the target machine has unlimited number
of registers, and designates them with the name iTemp. The compiler can be
made to dump a human readable form of the code generated by using the --dumpraw
- This phase does the bulk of the standard optimizations and is also MCU
independent. This phase can be broken down into several sub-phases.
- Break down intermediate code (iCode) into basic blocks.
- Do control flow & data flow analysis on the basic blocks.
- Do local common subexpression elimination, then global subexpression elimination
- dead code elimination
- loop optimizations
- if loop optimizations caused any changes then do 'global subexpression
elimination' and 'dead code elimination' again.
- This phase determines the live-ranges; by live range I mean those iTemp
variables defined by the compiler that still survive after all the optimizations.
Live range analysis is essential for register allocation, since these computation
determines which of these iTemps will be assigned to registers, and for how
- Phase five is register allocation. There are two parts to this process
- The first part I call 'register packing' (for lack of a better term) .
In this case several MCU specific expression folding is done to reduce register
- The second part is more MCU independent and deals with allocating registers
to the remaining live ranges. A lot of MCU specific code does creep into this
phase because of the limited number of index registers available in the 8051.
- The Code generation phase is (unhappily), entirely MCU dependent and very
little (if any at all) of this code can be reused for other MCU. However the
scheme for allocating a homogenized assembler operand for each iCode operand
may be reused.
- As mentioned in the optimization section the peep-hole optimizer is rule
based system, which can reprogrammed for other MCUs.