Как стать автором
Обновить

Как работает оптимизирующий компилятор

Время на прочтение23 мин
Количество просмотров19K
Всего голосов 78: ↑75 и ↓3+72
Комментарии14

Комментарии 14

Не надо быть умнее компилятора. Красивый и понятный код легче поддерживать, а компилятор и сам неплохо выкинет лишнее.
Я некоторое время назад написал транспиллер из bf в llvm ir… И было очень интересно смотреть как компилятор выкидывал куски кода заменяя на константы…
К сожалению, компиляторы не идеальны и иногда таки приходится либо объяснять, что же я хочу тут получить (с помощью атрибутов, интринсиков и так далее). Ну или на худой конец просто садимся писать на ассемблере, если некогда ждать, когда там в компиляторе пофиксят очередное правило для оптимизации.

Ага, не спорю никто не идеален, но так надо делать только после профайлинга и понимания проблемы.

Кому-то же надо писать оптимизирующие компиляторы

Красивый и понятный код легче поддерживать, а компилятор и сам неплохо выкинет лишнее.
Главное — компилятор ничего не может сделать с вашими структорами данных. Код — да, компилятор уже часто генерирует очень неплохой. А вот понять, что вы тут вычисляете структору в 100 мегабайт только чтобы где-то в другом месте спросить сколько там в ней элементов… он может только в простейших, сильно искусственных случаях.

Ну если таблица используется как просто хранилище данных и не изменяется то компилятор может вытаскивать данные просто по смещению. Но в целом да. Максимум что может так оптимизировать обращение к структуре, тут вы правы.

Сейчас как раз появляются первые попытки что-то такое сделать. Робкие и малополезные.

Может лет через 20 — это всё будет и не нужно. Но пока — о структурах данных приходится думать программисту

Программа — это описание закономерностей между входными сайд-эффектами и выходными. Если они не нарушаются, то компилятор может делать что угодно (хоть заменить весь код на GLUT).


… А ещё компилятору разрешено нарушать временные сайд-эффекты, но запрещено нарушать causality.

>Теперь мы знаем, что logger — это PrintLogger
Как? type propagation или type inference? Если inference — то какой? Hindley-Milner или есть что поинтереснее?

>а multiplied — нет: она начинается с 0 и каждый раз умножается через multiplied = multiplied * count,

Ээээ, нееет. В смысле да, но как мы об этом узнали? Точнее не мы а компилятор. Что стоит за этим выводом — гвоздями прибитый эмпиризм или он на этой же логике выведет str += '' и int += 0?

ну и так далее и тому подобное. /зануда моде офф
В Java, как и в Scala (автор статьи, Li Haoyi, хорошо известен Scala сообществу) не может быть использован алгоритм Hindley–Milner, так как HM не поддерживает sub-typing.
yep. Пропустил плашку перевода.

В статье про Optimization Pass'ы ни слова про SSA / mSSA / Array-SSA, зато куча байт-кода…
Слишком глубоко копнули без разъяснения теоретических основ, общих оптимизационных задач и практик.

Кое-что компилятор не смог оптимизировать (например, неиспользуемый вызов new PrintLogger)

Есть предположение, что компилятор вынужден был оставить не вызов пустого конструктора, а загрузку класса PrintLogger.


Кстати, что именно вы декомпилировали? Байт-код (результат javac) или результат JIT?

Все равно, на лапше-коде этот компилятор помрет на первом же этапе, да и бессмысленно.
А вот solid код, с минимум побочных эффектов, — это довольно безопасно, масштабируемо, и эффективно. Тот же Burst Compiler — чудесное решение, хоть и сырое.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий