-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Продумать и реализовать изменения в архитектуре, необходимые для высокоуровневых оптимизаций #155
Comments
Собственно, изменения продумал. Когда реализую, задокументирую в комментариях, что сделал и как этим пользоваться. |
Реализован обход результатных выражений и пометка в них «холодных» вызовов функций, не подлежащих дальнейшей оптимизации. А ещё реализовано раскрытие конструкторов замыканий слева от угловых скобок. Возможно, написано местами не оптимально — оптимизировать будем после реализации полноценной высокоуровневой оптимизации.
Заготовка для написания оптимизаторов находится в ветке В этой ветке (а вернее в актуальной master под ней) есть удобный логгер, который в процессе компиляции пишет в указанный файл синтаксическое дерево до, во время и после оптимизации. Для ознакомления можно выполнить На данный момент в каркасе добавлены следующие ключи
Опция Каркас в настоящий момент на каждой итерации обходит дерево с раскрытием конструкторов замыканий после открывающих угловых скобок и помечает неоптимизируемые функции «холодными», после чего вызывает проходы встраивания и специализации. Под «холодным» вызовом понимается вызов функции, которая (а) не оптимизируема, (б) аргумент вызова «холодный» (не содержит вызовов других функций или эти вызовы тоже холодные). Соответственно, проходы оптимизаций не должны рассматривать холодные вызовы, считать их (неразменными) e-переменными и т.д. Итерации выполняются, пока счётчик не обнулится, либо пока дерево не перестанет меняться между проходами. Точки входа для обоих оптимизаторов по смыслу одинаковы и имеют следующий вид: Функция Функция Функция Я создал отдельные подзадачи #157 и #158, в которых описал первые шаги по реализации оптимизаторов (правки парсера, checker’а и рассахаривателя). К этим задачам можно будет приступить, когда я закончу задачу #159 (про entry-функции). @StrixSeloputo и @madnaaaaas, вы работаете в своих ветках и не паритесь. Слияниями заниматься буду я. @StrixSeloputo и @madnaaaaas, отпишитесь в этом issue, если прочли этот комментарий и задачи #158 и #157 соответственно. |
Выполнил задачу #159, обновил описания задач #157 и #158, ветки @madnaaaaas и @StrixSeloputo , теперь можете писать свой код. |
Задачу можно закрыть. Всё сделано. |
Реализован обход результатных выражений и пометка в них «холодных» вызовов функций, не подлежащих дальнейшей оптимизации. А ещё реализовано раскрытие конструкторов замыканий слева от угловых скобок. Возможно, написано местами не оптимально — оптимизировать будем после реализации полноценной высокоуровневой оптимизации.
Дублирующиеся коммиты выше из-за того, что я ветку пересадил на новый master. Верить им. |
Если в автотесте присутствует слово TREE, то для него дополнительно запускаются тесты с ключами -OT, -OD, -OI, -OS, -OS --markup-context, -ODS --markup-context. Оптимизация специализации в идеале должна поддерживать --markup-context, поскольку аргументы функции рвутся на части и переупорядочиваются.
Эта задача — подзадача для #122 и #126.
Если внимательно посмотреть задачи по прогонке (#122) и специализации (#126) функций, а также на промежуточное представление, становится понятно, что актуальные структуры данных неадекватны новому синтаксису. Функции теперь могут быть, помимо типа entry/локальная, ещё и встраиваемыми, прогоняемыми и специализируемыми.
Со специализацией всё достаточно просто: для конструкта
$SPEC
можно просто добавить в синтаксическое дерево новый узел верхнего уровня.А вот с
$INLINE
,$DRIVE
и$ENTRY
хитрее. Функция может быть помечена как$ENTRY
в списке, подобном спискам$EXTERN
,$ENUM
и т.д. А ключевые слова$INLINE
и$DRIVE
могут находиться перед именем функции.Есть предложение для этого заменитьТакже для списковs.ScopeClass
на(e.Flags)
, где флагами могут бытьEntry
,Drive
иInline
.$ENTRY
,$DRIVE
и$INLINE
потребуется новый узел верхнего уровня.Подобное изменение AST потребует изменения обоих парсеров (
SR-Parser.sref
,), Checker’а, возможно, движка (R5-Parser.ref
Driver.sref
Engine.sref
) и, конечно, рассахаривателя (Desugaring.sref
,Desugaring-UnCondition.ref
). Т.е. весь front-end.Кстати, о рассахаривателе. Оптимизацию можно поместить как между рассахаривателем и высокоуровневым RASL’ом, так и внутри самого рассахаривателя после (опционального — см. #17) прохода удаления условий. Мне кажется, второй вариант предпочтительнее. Выход рассахаривателя для back-end’а менять не нужно.
О самой оптимизации. Оптимизация предполагает многократное и поочерёдное выполнение проходов специализации и прогонки/встраивания, одни проходы будут открывать возможность для других проходов. Например, специализация функции
Map
по применяемой функции откроет возможность прогонки этой функции, встраивание функцииPipe
(Seq
) откроет возможность встраиваний и специализаций перечисленных проходов.Многократность проходов несёт в себе зерно зацикливания: можно легко написать такую программу, что компилятор на ней зациклится, бесконечно выполняя прогонку, специализацию или встраивание. Задача обнаружения зацикливаний — алгоритмически неразрешимая, для неё возможно найти только приближённое решение. Наиболее общие решения разрабатываются в теории суперкомпиляции (отношение Турчина, Хигмана-Крускала и разные эвристики), что для нашей задачи совершенно избыточно. Поэтому есть предложение выбрать прагматичный вариант: ограничить количество итераций некоторой верхней границей, которая задаётся опцией командной строки.
Внутреннее устройство самого прохода оптимизации ещё подлежит обдумыванию, будет зафиксировано в комментариях к этой задаче.
The text was updated successfully, but these errors were encountered: