Code optimizer

The code optimizer takes the intermediate representation and tries to reduce redundant lines in it. Consider an example.

a = b + c * d + c * d

Notice how we did not recompute again.

This phase of the compiler is responsible for handling unreachable statement errors.