flang компилятор доказывает, что программа не зациклится 0.6.2 GitHub

Отбрасывание недостижимого на стороне flang даёт тот же ответ и стоит в 180 раз дороже

flang/src/reachable.mjs — 248 строк JavaScript в рабочем пути flang check, и сторона на flang у него УЖЕ ЕСТЬ: «Отбросить недостижимое» в flang/self/link.flang. Ответы совпадают. Переключать всё равно нельзя, и довод не «дорого вообще», а «дорого ровно там, где это стоит на горячем пути».

Чем подтверждено. Прогон 19 августа на ветке work/nepodvizhnaya-tochka поверх ствола 2bfcb7d0. Обе реализации звались на одной и той же отмеченной программе, время — performance.now() вокруг вызова:

программафункцийJavaScriptсторона на flangво сколько раз
examples/import-check.flang291 мс106 мс165
flang/self/emit-c.flang54724 мс1 947 мс80
flang/self/bootstrap/compiler.flang3 616143 мс25 905 мс181

Плюс 686 мс на сборку слоя link.flang при первом спросе. Ответы совпали на всех трёх, включая урезание 3 616 → 3 587 функций у самого компилятора.

Почему это отказ, а не «пока подождём». Отбрасывание недостижимого стоит на пути КАЖДОЙ печати во все восемь целей (flang/bin/flang.mjs, единственный вызов dropUnreachable). 26 секунд вместо 143 миллисекунд на собственном компиляторе — это не размен по времени, это другая команда: flang emit из секундной становится минутной.

Чем ограничено. Число — про слой, который едет ВЫЧИСЛИТЕЛЕМ. Собранный двоичный компилятор считает то же самое машинным кодом, и к нему этот замер не относится вовсе. То есть отказ здесь — от «звать сторону из рабочего пути интерпретируя», а не от стороны как таковой.

Побочное, найденное тем же заходом. Проверка «долг не вырос» (flang/test/rabochiy-put.test.mjs) искала сторону в файле того же имени — flang/self/reachable.flang, — не находила и МОЛЧАЛА. То есть готовая сторона не попадала в долг именно потому, что её назвали иначе: она живёт внутри link.flang. Это тот же класс, что «переименование файла молча выключает проверку»: соответствие имён надо задавать таблицей, а не соглашением.

Поправка 19 августа: цена подтвердилась, а вывод «остаётся навсегда в рабочем пути» — нет. Здесь и в docs/javascript-removal.md стояло, что модуль остаётся в рабочем пути flang check. Он из него ушёл, и переключать решение при этом не пришлось.

Цена перемерена на дереве ветки work/zelenyy-stvol тем же способом: ×203 на import-check.flang (1 мс против 160), ×116 на self/emit-c.flang (19 против 2 262), ×192 на самораскрутке (164 мс против 31 494), сборка слоя 981 мс, ответы совпали побайтово на всех трёх. Отказ от переключения в силе.

Но flang check dropUnreachable НЕ ЗОВЁТ НИ РАЗУ — он нужен одной команде emit. В перепись модуль попадал потому, что ввоз стоял статической строкой наверху flang/bin/flang.mjs и грузился в каждую команду. Ввоз отложен внутрь commandEmit, и 248 строк ушли из переписи, не тронув ни цены, ни ответа: печать считает тем же JavaScript, что и считала.

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

Связано: removed-from-the-decision-and-removed-from-the-load-are-two-events, a-side-may-already-exist-check-before-writing, renaming-a-file-silently-disables-the-guard, four-pieces-of-javascript, a-ratchet-instead-of-derivation