Московский государственный технический университет им. Н.Э. Баумана
Опубликован: 28.06.2006 | Доступ: свободный | Студентов: 12463 / 344 | Оценка: 4.54 / 3.83 | Длительность: 22:03:00
ISBN: 978-5-9556-0055-0
Лекция 10:

Динамическая генерация кода

Оптимизация кода, содержащего развилки

Рассмотрим несколько простых методов оптимизации кода, содержащего развилки, а именно:

  • удаление избыточных инструкций сохранения значений в переменных;
  • удаление псевдонимов переменных;
  • воспроизведение констант;
  • удаление неиспользуемых переменных.

Хороших результатов можно достичь, если применять эти методы в совокупности с peephole-оптимизацией. При этом получаемая цепочка оптимизирующих преобразований должна выполняться над одним и тем же кодом многократно до тех пор, пока не будет достигнута неподвижная точка.

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

Это преобразование уменьшает количество присваиваний. Оно осуществляется только для переменных, адреса которых не используются. Под переменными мы будем понимать как локальные переменные, так и параметры методов.

Другими словами, избыточные инструкции stloc и starg удаляются только для переменных, не использующихся в инструкциях ldloca и ldarga.

Для обнаружения избыточных инструкций сохранения значений выполняется анализ использования переменной, состоящий из двух фаз:

  1. Построение графа использования переменной.
  2. Анализ графа использования переменной.

Инструкции ldloc(ldarg) X и stloc(starg) X будем называть инструкциями использования переменной X.

Мы будем говорить, что в графе потока управления инструкция использования B следует за инструкцией использования A на пути w, если:

  1. инструкции A и B используют одну и ту же переменную X ;
  2. путь w соединяет A и B ;
  3. путь w не содержит ни одной инструкции использования переменной X, кроме инструкций A и B.

Граф использования переменной X - это ориентированный граф, в узлах которого находятся инструкции использования переменной X, а дуги задают отношение следования для этих инструкций. То есть, если инструкция B следует за инструкцией A на каком-либо пути в графе потока управления, то в графе использования переменной X имеется дуга от инструкции A к инструкции B.

Анализ графа использования переменной заключается в нахождении таких инструкций stloc(starg), за которыми не следует ни одной инструкции ldloc(ldarg). Эти инструкции являются избыточными и заменяются инструкциями pop.

На рисунке 5.3 изображен пример графа использования переменной. Серым цветом обозначены избыточные инструкции stloc.

Пример графа использования переменной

Рис. 5.3. Пример графа использования переменной
Удаление псевдонимов переменных

Это преобразование позволяет избавиться от лишних присваиваний и уменьшает количество локальных переменных. Под переменной будем понимать, опять же, как локальные переменные, так и параметры методов.

Переменная Y является псевдонимом переменной X тогда и только тогда, когда:

  1. переменная X используется в теле метода только один раз, причем в инструкции ldloc(ldarg) X ;
  2. за инструкцией ldloc(ldarg) X непосредственно следует инструкция stloc(starg) Y (впрочем, допускается наличие между ними любого количества инструкций dup ). Причем инструкция stloc(starg) Y является первым использованием переменной Y (назовем ее инструкцией инициализации переменной Y ).
Удаление псевдонима Y переменной X

Рис. 5.4. Удаление псевдонима Y переменной X

Схема удаления псевдонима Y переменной X показана на рис. 5.4. При удалении осуществляются два действия:

  1. Инструкция инициализации переменной Y заменяется инструкцией pop.
  2. Все использования переменной Y заменяются использованиями переменной X.
Воспроизведение констант

Это преобразование позволяет избавиться от переменных, имеющих константное значение.

Переменная Y имеет константное значение C тогда и только тогда, когда:

  1. первым использованием переменной Y является инструкция stloc(starg) Y (назовем ее инструкцией инициализации переменной Y );
  2. инструкция инициализации переменной Y непосредственно следует за инструкцией ldc C (любая инструкция загрузки константы на стек вычислений). Впрочем, допускается наличие между ними любого количества инструкций dup ;
  3. за исключением инструкции инициализации, переменная Y используется только в инструкциях ldloc(ldarg) Y.

Схема воспроизведения константы C, являющейся значением переменной Y, показана на рисунке 5.5. При воспроизведении осуществляются два действия:

Схема воспроизведения константы C, являющейся значением переменной Y

Рис. 5.5. Схема воспроизведения константы C, являющейся значением переменной Y
  1. Инструкция инициализации переменной Y заменяется инструкцией pop.
  2. Инструкции ldloc(ldarg) Y заменяются инструкциями ldc C.
Удаление неиспользуемых переменных

Если некоторая переменная не используется в графе метода или встречается только в инструкциях stloc(starg), то она удаляется. При этом все инструкции stloc(starg), использующие эту переменную, заменяются инструкциями pop.

Анастасия Булинкова
Анастасия Булинкова
Рабочим названием платформы .NET было