+++ title = "Back End" date = "2020-12-10" author = "Yann Herklotz" tags = [] categories = [] backlinks = ["3a2"] forwardlinks = ["3a4"] zettelid = "3a3" +++ This is where most of the optimisations happen, and where the intermediate CFG language is finally converted to proper assembly. The main optimisations are done in RTL, which is a language that models a CFG and has infinite registers it can choose from, therefore not using a stack. Optimisations such as inlining, constant propagation and dead code elimination are all performed at this level, using Kildall's algorithm to get the necessary analysis to perform these optimisations \[1\]. RTL is then translated to LTL, which is where physical registers are assigned, and where the rest of the variables are put into the stack. At this level, the CFG is also translated into a CFG that uses basic blocks instead of instructions. This is an interesting addition, and I am not sure why that is not a property of RTL, as basic blocks can make some optimisations simpler. Optimisations that would affect basic blocks, such as lazy code motion (LCM) optimisations would be harder if the language contained basic blocks, as these would have to be changed. As these optimisations are performed at the RTL level, it does make sense to have a simpler representation of code at that level and make these transformations simpler.
\[1\] Y. Bertot, B. Grégoire, and X. Leroy, “A structured approach to proving compiler optimizations based on dataflow analysis,” in *Types for proofs and programs*, J.-C. Filliâtre, C. Paulin-Mohring, and B. Werner, Eds., Berlin, Heidelberg: Springer Berlin Heidelberg, 2006, pp. 66–81.