Нумерация значений (англ. Value Numbering) — один из видов анализа потока данных[en], применяемый оптимизирующим компилятором с целью обнаружения избыточных вычислений в коде (промежуточном представлении) программы. Результатами анализа могут воспользоваться оптимизации: распространение копий[en], удаление частичных избыточностей[en], удаление общих подвыражений[1], оптимизация условий (англ. If Optimization)[2], inline-подстановка[en][3]. Анализ разбивает множество всех рассматриваемых операций, вырабатывающих какой-либо результат (число или предикат), на подмножества операций, в каждом из которых все операции вырабатывают одинаковый результат не зависимо от ввода. Такие подмножества (а так же, иногда, номера этих подмножеств[4]) называют классами конгруэнтности или классами эквивалентности[3]. Классы конгруэнтности пронумерованы, номер класса конгруэнтности называют номером значения. Таким образом, задачу нумерации значений можно сформулировать следующим образом: присвоить уникальный номер каждому значению, вырабатываемому внутри рассматриваемого участка программы[3]. Для осуществления нумерации значений может потребоваться построенный Def-Use-граф или SSA-форма[4]. Нумерация значений может быть локальной (в пределах одного базового блока), глобальной (в пределах CFG-графа одной процедуры) и межпроцедурной[3].

Примеры править

Алгоритмы править

Применение править

Использование результатов нумерации значений в алгоритмах некоторых оптимизаций, связанных с удалением избыточных вычислений, может существенно повысить их эффективность и упростить реализацию[5].

Удаление общих подвыражений править

Оптимизация условий править

 
Простейший пример применения оптимизации условий

Оптимизация условий — удаление избыточных условных вычислений. Управляющий граф может содержать, так называемые, If-узлы — узлы, имеющие по две исходящие дуги, и, соответственно, по набору операций, необходимому для выбора одной из этих дуг. Будем называть такой набор операций условным вычислением. Если в управляющем графе содержатся два If-узла, один из которых доминируется другим (или хотя бы одной исходящей из него дугой), то, при условии совпадения номеров значений результатов их условных вычислений (или при условии, что какое либо значение результата нижнего условного вычисления следует из какого-либо значения результата верхнего условного вычисления), вычисление в нижнем узле можно не повторять. Оптимизация условий удаляет условные вычисления в доминируемом узле и удаляет соответствующую исходящую дугу. Помимо удаления избыточных вычислений, преобразование может сделать некоторые узлы и дуги управляющего графа недостижимыми из корневого узла, то есть обнаружить недостижимый код.

Простейший пример применения оптимизации условий изображён на схеме: если переменные a и b относятся к одному классу конгруэнтности, то из условия a ≥ 7 следует, что b ≥ 7, значит, условие b ≥ 6 всегда выполняется, а условие b < 6 — не может быть выполнено. Операция сравнения и, соответствующая ей, операция перехода в узле 2 являются избыточными. Оптимизация условий удалит избыточные условные вычисления в узле 2 и удалит дугу от узла 2 к узлу 4. В результате, время исполнения программы при a ≥ 7 уменьшилось за счёт удаления операции сравнения, а также уменьшился размер кода.

Inline-подстановка править

Inlining — оптимизация, выполняющая подстановку тела функции вместо операции её вызова (CALL). Целью преобразование является уменьшение количества передач управления, то есть уменьшение количества операций CALL и RETURN, а также более эффективная работа оптимизаций, анализирующих только одну единицу трансляции (а таких большинство). Inline нельзя применять ко всем функциям в программе. Например, если подставить вместо вызова слишком большую функцию, то размер кода может существенно возрасти. В процессе выполнения оптимизации важно найти компромисс между увеличением кода и скоростью его исполнения. Межпроцедурная нумерация значений позволяет уточнить этот анализ, так как, даже если размер подставляемой функции слишком велик, в ней могут содержаться избыточные вычисления, которые, после подстановки и дальнейшего удаления избыточностей, исчезнут. Таким образом, межпроцедурная нумерация значений позволяет нам оперировать не размером подставляемой функции, а увеличением размера кода после подстановки этой функции. Частным случаем этой оптимизации является частичный inline, при котором подставляется только часть вызываемой функции, например, содержащая самые часто выполняемые пути.

Примечания править

  1. Филиппов А. Н. Методы удаления избыточностей на этапе компиляции программ. Автореферат, 2009 (текст)
  2. Степнов Д. В. Оптимизация управляющего графа программ, имеющих избыточные условные вычисления. 2012 (PPT Архивная копия от 18 июля 2014 на Wayback Machine Архивировано)
  3. 1 2 3 4 А. Ю. Дроздов, А. В. Кан. Анализ «Межпроцедурная нумерация значений». В Компьютеры в учебном процессе, 2005, № 5 (текст)
  4. 1 2 Дроздов А. Ю., Новиков С. В., Боханко А. С., Галазин А. Б. Глобальный граф потока данных и его роль в проведении оптимизирующих преобразований программ (текст)
  5. Филиппов А. Н. Метод нумерации значений и использование его результатов при оптимизации программ. В Информационные технологии, 2009, № 4 (текст)