Нумерация значений - Value numbering
Нумерация значений это метод определения, когда два вычисления в программе эквивалентны и устраняют одну из них с сохранением семантики оптимизации.
Нумерация глобальных значений
Нумерация глобальных значений (GVN) - это оптимизация компилятора на основе статическая форма единого назначения (SSA) промежуточное представление. Иногда помогает устранить избыточный код который исключение общего подвыражения (CSE) нет. Однако в то же время CSE может исключить код, которого нет в GVN, поэтому оба они часто встречаются в современных компиляторах. Нумерация глобальных значений отличается от нумерация местного значения в том, что отображения числа-значения сохраняются и через границы базовых блоков, и для вычисления отображений используются различные алгоритмы.
Нумерация глобального значения работает путем присвоения номера значения переменным и выражениям. Одинаковый номер значения присваивается тем переменным и выражениям, которые доказуемо эквивалентны. Например, в следующем коде:
ш: = 3х: = 3у: = х + 4z: = ш + 4
хорошая процедура GVN присвоила бы тот же номер значения ш
и Икс
, и тот же номер значения для y
и z
. Например, карта составило бы оптимальное отображение числа-значения для этого блока. Используя эту информацию, предыдущий фрагмент кода может быть безопасно преобразован в:
w: = 3x: = wy: = w + 4z: = y
В зависимости от кода, следующего за этим фрагментом, копирование распространения может удалить назначения для Икс
и чтобы z
Причина того, что GVN иногда оказывается более мощным, чем CSE, заключается в том, что CSE сопоставляет лексически идентичные выражения, тогда как GVN пытается определить базовую эквивалентность. Например, в коде:
a: = c × de: = cf: = e × d
Без распространения копий CSE будет нет исключить перерасчет, назначенный ж
, но даже плохой алгоритм GVN должен обнаружить и устранить эту избыточность.
Форма SSA требуется для выполнения GVN, чтобы не создавались ложные сопоставления {имя переменной → имя значения}.
Нумерация местных значений
Нумерация местных значений (LVN) - это оптимизация компилятора цель которого - найти несколько экземпляров эквивалентных выражений (то есть выражений, которые дают одинаковый результат) и заменить их первым вхождением. LVN - это локальная оптимизация, что означает, что в отличие от глобальная нумерация значений он работает на одном базовый блок вовремя.
Нумерация местных значений работает путем присвоения уникального номера каждой операции и запоминания этих ассоциаций. Затем просматриваются последующие инструкции, и в случае, если идентичная инструкция уже была зарегистрирована, они заменяются результатом предыдущей инструкции. Например:
a ← 4 a помечено как # 1b ← 5 b помечено как # 2c ← a + bc (# 1 + # 2) помечено как # 3d ← 5 d помечено как # 2, то же самое, что be ← a + de , будучи "# 1 + # 2", помечается как # 3
Присвоение чисел инструкциям сравнение дубликатов превращается в простые целочисленные сравнения. В этом конкретном примере 'c' и 'e' имеют одинаковый номер (# 3), таким образом сигнализируя компилятору, что любые ссылки на e могут быть просто заменены единицами на c.
Трудности и дополнения
Наивная реализация может попытаться выполнить оптимизацию, напрямую используя имена переменных вместо чисел. Однако этот подход не работает, когда значения переменных могут изменяться. Рассмотрим псевдокод:
a ← 1 a помечено как # 1b ← 2 b помечено как # 2c ← a + b c помечено как # 3b ← 3d ← a + b d неправильно помечено как # 3
В этом сценарии 'd' неправильно присвоено число 3, потому что аргументы совпадают с аргументами 'c'. Однако это неверно, потому что «b» изменило значение с 2 на 3, в результате чего фактические результаты отличаются.
Простая реализация может также оказаться неспособной уловить все эквивалентные выражения, даже если они отличаются только порядком их операндов. В следующем примере 'a' и 'b' могут быть присвоены одинаковые номера:
a ← 1 + 2b ← 2 + 1
Эта проблема может быть легко решена либо путем присвоения одного и того же номера обоим случаям (т.е. «a + b» и «b + a» записываются с одним и тем же номером), либо путем сортировки операндов перед проверкой эквивалентов.[1]
Оптимизаторы нумерации локальных значений также могут знать математические тождества. Предполагая, что 'a' - целое число, всем следующим выражениям можно присвоить одно и то же значение:[2]
b ← a + 0c ← a * 1d ← min (a, MAX_INT) e ← max (a, a) f ← a & 0xFF..FF (предполагается, что '&' обозначает побитовая операция )
Смотрите также
Рекомендации
- ^ Купер, Кейт Д.; Торчон, Линда. «Терминология, принципы и проблемы (с примерами из местной нумерации)». elsevier. Получено 15 мая 2017.
- ^ Купер, Кейт Д.; Торчон, Линда. «Локальная оптимизация: нумерация значений» (PDF). Университет Райса. Получено 15 мая 2017.
дальнейшее чтение
- Килдалл, Гэри Арлен (1973). «Единый подход к глобальной оптимизации программ». Материалы 1-го ежегодного симпозиума ACM SIGACT-SIGPLAN по принципам языков программирования. Попл '73: 194–206. Дои:10.1145/512927.512945. HDL:10945/42162. Получено 2006-11-20. [1]
- Альперн, Боуэн, Вегман, Марк Н. и Задек, Ф. Кеннет. «Обнаружение равенства переменных в программах», Запись конференции пятнадцатого ежегодного симпозиума ACM по принципам языков программирования (POPL ), ACM Press, Сан-Диего, Калифорния, США, январь 1988 г., страницы 1–11.
- Л. Тейлор Симпсон, «Устранение избыточности, ориентированной на ценность». Технический отчет 96-308, факультет компьютерных наук, Университет Райса, 1996 г. (авторская докторская диссертация)
- Мучник, Стивен Стэнли (1997). Расширенный дизайн и реализация компилятора. Издательство Morgan Kaufmann. ISBN 978-1-55860-320-2.
- Briggs, P .; Купер, Кейт Д.; Симпсон, Л. Тейлор (1997). «Нумерация значений». Программное обеспечение - практика и опыт. 27 (6): 701–724.