Анализ псевдонимов - это метод в теории компиляторов, используемый для определения того, может ли место хранения доступны более чем одним способом. Два указателя называются псевдонимом, если они указывают на одно и то же место.
Методы анализа псевдонимов обычно классифицируются по чувствительности к потоку и контексту. Они могут определять информацию о возможном или обязательном псевдониме. Термин анализ псевдонимов часто используется взаимозаменяемо с анализом точек, конкретным случаем.
Анализаторы псевдонимов предназначены для создания и вычисления полезной информации для понимания псевдонимов в программах.
Как правило, анализ псевдонимов определяет, указывают ли отдельные ссылки памяти на одну и ту же область памяти. Это позволяет компилятору определить, какие переменные в программе будут затронуты оператором. Например, рассмотрим следующий раздел кода, который обращается к членам структур:
p.foo = 1; q.foo = 2; я = p.foo + 3;
Здесь есть три возможных случая псевдонима:
Если p и q не могут быть псевдонимами, тогда i = p. foo + 3;
можно изменить на i = 4
. Если p и q должны быть псевдонимами, то i = p.foo + 3;
можно изменить на i = 5
, потому что p.foo + 3
= q.foo + 3
. В обоих случаях мы можем выполнять оптимизацию на основе знания псевдонимов (предполагая, что никакой другой поток , обновляющий те же места, не может чередоваться с текущим потоком, или что языковая модель памяти разрешает эти обновления не должны быть немедленно видимы для текущего потока при отсутствии явных синхронизирующих конструкций ). С другой стороны, если неизвестно, являются ли псевдонимы p и q или нет, то оптимизация не может быть выполнена, и весь код должен быть выполнен для получения результата. Говорят, что две ссылки на память имеют отношение «возможно-псевдоним», если их псевдоним неизвестен.
При анализе псевдонимов мы разделяем память программы на классы псевдонимов. Классы псевдонимов - это непересекающиеся наборы местоположений, которые не могут быть псевдонимами друг друга. Для обсуждения здесь предполагается, что выполняемые здесь оптимизации происходят на низкоуровневом промежуточном представлении программы. Это означает, что программа была скомпилирована в двоичные операции, переходы, перемещения между регистрами, переходы из регистров в память, переходы из памяти в регистры, переходы и вызовы / возврат функций.
Если компилируемый язык является типобезопасным, проверка типов компилятора верна, и в языке отсутствует возможность создавать указатели, ссылающиеся на локальные переменные (такие как ML, Haskell или Java ), то можно сделать некоторые полезные оптимизации. Во многих случаях мы знаем, что две ячейки памяти должны находиться в разных классах псевдонимов:
При выполнении псевдонима При анализе кода каждая загрузка и сохранение в памяти должны быть помечены своим классом. Затем у нас есть полезное свойство, учитывая ячейки памяти и с классы псевдонимов, если , то may-alias , а если тогда ячейки памяти не будут псевдонимами.
Анализ на основе потока может применяться к программам на языке со ссылками или преобразованием типов. Анализ на основе потоков может использоваться вместо или в дополнение к анализу на основе типов. При потоковом анализе новые классы псевдонимов создаются для каждого выделения памяти и для каждой глобальной и локальной переменной, адрес которой был использован. Ссылки могут указывать на более чем одно значение с течением времени и, следовательно, могут относиться к более чем одному классу псевдонимов. Это означает, что каждая ячейка памяти имеет набор классов псевдонимов вместо одного класса псевдонимов.