В теории компиляторов, исключение общих подвыражений (CSE ) - это оптимизация компилятора, которая ищет экземпляры идентичные выражения (т. е. все они вычисляют одно и то же значение) и анализирует, стоит ли заменять их одной переменной, содержащей вычисленное значение.
В следующем коде:
a = b * c + g; d = b * c * e;
, возможно, стоит преобразовать код в:
tmp = b * c; а = tmp + g; d = tmp * e;
, если стоимость сохранения и извлечения tmp
меньше, чем стоимость вычисления b * c
дополнительного времени.
Возможность выполнения CSE основана на доступном анализе выражения (анализ потока данных ). Выражение b * c
доступно в точке p в программе, если:
b * c
до достижения p,b
или c
после оценки, но до p.Анализ затрат / выгод, выполненный оптимизатором, рассчитает, будут ли затраты на сохранить в tmp
меньше стоимости умножения; на практике также имеют значение другие факторы, например, какие значения хранятся в каких регистрах.
Составители компилятора различают два вида CSE:
Оба вида полагаются на анализ потока данных, какие выражения доступны в каких точках программы.
Преимущества выполнения CSE настолько велики, что это широко используемая оптимизация.
В простых случаях, как в примере выше, программисты могут вручную удалить повторяющиеся выражения при написании кода. Самый большой источник CSE - это промежуточные кодовые последовательности, генерируемые компилятором, например, для вычислений индексации массива , в которые разработчик не может вмешаться вручную. В некоторых случаях языковые функции могут создавать множество повторяющихся выражений. Например, C макрос, где расширение макроса может привести к общим подвыражениям, не видимым в исходном исходном коде.
Компиляторы должны быть осторожны в отношении количества временных файлов, созданных для хранения значений. Чрезмерное количество временных значений создает давление на регистры, что может привести к переполнению регистров в памяти, что может занять больше времени, чем просто пересчет арифметического результата, когда это необходимо.