Nissan Wingroad (третье поколение)
- 1 year ago
- 0
- 0
SSA ( англ. Static single assignment form ) — промежуточное представление, используемое компиляторами , в котором каждой переменной значение присваивается лишь единожды. Переменные исходной программы разбиваются на версии, обычно с помощью добавления суффикса, таким образом, что каждое присваивание осуществляется уникальной версии переменной. В SSA-представлении DU-цепи ( англ. def-use ) заданы явно и содержат единственный элемент.
SSA-представление было разработано исследователями IBM Роном Ситроном ( Ron Cytron ), Жаном Феррантом ( Jeanne Ferrante ), Барри Розеном ( Barry Rosen ), ( англ. ) и Кеном Задеком ( Ken Zadeck ) в 1980-е годы.
В компиляторах функциональных языков программирования , таких как Scheme , ML и Haskell , вместо SSA обычно используется CPS -представление ( англ. Continuation-passing style ). Формально эти представления эквивалентны, поэтому оптимизации и трансформации, сформулированные в одном из представлений, могут быть применены и для другого.
Для кода в SSA-форме проще и эффективнее проводить многие виды компиляторной оптимизации . Например, в следующем коде:
y := 1 y := 2 x := y
для человека очевидно, что первое присваивание не нужно, так как значение y, использованное в третьей строчке, соответствует второму присваиванию. Однако для того, чтобы выяснить это, компилятору пришлось бы прибегнуть к анализу достигающих определений . Но с использованием SSA-представления это становится гораздо проще:
y1 := 1 y2 := 2 x1 := y2
SSA делает возможными или существенно упрощает следующие оптимизационные алгоритмы:
Перевод обычного программного кода в SSA-представление достигается путём замены в каждой операции присваивания переменной из левой части на новую переменную. Для каждого использования значения переменной исходное имя заменяется на имя «версии», соответствующей нужному базовому блоку. Рассмотрим следующий граф потока управления :
В соответствии с определением SSA создадим вместо переменной x две новые переменные x 1 и x 2 . Каждой из них значение будет присвоено ровно один раз. Аналогичным образом заменим остальные переменные, после чего получим следующий граф:
Пока остаётся неясным, какое значение y будет использоваться в нижнем блоке. Там имя y может означать как y 1 , так и y 2 . Для того, чтобы разрешить неоднозначности такого рода, в SSA введена специальная Φ-функция. Эта функция создаёт новую версию переменной y, которой будет присвоено значение либо из y 1 , либо из y 2 , в зависимости от того, из какой ветви перешло управление.
При этом использовать Φ-функцию для переменной x не нужно, так как лишь одна версия x (а именно, x 2 ) «достигает» последнего блока.
Φ-функция в действительности не реализована; она представляет собой лишь указание компилятору хранить все переменные, перечисленные в списке её аргументов, в одном и том же месте в памяти (или регистре ).
Более общий вопрос состоит в том, можно ли по заданному графу потока управления понять, где и для каких переменных в SSA-представление нужно вставить Φ-функции? Ответ на этот вопрос можно получить с помощью доминаторов .