Оптимизирующие компиляторы языков высокого уровня нужны по следующим причинам:
1) Языки высокого уровня содержат общие подвыражения, которые программист, не может выделить в отдельную инструкцию, например, здесь индекс умножается на размер элемента массива 3 раза:
> -- Цитата:
> VAR   i: INTEGER;   a: ARRAY 1000 OF INTEGER;BEGIN  ...  a[i] := b[i] + c[i]
Оптимизирующий компилятор может выделить такие общие инструкции автоматически.
2) Время_работы_программы = количество_инструкций * средняя_длительность_инструкции_в_тактах * длительность_одного_такта
Производители процессоров для повышения их производельности стараются наращивать частоту процессора и уменьшать количество тактов, которое требуется на одну инструкцию.
Вообще, обработка инстукции проходит несколько фаз:
- выборка инструкции
- декодирование
- выполнение
- завершение
- запись результата
Если, допустим, каждая из фаз занимает по одному такту, то среднее время выполнения одной инструкции было бы 5. Затем придумали конвейер, который позволяет выполнять, допустим, 5 инструкций на 5 фазах и в этом случае среднее время выполнения сокращается до 1 такта на инструкцию. Но при этом возможны коллизии и простои конвейера, если операндами следующей инструкции является результат предыдущей инструкции, который еще не записан в регистр.
Вот для того, чтобы уменьшить количество коллизий и простоев конвейера, оптимизирующие компиляторы переупорядочивают инструкции, при этом корректность программы должна сохраняться, так как оптимизирующий компилятор должен переупорядочивать инструкции таким образом, чтобы это не повлияло на окончательный результат.

P.S. Да, оптимизация не увеличивает производительность на порядок, но в зависимости от задачи может уменьшать время выполнения в 2-3 раза.