An LLVM compiler has three components: the front-end, the middle-layer, and the back-end. The front-end converts any programming language into an intermediate representation (IR). The middle-layer runs a bunch of optimizations on the IR, to make the code more space and time efficient. The back-end converts the IR into assembly language.
In a class at Northwestern called "Code Analysis and Transformation", I built an optimization in the middle-layer of the compiler for a toy language. My optimization removes computational redundancies from the code, making the compiled code run faster. It does so using techniques called reaching definition analysis, constant propagation, constant folding, loop unrolling, and function inlining.
I placed 3rd in the class competition out of 20 teams.
Read more about the class here: https://www.mccormick.northwestern.edu/computer-science/courses/descriptions/323.html.