Z:gnu-www-ja-stallman-kth--f993e3-This compiler currently works/en

This compiler currently works by having a parser which turns C code into effectively a syntax tree annotated with C datatype information. Then another pass which looks at that tree and generates code like this [LISP like code]. Then several optimization passes. One to handle things like jumps across jumps, jumps to jumps, jumps to .+1, all of which can be immediately simplified. Then a common subexpression recognizer, then finding basic blocks, and performing dataflow-analysis, so that it can tell for each instruction which values are used in that instruction and never used afterward. And also linking each instruction to the places where the values it uses were generated, so if I have one instruction which generates pseudo register R[28], and then another instruction later which uses R[28] and it's the first place to use R[28], I make the second one point back to the first one, and this pointer is used to control the attempts to combine the instructions. You don't combine adjacent instructions, you combine an instruction that uses a value with the instruction that produced that value. Even if there are other instructions in between, they don't matter for this, you just have to check them to make sure they don't do anything to interfere. Then after the combiner comes the dynamic register allocator, and finally something to convert it into assembly code.