Межпроцедурные анализы и оптимизации

Содержание

Слайд 2

Содержание

Межпроцедурные оптимизации:
Граф вызовов процедур ( call graph )
Подстановка процедур ( inline )
Частичная

Содержание Межпроцедурные оптимизации: Граф вызовов процедур ( call graph ) Подстановка процедур
подстановка ( partial inline & outlining)
Пропагация констант, диапазонов, выравнивая, указателей и алиасов ( constant, range, alignment, points-to, aliases propagation )
Клонирование процедур ( cloning)
Замена стандартных процедур ( replacing)
Хвостовая рекурсия ( tail recursion)
Оптимизации доступа в память ( memory optimizations)
Межпроцедурные анализы указателей:
Результаты анализов: указатели и алиасы, свойства may- и must-point-to
Неинициализированные указатели и неадресные значения
Чувствительность к потоку управления
Чувствительность к вызывающему контексту
Модель обработки динамической памяти и составных объектов
Учет языковых типов, требование компиляции всей программы
Эффективный анализ на основе свойства транзитивности
Точный анализ на основе ЧТФ

Agenda

Слайд 3

Граф вызовов процедур

Граф вызовов – мультиграф, вершины – процедуры. Вершины proc1, proc2

Граф вызовов процедур Граф вызовов – мультиграф, вершины – процедуры. Вершины proc1,
соединены ориентированном ребром (proc1 , proc2 ), если процедура proc1 вызывается из proc2.
Трудности при построении:
Раздельная компиляция
Различные вызовы одной и той же процедуры ( пометка точки вызова)
Вызовы по косвенности и рекурсивные вызовы
Глобальные метки и нелокальные переходы
Свойства графов:
Динамический и статический
Чувствительность к контексту ( fully context-sensitive <-> context-insensive)
Оптимизации на графе вызовов:
Удаление невызывающихся процедур ( «мертвый код»)
Пропагация свойства процедур невозврата управления ( abort, exit, longjmp) для переноса операции через операцию вызова
Планирование на межпроцедурном уровне по «холодным» и «горячим» регионам – не просаживать буфер инструкций
Анализ указателей – уточнение графа вызовов, превращение косвенных вызовов в прямые

Call graph

Слайд 4

Подстановка процедур

Подстановка процедуры – замена вызова процедуры на копию ее кода, связывание

Подстановка процедур Подстановка процедуры – замена вызова процедуры на копию ее кода,
формальных параметров с фактическими, возвращаемых значений с переменными, в который происходит запись этих значений.

Inline

Слайд 5

Подстановка процедур

Трудности:
Несовпадение числа формальных и фактических параметров ( функции с переменным числом

Подстановка процедур Трудности: Несовпадение числа формальных и фактических параметров ( функции с
параметров, нотация Керниган-Риччи)
Нелокальные метки в вызывающем контексте – простановка глобальных меток в точках подстановки процедуры
Коррекция профильной информации и результатов анализов
Подстановка рекурсивной процедуры
Плюсы:
Избавляемся от накладных расходов на вызов
Специфицируем контекст для проведения локальных оптимизаций ( оптимизация циклов)
Минусы:
Рост кода
Просадка кеша инструкций
Давление на регистры
Утяжеление процедуры – увеличение времени работы компилятора – неэффективный анализ
Поддержка в языках программирования - директива inline

Inline

Слайд 6

Подстановка процедур

Схемы подстановки – разный обход графа вызовов:
Начиная с main берем процедуру

Подстановка процедур Схемы подстановки – разный обход графа вызовов: Начиная с main
и подставляем в нее все вызываемые процедуры, которые могут быть подставлены.
Начиная с процедур, не содержащих вызовы ( листовых) подставляем их в процедуры, откуда они вызываются и могут быть подставлены.
Оптимизация листовых процедур (Leaf-Routine Optimization)
упрощение пролога и эпилога вызова процедуры за счет того, что внутри не содержится вызовов.
Эвристики inline:
Профильная информация ( чем больше процедура вызывается, тем больше она годится для подстановки)
Размер подставляемого кода ( чем меньше процедура, тем больше она годится для подстановки)
Процедуры внутри цикла надо подставлять для расширение возможностей оптимизации
Если некоторые параметры процедуры константы, то надо подставлять для повышения эффективности оптимизаций благодаря пропагации констант

Inline

Слайд 7

Частичная подстановка

Частичная подстановка ( partial inline) - процедуры с большим размером кода,

Частичная подстановка Частичная подстановка ( partial inline) - процедуры с большим размером
не подходящим по эвристике для подстановки, но содержащие значительную вероятную часть.
Подготовка ( outlining ):
В соответствии с профилем выделяется наиболее вероятная часть процедуры
Выходы из вероятной части стягиваются в одну точку, в которой строится вызов новой процедуры называемой хвостовой ( tail proc), содержащей маловероятные остатки
Outlining полезен для уменьшения размера процедур

Partial inline and outlining

вер. часть

маловер. остатки

Вер. часть

Call tail_proc

маловер. остатки

Слайд 8

Частичная подстановка

Подстановка:
Если у процедуры есть разрезанная копия, то подставляем вероятную часть и

Частичная подстановка Подстановка: Если у процедуры есть разрезанная копия, то подставляем вероятную
оставляем вызов хвостовой части
Процедура с большим размером кода, но при вызове она специфицируется параметрами до небольшого размера – необходим пропагатор.

Partial inline and outlining

Слайд 9

Пропагатор

Пропагация констант ( constant propagation) – пропагирует статически известные константные значения

Пропагатор Пропагация констант ( constant propagation) – пропагирует статически известные константные значения по представлению. Propagator
по представлению.

Propagator

Слайд 10

Пропагатор

Пропагация выравниваний определяет для каждой операции доступа в память выровненность на

Пропагатор Пропагация выравниваний определяет для каждой операции доступа в память выровненность на
определенное значение ( фортран ).
Пропагация указателей определяет к каким именно объектам в памяти обращаются операции доступа в память.
Пропагация алиасов определяет могут ли две операции доступа в память работать с одним фрагментом.
Пропагация диапазонов определяет интервал или набор возможно принимаемых значений объектами программы
С помощью этих анализов возможно специфициовать поведение процедуры для опеределенных вызывающих контекстов – провести клонирование процедур.

Propagator

Слайд 11

Клонирование процедур
Клон – спецификация процедуры для определенного вызывающего контекста
Клонирование подставляет вместо

Клонирование процедур Клон – спецификация процедуры для определенного вызывающего контекста Клонирование подставляет
вызова процедуры вызов ее клона, соответствующего приходящим в эту точку вызова контекстам
После клонирования становится возможно подстановка.

Cloning

Множество вызывающих контекстов

Множество вызывающих контекстов 1

Процедура f

Множество вызывающих контекстов n

Клон f1

Клон fn

Слайд 12

Клонирование процедур

Cloning

Клонирование процедур Cloning

Слайд 13

Замена стандартных процедур

Replacing – замена вызова стандартной функции с некоторыми параметрами

Замена стандартных процедур Replacing – замена вызова стандартной функции с некоторыми параметрами
на эквивалентный код
Это позволяет сделать затем подстановку или вообще избавиться от вызова.
Для замены требуется условие доверия к стандартным библиотекам, errno и т.д.

Replacing

Слайд 14

Хвостовая рекурсия

Хвостовая рекурсия – преобразование рекурсии в цикл заменой рекурсивного вызова процедуры

Хвостовая рекурсия Хвостовая рекурсия – преобразование рекурсии в цикл заменой рекурсивного вызова
переходом к первой операции.
Для замены необходимо:
После рекурсивного вызова сразу следует выход из процедуры
При наличии профиля вызовов > 0
Если глубина >= 2, то уменьшаем ее с помощью подстановки.

Tail recursion

Слайд 15

Оптимизации работы с памятью

Оптимизация размещения данных в памяти замена выделения многомерного массива

Оптимизации работы с памятью Оптимизация размещения данных в памяти замена выделения многомерного
на одномерный.
Разбор шаблона – динамическое выделение многомерного массива
Замена его на выделение одномерного массива
Замена работы с многомерным массивом на одномерный
Расположение исходных данных по профильной информации
Шаблон выделения памяти:
a = malloc( n1*sizeof(data**));
for ( i = 0; i < n1; i++ )
{
a[i] = malloc( n2*sizeof(data*));
for ( j = 0; j < n2; j++ )
a[i][j] = malloc( n3*sizeof(data));
}

Memory optimizations

Слайд 16

Оптимизации работы с памятью

Memory optimizations

Оптимизации работы с памятью Memory optimizations

Слайд 17

Оптимизации работы с памятью

Memory optimizations

Оптимизации работы с памятью Memory optimizations

Слайд 18

Оптимизации работы с памятью

Memory optimizations

Оптимизации работы с памятью Memory optimizations

Слайд 19

Оптимизации работы с памятью

Достаточные условия для применения:
Выделение памяти через стандартные функции malloc,

Оптимизации работы с памятью Достаточные условия для применения: Выделение памяти через стандартные
calloc, memalign
Не было взятия адреса на объекты, содержащие данные (в примере static double ***a) или указатели на данные ( исключая возможно стандартные безобидные функции scanf(“%d”,&a[i][j][k] )
Отслежены все обращения к данным ( для глобальных данных необходим анализ в режиме компиляции всей программы)
Плюсы:
Замена нескольких операций доступа в память на одну ( блочную)
Улучшение работы индексного анализа, разрыв зависимостей
Дополнительное переупорядочивание данных позволяет оптимизировать работу с памятью
Переупорядочивание данных ( Reordering transformations)
Транспонирование матрицы ( разместить в памяти по столбцам)
Массив структур -> структуру массивов ( AoS -> SoA )
Разрезание и переупорядочивание структур ( Structure splitting and reordering)

Memory optimizations

Слайд 20

Анализы указателей и алиасов

Результаты анализов:
анализ указателей – на какие области памяти указывает

Анализы указателей и алиасов Результаты анализов: анализ указателей – на какие области
каждый указатель в программе
анализ алиасов – для любых пар указателей ответ указывают ли они на одну область памяти
Анализ указателей => анализ алиасов
Анализ алиасов => анализ указателей ?
p = &x; q = &p; *q = &y;
p ->{x,y}, q->{p}
<*p,x>,<*q,p>,<**q,y>,<**q,x>

Points-to and aliases analysis

Слайд 21

Анализы may-point-to и must-point-to

Свойства результатов:
анализ may-point-to – указатель может указывать на некоторую

Анализы may-point-to и must-point-to Свойства результатов: анализ may-point-to – указатель может указывать
область памяти
анализ must-point-to – указатель обязательно указывает на некоторую область памяти

May-Point-to and must-point-to analysis

Слайд 22

Неинициализированные указатели и неадресные значения

Разыменование неинициализированного указателя
Некорректная семантика – завершение анализа
Разыменование в

Неинициализированные указатели и неадресные значения Разыменование неинициализированного указателя Некорректная семантика – завершение
правой части присваивания ( только чтение). Тогда считаем обращения к объекту в левой части ( в который пишем) конфликтуют со всеми обращениями в память
Разыменование в левоей части присваивания – некорректная семантика и завершение
Игнорируем. Считаем, что результат разыменования не будет использован как адрес для обращения в память, иначе ошибка исполнения.

Слайд 23

Неинициализированные указатели и неадресные значения

Неадресные значения ( что считать инициализацией указателя)
Любое присваивание

Неинициализированные указатели и неадресные значения Неадресные значения ( что считать инициализацией указателя)
в указатель – инициализация
Присваивание только адресных значений – адреса объектов программы и возвращаемый процедурами выделения памяти

Слайд 24

Чувствительность к потоку управления

Учитывает или нет поток управления внутри анализируемых процедур (

Чувствительность к потоку управления Учитывает или нет поток управления внутри анализируемых процедур
flow-sensitive и flow-insensitive )
Увеличивает точность анализа
Существенно увеличивает расходы на память
Замедляет работу анализа
Позволяет затирать в точке постдоминирующего присваивания предыдущие значения указателя – свойство сильного обновления ( strong update )

Слайд 25

Чувствительность к вызывающему контексту

Разделение информации ( вызывающий контекст), приходящей в процедуру по

Чувствительность к вызывающему контексту Разделение информации ( вызывающий контекст), приходящей в процедуру
разным путям исполнения ( сontext-sensitive )
Нахождение нереализуемых путей ( путь, который никогда не может возникнуть в процессе исполнения программы - unrealized paths problem)

Слайд 26

Чувствительность к вызывающему контексту

Вызывающий контекст однозначно определяется путем в графе вызовов
Разные пути

Чувствительность к вызывающему контексту Вызывающий контекст однозначно определяется путем в графе вызовов
могут давать идентичные контексты, но в общем случае число различных контекстов – число всех путей к процедуре из main – экспонента от числа процедур программы
Если есть рекурсивные циклы - число путей потенциально бесконечно
Необходимо объединять информацию, приходяющую из разных вызывающих контекстов
Объединять всю информацию – не чувствительный к контексту
Различать контексты по точкам вызова процедур ( на примере для g этого не достаточно)
Клонирование процедур и граф активаций программы

Слайд 27

Модель обработки динамической памяти

Вся динамическая память - один объект
Создавать уникальный объект динамической

Модель обработки динамической памяти Вся динамическая память - один объект Создавать уникальный
памяти по точке выделения
Путь в графе вызовов определяет объект – эскпонента
Некоторый начальный отрезок пути с эвристический длиной

Слайд 28

Модель обработки динамической памяти

Эвристически распознавать выделение памяти ( newnode – выделение памяти)

Модель обработки динамической памяти Эвристически распознавать выделение памяти ( newnode – выделение памяти)

Слайд 29

Обработка составных объектов

Различать элементы составных объектов или рассматривать как единое целое
Множество локализаций

Обработка составных объектов Различать элементы составных объектов или рассматривать как единое целое
– подмножество целочисленной прямой, задается парой
Для однозначности s != 0 и 0<=fМножество локализаций позволяют производить теоретико-множественные операции над бесконечными множествами за константное время.
Объединение, разность – наименьшее множество, содержащее результат. Требуется нахождение НОД шагов.
Не учитывает размера области памяти.

Слайд 30

Обработка составных объектов

Соотвествие языковых типов и множества локализаций

Обработка составных объектов Соотвествие языковых типов и множества локализаций

Слайд 31

Обработка составных объектов

Некорректное использование union

Обработка составных объектов Некорректное использование union

Слайд 32

Учет языковых типов

Учет типа для операций доступа в память
Область памяти, независимо от

Учет языковых типов Учет типа для операций доступа в память Область памяти,
типа, может содержат указатель любого типа – слаботипизированные языки C/C++
Строгое следование языковым типам – не обработать многие реальные программы
Использовать часть ограничений из стандарта языка – например позволять обращаться к int[] c помощью char *, но запрещать доступ по указателю на процедуру или константую строку.
Использовать информацию о типе для эвристик – например через формальные параметры типа указатель ждать передачи указателей соответствующего типа.

Слайд 33

Требование компиляции всей программы
Необходимо наличие для анализа всей программы, за исключением возможно

Требование компиляции всей программы Необходимо наличие для анализа всей программы, за исключением
стандартных библиотек ( флаг доверия к библиотекам)
Динамически линкуемые библиотеки
Помодульная компиляция – анализу необходим предполагать, что любая глобальная переменная может быть модифицированна, любая функция может быть вызвана с неизвестными параметрами

Слайд 34

Пример эффективного анализа

Анализ на основе свойства транзитивности
Для отношения «алиасить» добавляется свойство транзитивности:

Пример эффективного анализа Анализ на основе свойства транзитивности Для отношения «алиасить» добавляется
если <*p,x> и <*p,y>, то .
За один проход по представлению происходит сбор информации об алиасах и объединение объектов в соответствии с введенным отношением.
Транзитивность увеличивает скорость и уменьшает точность.
Результаты – информация об алиасах
May-aliased анализ
Не чувствителен к управлению
Не чувствителен к контексту
Динамическую память различает по точкам вызова
Элементы составных объектов не различаются
Языковые типа не использует
Требуется компиляция в режиме вся программа

Слайд 35

Пример точного анализа

Анализ на основе ЧТФ
Трасферная функция процедуры определена для всех вызывающих

Пример точного анализа Анализ на основе ЧТФ Трасферная функция процедуры определена для
контекстов, результат - измененный процедурой вызывающий контекст. ( a )
Частичная трасферная функция определена не для всех возможных вызывающих контекстов.
Обобщение одной ЧТФ на все
вызывающие контектсты и
получение таким образом ТФ -
моновариантный анализ ( b )
Построение нескольких ЧТФ,
определенных в совокупности
на всех вызывающих
контекстах -
поливариантный анализ ( с )

Слайд 36

Анализ на основе ЧТФ

Идея абстрактной интерпритации – начиная с main итерационно собирается

Анализ на основе ЧТФ Идея абстрактной интерпритации – начиная с main итерационно
информация о значении указателей и завершается, когда значения указателей в main перестают меняться.
Встречаем вызов, построение ЧТФ текущей процедуры приостанаваливается и переходим к анализу вызвынной процедуры ( построению новой или обобщению уже имеющейся ЧТФ), затем продолжается построение ЧТФ текущей процедуры.
Эвристики – число ЧТФ, алгоритм сравнения контекстов, обощение области определения ЧТФ. Эффективность ?? точность.

Слайд 37

Анализ на основе ЧТФ

Пример
Как формализовать контекст с точки зрения интересующего нас свойства

Анализ на основе ЧТФ Пример Как формализовать контекст с точки зрения интересующего нас свойства указывать?
указывать?

Слайд 38

Анализ на основе ЧТФ

Чтобы задать область определения ТФ используем points-to функции
p->{x,y}

Анализ на основе ЧТФ Чтобы задать область определения ТФ используем points-to функции
p->{y}
1-й и 2-й контекст одинаковые, как это отразить?
Пространстро имен ( name space) для каждой ЧТФ:
Локальные блоки – не зависящие от вызывающего контекста ( формальные параметры, локальные переменные, динамически выделяемая память)
Нелокальные блоки – существуют в вызвающем контексте ( глобальные переменные, объекты вызывающей процедуры)
Block binding function – связывает нелокальные блоки в вызывающем и вызываемом контексте

Слайд 39

Анализ на основе ЧТФ
Начальная points-to функция для main
Начальная и конечная points-to функция

Анализ на основе ЧТФ Начальная points-to функция для main Начальная и конечная
для f в точке вызова S1
В начале процедуры перезаписываем значение *p, потому на что указыает b0 нас не интересует

Слайд 40

Анализ на основе ЧТФ

Начальная и конечная points-to функция для f в точках

Анализ на основе ЧТФ Начальная и конечная points-to функция для f в
вызова S3
пунктиром анализ определяет, что при записи в *p, записали в *r
Конечная points-to функция для main

Слайд 41

Анализ на основе ЧТФ

Блоки создаем только когда встречаем реальное разыменование указателя, т.е.

Анализ на основе ЧТФ Блоки создаем только когда встречаем реальное разыменование указателя,
записываем информацию не в виде “p есть указатель на b0”, а “p c начальным значением”

Слайд 42

Анализ на основе ЧТФ

Неявные вызовы – включаем в область определения ЧТФ таблицу

Анализ на основе ЧТФ Неявные вызовы – включаем в область определения ЧТФ
с указателями на функции, которые потенциально могут быть вызваны. Добавляем только в случае реального вызова.

Слайд 43

Анализ на основе ЧТФ

Обработка рекурсии

Анализ на основе ЧТФ Обработка рекурсии
Имя файла: Межпроцедурные-анализы-и-оптимизации.pptx
Количество просмотров: 118
Количество скачиваний: 0