Распределение регистров может происходить по базовому блоку ( локальное распределение регистров ), по всей функции/ процедуре ( глобальное распределение регистров ) или через границы функций, пройденные через граф вызовов ( межпроцедурное распределение регистров ). При выполнении для каждой функции/процедуры соглашение о вызовах может потребовать вставки сохранения/восстановления вокруг каждого места вызова .
Контекст
Принцип
Во многих языках программирования программист может использовать любое количество переменных . Компьютер может быстро считывать и записывать регистры в ЦП , поэтому компьютерная программа работает быстрее, когда больше переменных может быть в регистрах ЦП. [1] Кроме того, иногда код, обращающийся к регистрам, более компактен, поэтому код меньше и может быть извлечен быстрее, если он использует регистры, а не память. Однако количество регистров ограничено. Поэтому, когда компилятор транслирует код на машинный язык, он должен решить, как распределить переменные по ограниченному количеству регистров в ЦП. [2] [3]
Не все переменные используются (или «живут») одновременно, поэтому в течение жизненного цикла программы данный регистр может использоваться для хранения разных переменных. Однако две переменные, используемые одновременно, не могут быть назначены одному регистру без повреждения одной из переменных. Если регистров недостаточно для хранения всех переменных, некоторые переменные могут быть перемещены в ОЗУ и из него . Этот процесс называется «выгрузкой» регистров. [4] В течение жизненного цикла программы переменная может быть как выгружена, так и сохранена в регистрах: эта переменная затем считается «разделенной». [5] Доступ к ОЗУ значительно медленнее, чем доступ к регистрам [6], и поэтому скомпилированная программа работает медленнее. Поэтому оптимизирующий компилятор стремится назначить как можно больше переменных регистрам. Высокое « давление регистра » — это технический термин, который означает, что требуется больше выгрузок и перезагрузок; Браун и др. определяют его как «количество одновременно живых переменных в инструкции». [7]
Кроме того, некоторые компьютерные конструкции кэшируют часто используемые регистры. Таким образом, программы можно дополнительно оптимизировать, назначая один и тот же регистр источнику и месту назначения инструкции, moveкогда это возможно. Это особенно важно, если компилятор использует промежуточное представление , такое как статическая форма с одним присваиванием (SSA). В частности, когда SSA не полностью оптимизирована, она может искусственно генерировать дополнительные moveинструкции.
Компоненты распределения регистров
Таким образом, распределение регистров заключается в выборе места хранения переменных во время выполнения, т. е. внутри или вне регистров. Если переменная должна храниться в регистрах, то распределитель должен определить, в каком регистре(ах) эта переменная будет храниться. В конечном итоге, еще одной проблемой является определение продолжительности, в течение которой переменная должна оставаться в одном и том же месте.
Регистровый распределитель, не обращая внимания на выбранную стратегию распределения, может полагаться на набор основных действий для решения этих проблем. Эти действия могут быть объединены в несколько различных категорий: [8]
Переместить вставку
Это действие заключается в увеличении количества инструкций перемещения между регистрами, т. е. в том, чтобы переменная жила в разных регистрах в течение своей жизни, а не в одном. Это происходит в подходе с разделением живого диапазона.
Разлив
Это действие заключается в сохранении переменной в памяти вместо регистров. [9]
Назначение
Это действие заключается в присвоении регистра переменной. [10]
Слияние
Это действие заключается в ограничении количества перемещений между регистрами, тем самым ограничивая общее количество инструкций. Например, путем идентификации переменной в реальном времени между различными методами и сохранения ее в одном регистре в течение всего срока ее службы. [9]
Многие подходы к распределению регистров оптимизируются для одной или нескольких конкретных категорий действий.
Распространенные проблемы, возникающие при распределении регистров
Распределение регистров вызывает несколько проблем, которые можно решить (или избежать) с помощью различных подходов к распределению регистров. Три наиболее распространенных проблемы определяются следующим образом:
Алиасинг
В некоторых архитектурах присвоение значения одному регистру может повлиять на значение другого: это называется псевдонимизацией. Например, архитектура x86 имеет четыре 32-битных регистра общего назначения, которые также могут использоваться как 16-битные или 8-битные регистры. [11] В этом случае присвоение 32-битного значения регистру eax повлияет на значение регистра al.
Предварительная окраска
Эта проблема представляет собой действие, направленное на принудительное назначение некоторых переменных определенным регистрам. Например, в соглашениях о вызовах PowerPC параметры обычно передаются в R3-R10, а возвращаемое значение передается в R3. [12]
NP-задача
Чайтин и др. показали, что распределение регистров является NP-полной задачей. Они свели задачу раскраски графа к задаче распределения регистров, показав, что для произвольного графа можно построить программу так, что распределение регистров для программы (с регистрами, представляющими узлы, и машинными регистрами, представляющими доступные цвета) будет раскраской для исходного графа. Поскольку раскраска графа является NP-сложной задачей, а распределение регистров находится в NP, это доказывает NP-полноту задачи. [13]
Методы распределения регистров
Распределение регистров может происходить по базовому блоку кода: это называется «локальным» и впервые было упомянуто Хорвицем и др. [14] Поскольку базовые блоки не содержат ветвей, процесс распределения считается быстрым, поскольку управление точками слияния графа потока управления при распределении регистров оказывается [ необходимо разъяснение ] трудоемкой операцией. [15] Однако считается, что этот подход не создает такой же оптимизированный код, как «глобальный» подход, который работает по всей единице компиляции (например, методу или процедуре). [16]
Распределение раскраски графа
Распределение раскраски графа является преобладающим подходом к решению распределения регистров. [17] [18] Впервые он был предложен Чайтином и др. [4]
В этом подходе узлы в графе представляют собой живые диапазоны ( переменные , временные , виртуальные/символические регистры), которые являются кандидатами для распределения регистров. Ребра соединяют живые диапазоны, которые мешают, т. е. живые диапазоны, которые одновременно активны по крайней мере в одной точке программы. Затем распределение регистров сводится к задаче раскраски графа , в которой цвета (регистры) назначаются узлам таким образом, что два узла, соединенных ребром, не получают один и тот же цвет. [19]
Используя анализ живучести , можно построить интерференционный граф. Интерференционный граф, который является неориентированным графом , где узлы являются переменными программы, используется для моделирования того, какие переменные не могут быть выделены в один и тот же регистр. [20]
Принцип
Основные фазы в распределителе регистров раскраски графа в стиле Чайтина: [18]
Перенумеровать : обнаружить информацию о текущем диапазоне в исходной программе.
Построить : построить график интерференции.
Объединить : объединить текущие диапазоны немешающих переменных, связанных инструкциями копирования.
Стоимость сброса : вычислить стоимость сброса каждой переменной. Это оценивает влияние отображения переменной в памяти на скорость конечной программы.
Упростить : построить порядок узлов в графе выводов.
Код сброса : вставка инструкций сброса, т.е. загрузка и сохранение для коммутации значений между регистрами и памятью.
Выберите : назначить регистр каждой переменной.
Недостатки и дальнейшие улучшения
Распределение раскраски графа имеет три основных недостатка. Во-первых, оно опирается на раскраску графа, которая является NP-полной задачей , для решения того, какие переменные будут сброшены. Нахождение минимальной раскраски графа действительно является NP-полной задачей. [21] Во-вторых, если не используется разбиение в реальном времени, вытесненные переменные сбрасываются везде: инструкции сохранения вставляются как можно раньше, т. е. сразу после определения переменных; инструкции загрузки соответственно вставляются поздно, непосредственно перед использованием переменной. В-третьих, переменная, которая не сбрасывается, хранится в том же регистре в течение всего своего срока службы. [22]
С другой стороны, одно имя регистра может появляться в нескольких классах регистров, где класс представляет собой набор имен регистров, которые взаимозаменяемы в определенной роли. Затем, несколько имен регистров могут быть псевдонимами для одного аппаратного регистра. [23]
Наконец, раскраска графа является агрессивной техникой выделения регистров, но является вычислительно дорогой из-за использования графа помех, который может иметь наихудший размер, квадратичный по числу активных диапазонов. [24]
Традиционная формулировка выделения регистров раскраски графа неявно предполагает один банк неперекрывающихся регистров общего назначения и не обрабатывает нерегулярные архитектурные особенности, такие как перекрывающиеся пары регистров, регистры специального назначения и несколько банков регистров. [25]
Одно из последних улучшений подхода к раскраске графов в стиле Чайтина было найдено Бриггсом и др.: оно называется консервативным объединением. Это улучшение добавляет критерий для принятия решения о том, когда два живых диапазона могут быть объединены. В основном, в дополнение к требованиям невмешательства, две переменные могут быть объединены только в том случае, если их объединение не приведет к дальнейшему разливу. Бриггс и др. вводят второе улучшение в работы Чайтина, которое представляет собой смещенную раскраску. Смещенная раскраска пытается назначить тот же цвет в раскраске графа живым диапазонам, которые связаны с копированием. [18]
Линейное сканирование
Линейное сканирование — еще один подход к распределению глобальных регистров. Впервые он был предложен Полетто и др. в 1999 году. [26] В этом подходе код не превращается в график. Вместо этого все переменные линейно сканируются для определения их диапазона значений, представленного в виде интервала. После того, как диапазоны значений всех переменных определены, интервалы обходят в хронологическом порядке. Хотя этот обход может помочь идентифицировать переменные, диапазоны значений которых мешают друг другу, граф помех не строится, и переменные распределяются жадным образом. [24]
Мотивацией для этого подхода является скорость; не с точки зрения времени выполнения сгенерированного кода, а с точки зрения времени, затраченного на генерацию кода. Обычно стандартные подходы к раскраске графов производят качественный код, но имеют значительные накладные расходы , [27] [28] используемый алгоритм раскраски графов имеет квадратичную стоимость. [29] Благодаря этой особенности, линейное сканирование является подходом, который в настоящее время используется в нескольких JIT-компиляторах, таких как клиентский компилятор Hotspot , V8 , Jikes RVM , [5] и Android Runtime (ART). [30] Серверный компилятор Hotspot использует раскраску графов для своего превосходного кода. [31]
Псевдокод
Это описывает алгоритм, впервые предложенный Полетто и др. [32] , где:
R — количество доступных регистров.
активным является список, отсортированный в порядке возрастания конечной точки, живых интервалов, перекрывающих текущую точку и помещенных в регистры.
LinearScanRegisterAllocation активный ← {} для каждого живого интервала i , в порядке возрастания начальной точки, выполните ИстекаютСтарыеИнтервалы(i) если длина(активная) = R тогда SpillAtInterval(i) еще register[i] ← регистр удален из пула свободных регистров добавить i к активному, отсортировать по возрастанию конечной точкиExpireOldIntervals(i) для каждого интервала j в active, в порядке возрастания конечной точки, выполнить if endpoint[j] ≥ startpoint[i], затем вернуть remove j из active добавить регистр[j] в пул свободных регистровSpillAtInterval(i) разлив ← последний интервал в активном если конечная точка[spill] > конечная точка[i] , то регистр[i] ← регистр[пролив] местоположение[spill] ← новое местоположение стека удалить разлив из активного добавить i к активному, отсортировать по возрастанию конечной точки иначе location[i] ← новое местоположение стека
Недостатки и дальнейшие улучшения
Однако линейное сканирование имеет два основных недостатка. Во-первых, из-за своей жадности оно не учитывает дыры в жизни, то есть «диапазоны, где значение переменной не нужно». [33] [34] Кроме того, слитая переменная останется слитой на протяжении всей своей жизни.
Многие другие исследовательские работы продолжили алгоритм линейного сканирования Полетто. Например, Трауб и др. предложили алгоритм, называемый second-chance binpacking, нацеленный на генерацию кода лучшего качества. [35] [36] В этом подходе пролитые переменные получают возможность быть сохраненными позже в регистре с использованием эвристики, отличной от той, которая используется в стандартном алгоритме линейного сканирования. Вместо использования живых интервалов алгоритм полагается на живые диапазоны, что означает, что если диапазон необходимо пролить, нет необходимости проливать все другие диапазоны, соответствующие этой переменной.
Линейное распределение сканирования также было адаптировано для использования преимуществ формы SSA : свойства этого промежуточного представления упрощают алгоритм распределения и позволяют напрямую вычислять дыры в сроках службы. [37] Во-первых, сокращается время, затрачиваемое на анализ графа потока данных, направленное на построение интервалов срока службы, а именно потому, что переменные уникальны. [38] Следовательно, оно создает более короткие интервалы времени, поскольку каждое новое назначение соответствует новому интервалу времени. [39] [40] Чтобы избежать интервалов моделирования и дыр в сроках службы, Роджерс продемонстрировал упрощение, называемое наборами будущих активных устройств, которое успешно удалило интервалы для 80% инструкций. [41]
Рематериализация
Слияние
В контексте распределения регистров объединение — это действие по слиянию операций перемещения переменных в переменные путем распределения этих двух переменных в одном месте. Операция объединения происходит после построения интерференционного графа. После объединения двух узлов они должны получить одинаковый цвет и быть распределены в один и тот же регистр, как только операция копирования станет ненужной. [42]
Объединение может иметь как положительное, так и отрицательное влияние на раскрашиваемость графа интерференции. [9] Например, одно отрицательное влияние, которое объединение может оказать на раскрашиваемость вывода графа, — это когда два узла объединяются, так как результирующий узел будет иметь объединение ребер объединяемых узлов. [9]
Положительное влияние объединения на раскрашиваемость графа вывода заключается, например, в том, что когда узел мешает обоим объединяемым узлам, степень узла уменьшается на единицу, что приводит к улучшению общей раскрашиваемости графа интерференции. [43]
Существует несколько эвристик объединения: [44]
Агрессивное слияние
Впервые он был представлен оригинальным распределителем регистров Чайтина. Эта эвристика направлена на объединение любых не мешающих, связанных с копированием узлов. [45] С точки зрения устранения копирования эта эвристика дает наилучшие результаты. [46] С другой стороны, агрессивное объединение может повлиять на окрашиваемость графа вывода. [43]
Консервативное объединение
в основном он использует ту же эвристику, что и агрессивное объединение, но он объединяет ходы тогда и только тогда, когда это не ставит под угрозу окрашиваемость графа интерференции. [47]
Итеративное объединение
он удаляет один конкретный ход за раз, сохраняя при этом возможность раскрашивания графа. [48]
Оптимистичное слияние
он основан на агрессивном объединении, но если раскрашиваемость графа вывода нарушена, то он отказывается от минимально возможного количества ходов. [49]
Смешанные подходы
Гибридное распределение
Некоторые другие подходы к распределению регистров не ограничиваются одной техникой для оптимизации использования регистра. Например, Кавазос и др. предложили решение, в котором можно использовать как алгоритмы линейного сканирования, так и алгоритмы раскраски графа. [50] В этом подходе выбор между одним или другим решением определяется динамически: сначала алгоритм машинного обучения используется «офлайн», то есть не во время выполнения, для построения эвристической функции, которая определяет, какой алгоритм распределения необходимо использовать. Затем эвристическая функция используется во время выполнения; в свете поведения кода распределитель может выбрать один из двух доступных алгоритмов. [51]
Распределение регистров трассировки — это недавний подход, разработанный Эйслом и др. [3] [5] Этот метод обрабатывает распределение локально: он полагается на динамические данные профилирования для определения того, какие ветви будут наиболее часто использоваться в заданном графе потока управления. Затем он выводит набор «трасс» (т. е. сегментов кода), в которых точка слияния игнорируется в пользу наиболее используемой ветви. Затем каждая трасса независимо обрабатывается распределителем. Этот подход можно считать гибридным, поскольку можно использовать различные алгоритмы распределения регистров между различными трассами. [52]
Раздельное распределение
Распределение разделений — это еще один метод распределения регистров, который объединяет различные подходы, обычно рассматриваемые как противоположные. Например, метод гибридного распределения можно считать разделенным, поскольку первый этап эвристического построения выполняется в автономном режиме, а эвристическое использование выполняется в режиме онлайн. [24] Таким же образом, Б. Диуф и др. предложили метод распределения, основанный как на автономном, так и на онлайн-поведении, а именно на статической и динамической компиляции. [53] [54] На этапе офлайн сначала собирается оптимальный набор слива с использованием целочисленного линейного программирования . Затем аннотируются живые диапазоны с использованием compressAnnotationалгоритма, который опирается на ранее определенный оптимальный набор слива. Распределение регистров выполняется впоследствии на этапе онлайн на основе данных, собранных на этапе офлайн. [55]
В 2007 году Буше и др. также предложили разделить распределение регистров на разные этапы, посвятив один этап разливу, а другой – окрашиванию и объединению. [56]
Сравнение различных методов
Несколько метрик использовались для оценки производительности одного метода распределения регистров по сравнению с другим. Распределение регистров обычно имеет дело с компромиссом между качеством кода, т. е. кодом, который выполняется быстро, и накладными расходами анализа, т. е. временем, потраченным на определение анализа исходного кода для генерации кода с оптимизированным распределением регистров. С этой точки зрения, время выполнения сгенерированного кода и время, потраченное на анализ жизнеспособности, являются соответствующими метриками для сравнения различных методов. [57]
После выбора соответствующих метрик код, к которому будут применяться метрики, должен быть доступен и соответствовать проблеме, либо отражая поведение реального приложения, либо будучи соответствующим конкретной проблеме, которую алгоритм хочет решить. В более поздних статьях о распределении регистров в частности используется набор тестов Dacapo. [58]
Смотрите также
Число Стралера , минимальное количество регистров, необходимое для оценки дерева выражений. [59]
Алгоритм Сети–Ульмана — алгоритм, обеспечивающий наиболее эффективное распределение регистров для вычисления одного выражения, когда количество регистров, необходимых для вычисления выражения, превышает количество доступных регистров.
Ссылки
^ Дитцель и Маклеллан 1982, с. 48.
^ Рунесон и Нистрем 2003, стр. 242.
^ аб Эйсл и др. 2016, с. 14:1.
^ аб Чайтин и др. 1981, с. 47.
^ abc Eisl et al. 2016, стр. 1.
^ "Сравнительные показатели задержки в компьютере/сети". blog.morizyun.com. 6 января 2018 г. Получено 08.01.2019 г.
^ Браун и Хак 2009, стр. 174.
^ Коес и Гольдштейн 2009, с. 21.
^ abcd Bouchez, Darte & Rastello 2007b, стр. 103.
^ Коломбет, Бранднер и Дарте 2011, с. 26.
^ «Руководство разработчика программного обеспечения для архитектур Intel® 64 и IA-32, раздел 3.4.1» (PDF) . Intel. Май 2019 г. Архивировано из оригинала (PDF) 25.05.2019.
^ «Соглашения о вызове функций 32-битной PowerPC».
^ Бушез, Дарте и Растелло 2006, стр. 4.
^ Хорвиц и др. 1966, стр. 43.
^ Фарах и Либераторе 1998, с. 566.
^ Эйсл и др. 2017, стр. 92.
^ Эйсль, Леопольдзедер и Мессенбёк 2018, стр. 1.
^ abc Бриггс, Купер и Торзон 1992, стр. 316.
^ Полетто и Саркар 1999, с. 896.
^ Рунесон и Нистрем 2003, стр. 241.
↑ Книга 1975, стр. 618–619.
^ Коломбет, Бранднер и Дарте 2011, с. 1.
^ Смит, Рэмси и Холлоуэй 2004, стр. 277.
^ abc Кавазос, Мосс и О'Бойл 2006, стр. 124.
^ Рунесон и Нистрем 2003, стр. 240.
^ Полетто и Саркар 1999, с. 895.
^ Полетто и Саркар 1999, с. 902.
^ Виммер и Мёссенбёк 2005, стр. 132.
^ Йоханссон и Сагонас 2002, с. 102.
^ Эволюция ИСКУССТВА - Google I/O 2016. Google . 25 мая 2016 г. Событие происходит в 3:47.
^ Палечны, Вик и Клик 2001, стр. 1.
^ Полетто и Саркар 1999, с. 899.
^ Эйсл и др. 2016, стр. 2.
^ Трауб, Холлоуэй и Смит 1998, стр. 143.
^ Трауб, Холлоуэй и Смит 1998, стр. 141.
^ Полетто и Саркар 1999, с. 897.
^ Виммер и Франц 2010, стр. 170.
^ Мёссенбёк и Пфайффер 2002, стр. 234.
^ Мёссенбёк и Пфайффер 2002, стр. 233.
^ Мёссенбёк и Пфайффер 2002, стр. 229.
^ Роджерс 2020.
^ Чайтин 1982, стр. 90.
^ ab Ahn & Paek 2009, стр. 7.
↑ Парк и Мун 2004, стр. 736.
^ Чайтин 1982, стр. 99.
↑ Парк и Мун 2004, стр. 738.
^ Бриггс, Купер и Торзон 1994, стр. 433.
^ Джордж и Аппель 1996, стр. 212.
↑ Парк и Мун 2004, стр. 741.
^ Эйсл и др. 2017, стр. 11.
^ Кавазос, Мосс и О'Бойл 2006, с. 124-127.
^ Эйсл и др. 2016, стр. 4.
^ Диуф и др. 2010, стр. 66.
^ Коэн и Рохоу 2010, стр. 1.
^ Диуф и др. 2010, стр. 72.
^ Бушез, Дарте и Растелло 2007a, с. 1.
^ Полетто и Саркар 1999, с. 901-910.
^ Блэкберн и др. 2006, стр. 169.
^ Флажоле, Рауль и Вийемен 1979.
Источники
Ahn, Minwook; Paek, Yunheung (2009). «Методы объединения регистров для гетерогенной архитектуры регистров с отсеиванием копий». ACM Transactions on Embedded Computing Systems . 8 (2): 1–37. CiteSeerX 10.1.1.615.5767 . doi :10.1145/1457255.1457263. ISSN 1539-9087. S2CID 14143277.
Ахо, Альфред В.; Лам, Моника С.; Сетхи, Рави; Ульман, Джеффри Д. (2006). Составители: принципы, методы и инструменты (второе издание). Addison-Wesley Longman Publishing Co., Inc. ISBN 978-0321486813.
Appel, Andrew W.; George, Lal (2001). "Оптимальное разбиение для машин CISC с небольшим количеством регистров". Труды конференции ACM SIGPLAN 2001 по проектированию и реализации языков программирования - PLDI '01 . стр. 243–253. CiteSeerX 10.1.1.37.8978 . doi :10.1145/378795.378854. ISBN 978-1581134148. S2CID 1380545.
Barik, Rajkishore; Grothoff, Christian; Gupta, Rahul; Pandit, Vinayaka; Udupa, Raghavendra (2007). "Optimal Bitwise Register Allocation Using Integer Linear Programming". Языки и компиляторы для параллельных вычислений . Конспект лекций по информатике. Том 4382. С. 267–282. CiteSeerX 10.1.1.75.6911 . doi :10.1007/978-3-540-72521-3_20. ISBN 978-3-540-72520-6.
Бергнер, Питер; Даль, Питер; Энгебретсен, Дэвид; О'Киф, Мэтью (1997). "Минимизация кода утечки посредством утечки интерференционной области". Труды конференции ACM SIGPLAN 1997 года по проектированию и реализации языков программирования - PLDI '97 . стр. 287–295. doi :10.1145/258915.258941. ISBN 978-0897919074. S2CID 16952747.
Blackburn, Stephen M.; Guyer, Samuel Z.; Hirzel, Martin; Hosking, Anthony; Jump, Maria; Lee, Han; Eliot, J.; Moss, B.; Phansalkar, Aashish; Stefanović, Darko; VanDrunen, Thomas; Garner, Robin; von Dincklage, Daniel; Wiedermann, Ben; Hoffmann, Chris; Khang, Asjad M.; McKinley, Kathryn S.; Bentzur, Rotem; Diwan, Amer; Feinberg, Daniel; Frampton, Daniel (2006). "The DaCapo benchmarks". Труды 21-й ежегодной конференции ACM SIGPLAN по системам, языкам и приложениям объектно-ориентированного программирования - OOPSLA '06 . стр. 169. doi :10.1145/1167473.1167488. hdl :1885/33723. ISBN 978-1595933485. S2CID 9255051.
Книга, Рональд В. (декабрь 1975 г.). "Карп Ричард М.. Сводимость среди комбинаторных задач. Сложность компьютерных вычислений, Труды симпозиума по сложности компьютерных вычислений, состоявшегося 20-22 марта 1972 г. в IBM Thomas J. Watson Center, Yorktown Heights, Нью-Йорк, под редакцией Миллера Рэймонда Э. и Тэтчера Джеймса У., Plenum Press, Нью-Йорк и Лондон, 1972 г., стр. 85–103". Журнал символической логики . 40 (4): 618–619. doi :10.2307/2271828. ISSN 0022-4812. JSTOR 2271828.
Буше, Флоран; Дарте, Ален; Растелло, Фабрис (2006). «Распределение регистров: что на самом деле доказывает доказательство NP-полноты Чайтина и др.? Или пересмотр распределения регистров: почему и как». Распределение регистров: что на самом деле доказывает доказательство NP-полноты Чайтина и др.? . Lecture Notes in Computer Science. Vol. 4382. pp. 2–14. doi :10.1007/978-3-540-72521-3_21. ISBN 978-3-540-72520-6.
Буше, Флоран; Дарте, Ален; Растелло, Фабрис (2007a). «О сложности объединения регистров». Международный симпозиум по генерации и оптимизации кода (CGO'07) . стр. 102–114. CiteSeerX 10.1.1.101.6801 . doi :10.1109/CGO.2007.26. ISBN 978-0-7695-2764-2. S2CID 7683867.
Буше, Флоран; Дарте, Ален; Растелло, Фабрис (2007b). «О сложности разлива повсеместно по форме ССА». Уведомления ACM SIGPLAN . 42 (7): 103–114. arXiv : 0710.3642 . дои : 10.1145/1273444.1254782. ISSN 0362-1340.
Браун, Маттиас; Хак, Себастьян (2009). «Регистровое разбиение и разделение в реальном времени для программ в форме SSA». Конструкция компилятора . Конспект лекций по информатике. Том 5501. С. 174–189. CiteSeerX 10.1.1.219.5318 . doi :10.1007/978-3-642-00722-4_13. ISBN 978-3-642-00721-7. ISSN 0302-9743.
Бриггс, Престон; Купер, Кит Д.; Торцон, Линда (1994). «Улучшения в распределении регистров для раскраски графов». Труды ACM по языкам программирования и системам . 16 (3): 428–455. CiteSeerX 10.1.1.23.253 . doi :10.1145/177492.177575. ISSN 0164-0925. S2CID 6571479.
Кавазос, Джон; Мосс, Дж. Элиот Б.; О'Бойл, Майкл Ф.П. (2006). «Гибридные оптимизации: какой алгоритм оптимизации использовать?». Конструкция компилятора . Конспект лекций по информатике. Том 3923. С. 124–138. doi :10.1007/11688839_12. ISBN 978-3-540-33050-9. ISSN 0302-9743.
Чайтин, Грегори Дж.; Аусландер, Марк А.; Чандра, Ашок К.; Кок, Джон; Хопкинс, Мартин Э.; Маркштейн, Питер В. (1981). «Распределение регистров с помощью раскраски». Computer Languages . 6 (1): 47–57. doi :10.1016/0096-0551(81)90048-5. ISSN 0096-0551.
Чайтин, Г. Дж. (1982). "Распределение регистров и сброс с помощью раскраски графов". Труды симпозиума SIGPLAN 1982 года по построению компиляторов - SIGPLAN '82 . стр. 98–101. doi :10.1145/800230.806984. ISBN 978-0897910743. S2CID 16872867.
Chen, Wei-Yu; Lueh, Guei-Yuan; Ashar, Pratik; Chen, Kaiyu; Cheng, Buqi (2018). "Распределение регистров для графики процессоров Intel". Труды Международного симпозиума по генерации и оптимизации кода 2018 года - CGO 2018. стр. 352–364. doi :10.1145/3168806. ISBN 9781450356176. S2CID 3367270.
Cohen, Albert; Rohou, Erven (2010). "Виртуализация процессора и раздельная компиляция для гетерогенных многоядерных встраиваемых систем". Труды 47-й конференции по автоматизации проектирования - DAC '10 . стр. 102. CiteSeerX 10.1.1.470.9701 . doi :10.1145/1837274.1837303. ISBN 9781450300025. S2CID 14314078.
Colombet, Quentin; Brandner, Florian; Darte, Alain (2011). "Изучение оптимального проливания в свете SSA". Труды 14-й международной конференции по компиляторам, архитектурам и синтезу для встраиваемых систем - CASES '11 . стр. 25. doi :10.1145/2038698.2038706. ISBN 9781450307130. S2CID 8296742.
Diouf, Boubacar; Cohen, Albert; Rastello, Fabrice; Cavazos, John (2010). «Разделение регистров: линейная сложность без ухудшения производительности». Высокопроизводительные встраиваемые архитектуры и компиляторы . Конспект лекций по информатике. Том 5952. С. 66–80. CiteSeerX 10.1.1.229.3988 . doi :10.1007/978-3-642-11515-8_7. ISBN 978-3-642-11514-1. ISSN 0302-9743.
Ditzel, David R.; McLellan, HR (1982). "Распределение регистров бесплатно". Труды первого международного симпозиума по архитектурной поддержке языков программирования и операционных систем - ASPLOS-I . стр. 48–56. doi :10.1145/800050.801825. ISBN 978-0897910668. S2CID 2812379.
Айсл, Йозеф; Гриммер, Маттиас; Саймон, Дуг; Вюртингер, Томас; Мёссенбёк, Ханспетер (2016). «Распределение регистров на основе трассировки в JIT-компиляторе». Труды 13-й Международной конференции по принципам и практикам программирования на платформе Java: виртуальные машины, языки и инструменты — PPPJ '16. стр. 1–11. doi :10.1145/2972206.2972211. ISBN 9781450341356. S2CID 31845919.
Eisl, Josef; Marr, Stefan; Würthinger, Thomas; Mössenböck, Hanspeter (2017). "Trace Register Allocation Policies" (PDF) . Труды 14-й Международной конференции по управляемым языкам и средам выполнения - Man Lang 2017. стр. 92–104. doi :10.1145/3132190.3132209. ISBN 9781450353403. S2CID 1195601.
Eisl, Josef; Leopoldseder, David; Mössenböck, Hanspeter (2018). «Параллельное распределение регистров трассировки». Труды 15-й Международной конференции по управляемым языкам и средам выполнения — Man Lang '18. стр. 1–7. doi :10.1145/3237009.3237010. ISBN 9781450364249. S2CID 52137887.
Koes, David Ryan; Goldstein, Seth Copen (2009). «Register Allocation Deconstructed». Написано в Ницце, Франция. Труды 12-го Международного семинара по программному обеспечению и компиляторам для встраиваемых систем . SCOPES '09. Нью-Йорк, штат Нью-Йорк, США: ACM. стр. 21–30. ISBN 978-1-60558-696-0.
Farach, Martin; Liberatore, Vincenzo (1998). "On Local Register Allocation". Написано в Сан-Франциско, Калифорния, США. Труды девятого ежегодного симпозиума ACM-SIAM по дискретным алгоритмам . SODA '98. Филадельфия, Пенсильвания, США: Общество промышленной и прикладной математики. стр. 564–573. ISBN 0-89871-410-9.
Flajolet, P .; Raoult, JC; Vuillemin, J. (1979), «Количество регистров, необходимых для вычисления арифметических выражений», Theoretical Computer Science , 9 (1): 99–125, doi : 10.1016/0304-3975(79)90009-4
Джордж, Лал; Аппель, Эндрю В. (1996). «Итеративное объединение регистров». Труды ACM по языкам и системам программирования . 18 (3): 300–324. doi : 10.1145/229542.229546 . ISSN 0164-0925. S2CID 12281734.
Хорвиц, Л. П.; Карп, Р. М.; Миллер, Р. Э.; Виноград, С. (1966). «Распределение индексного регистра». Журнал ACM . 13 (1): 43–61. doi : 10.1145/321312.321317 . ISSN 0004-5411. S2CID 14560597.
Йоханссон, Эрик; Сагонас, Константинос (2002). «Распределение регистров линейного сканирования в высокопроизводительном компиляторе Erlang». Практические аспекты декларативных языков . Конспект лекций по информатике. Том 2257. С. 101–119. doi :10.1007/3-540-45587-6_8. ISBN 978-3-540-43092-6. ISSN 0302-9743.
Курдахи, Ф.Дж.; Паркер, А.С. (1987). "REAL: программа для распределения регистров". Труды 24-й конференции ACM/IEEE по конференции по автоматизации проектирования - DAC '87 . С. 210–215. doi :10.1145/37888.37920. ISBN 978-0818607813. S2CID 17598675.
Mössenböck, Hanspeter; Pfeiffer, Michael (2002). "Linear Scan Register Allocation in the Context of SSA Form and Register Constraints". Compiler Construction . Lecture Notes in Computer Science. Vol. 2304. pp. 229–246. doi :10.1007/3-540-45937-5_17. ISBN 978-3-540-43369-9. ISSN 0302-9743.
Никерсон, Брайан Р. (1990). «Распределение регистров раскраски графа для процессоров с многорегистровыми операндами». ACM SIGPLAN Notices . 25 (6): 40–52. doi :10.1145/93548.93552. ISSN 0362-1340.
Палечны, Майкл; Вик, Кристофер; Клик, Клифф (2001). «Компилятор сервера Java HotSpot». Труды симпозиума по исследованию и технологиям виртуальных машин Java (JVM01) . Монтерей, Калифорния, США. стр. 1–12. CiteSeerX 10.1.1.106.1919 .
Park, Jinpyo; Moon, Soo-Mook (2004). «Оптимистическое объединение регистров». ACM Transactions on Programming Languages and Systems . 26 (4): 735–765. CiteSeerX 10.1.1.33.9438 . doi :10.1145/1011508.1011512. ISSN 0164-0925. S2CID 15969885.
Poletto, Massimiliano; Sarkar, Vivek (1999). "Распределение регистров линейного сканирования". ACM Transactions on Programming Languages and Systems . 21 (5): 895–913. CiteSeerX 10.1.1.27.2462 . doi :10.1145/330249.330250. ISSN 0164-0925. S2CID 18180752.
Runeson, Johan; Nyström, Sven-Olof (2003). "Retargetable Graph-Coloring Register Allocation for Irregular Architectures". Программное обеспечение и компиляторы для встраиваемых систем . Lecture Notes in Computer Science. Vol. 2826. pp. 240–254. CiteSeerX 10.1.1.6.6186 . doi :10.1007/978-3-540-39920-9_17. ISBN 978-3-540-20145-8. ISSN 0302-9743.
Смит, Майкл Д.; Рэмси, Норман; Холлоуэй, Гленн (2004). «Обобщенный алгоритм распределения регистров для раскраски графов». ACM SIGPLAN Notices . 39 (6): 277. CiteSeerX 10.1.1.71.9532 . doi :10.1145/996893.996875. ISSN 0362-1340.
Трауб, Омри; Холловей, Гленн; Смит, Майкл Д. (1998). «Качество и скорость распределения регистров линейного сканирования». ACM SIGPLAN Notices . 33 (5): 142–151. CiteSeerX 10.1.1.52.8730 . doi :10.1145/277652.277714. ISSN 0362-1340.
Wimmer, Christian; Mössenböck, Hanspeter (2005). "Оптимизированное разделение интервалов в линейном сканирующем регистровом распределителе". Труды 1-й международной конференции ACM/USENIX по виртуальным средам выполнения - VEE '05 . стр. 132. CiteSeerX 10.1.1.394.4054 . doi :10.1145/1064979.1064998. ISBN 978-1595930477. S2CID 494490.
Wimmer, Christian; Franz, Michael (2010). "Распределение регистров линейного сканирования в форме SSA". Труды 8-го ежегодного международного симпозиума IEEE/ACM по генерации и оптимизации кода - CGO '10 . стр. 170. CiteSeerX 10.1.1.162.2590 . doi :10.1145/1772954.1772979. ISBN 9781605586359. S2CID 1820765.
Внешние ссылки
Учебник по целочисленному программированию
Конференция «Целочисленное программирование и комбинаторная оптимизация», IPCO
Семинар по комбинаторной оптимизации в Оссуа
Bosscher, Steven; и Novillo, Diego. GCC получает новый фреймворк оптимизатора. Статья об использовании SSA в GCC и о том, как он улучшается по сравнению со старыми IR.
Библиография SSA. Обширный каталог исследовательских работ SSA.
Задек, Ф. Кеннет. «Разработка статической формы одиночного присваивания», доклад от декабря 2007 г. о происхождении SSA.
ВВ.АА. "Проектирование компилятора на основе SSA" (2014)
Цитаты из CiteSeer
Руководства по оптимизации от Агнера Фога — документация по архитектуре процессора x86 и оптимизации кода низкого уровня