I'm continuing my work on my C# compiler for my Compilers Class. At the moment I'm nearly finished with the chapters on Compiler Optimizations in my textbook.
For the most part, my textbook didn't have Just-In-Time compilation in mind when it was written and I'm curious about the kinds of static, pre-jit optimizations the C# compiler performs versus what it does during the JIT process?
When I talk to people about compiling against the CLR, I typically hear things like, "Most of the optimizations are done by the JIT".
Are things like loop unrolling, constant folding/propagation, instruction interweaving done pre-Jit by C#'s compiler or handled by the jitter? If they aren't handled by the jitter, then what kind of optimizations does the jitter do that are unique to a just-in-time compiler?