"Филипп Н.Хислей. Генерация высококачественного кода для программ, написанных на СИ " - читать интересную книгу автора

b = 0;
a = b;
первый оператор есть лишнее присваивание, и может быть удален
безопасно. Лишние присваивания могут возникать непреднамеренно, когда
промежуток жизни переменной велик и между вхождениями переменной имеется
более-менее длинный код. Лишние присваивания могут быть также результатом
предыдущих проходов оптимизации.
Цель "распределения переменных по регистрам" состоит в попытке
обеспечить оптимальное назначение регистров путем сохранения часто
используемых переменных в регистрах так долго, как это возможно, для того,
чтобы исключить более медленный доступ к памяти. Количество регистров,
доступных для использования, зависит от архитектуры процессора. Семейство
микропроцессоров Intel 80x86 резервирует много регистров для специального
использования и имеет несколько универсальных регистров. В помощь
распределению переменных по регистрам язык Си предоставляет спецификатор
класса регистровой памяти, который дает возможность программисту указывать,
какие переменные должны располагаться в регистрах.
При назначении переменных регистрам компилятор принимает во внимание не
только какие переменные нужно выделить, но также и регистры, которым они
назначаются. Выбор переменных зависит от частоты их использования,
промежутков жизни текущих регистровых переменных (которые определяются при
анализе потоков данных) и количества доступных регистров. В зависимости от
степени выполняемой компилятором оптимизации промежуток жизни переменной
может определяться внутри единственного оператора, внутри базового блока или
перекрывать несколько базовых блоков. Переменная сохраняется в регистре
только если она будет снова использоваться. Если на переменную в дальнейшем
не будет ссылок, то она сохраняется в оперативной памяти, освобождая регистр
для другой переменной.
Поскольку оптимизирующему компилятору известен промежуток жизни
переменной, он не будет намеренно генерировать "лишние операции сохранения и
загрузки" (регистров). Лишние операции сохранения удаляются посредством
удаления излишних присваиваний; лишние операции загрузки опускаются с
помощью усовершенствованного распределения переменных по регистрам. Имея
текст:
a = i + 2;
b = a + 3;
компилятор без возможностей оптимизации может сгенерировать следующий
код:
mov AX,i
add AX,2
mov a,AX
mov AX,a
add AX,3
mov b,AX
тогда как оптимизирующий компилятор может использовать механизм
размещения переменных в регистрах для удаления лишней четвертой инструкции
(mov AX,a).
Время, проводимое в циклах, может считаться основной частью всего
времени выполнения программы. Наиболее важным в оптимизации циклов является
минимизация временных циклов микропроцессора, требуемых для одной итерации