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

«Вынут из решения» и «вынут из загрузки» — два разных события, и второе бывает дороже первого

Переключить слой на flang — значит отдать ему РЕШЕНИЕ. Файл на JavaScript от этого из рабочего пути не уходит: его продолжает тянуть первый попавшийся импорт, и тянуть может ради одного числа. Пока это не разделено словами, отчёт «слой переключён» читается как «файла больше нет», а файл на месте.

Чем подтверждено — три случая, все прогоном.

файлрешение отданочто держало загрузкучем снято
src/obligations.mjs16 августакакНаписан и одинаковы у четырёх потребителейразделением: обе функции выехали в src/as-written.mjs
src/monoid.mjs19 августаПРЕДЕЛ_СЕТКИ — одно число 12 для ведомостикопия числа в src/self.mjs + сверка копии с объявлением слоя
src/iso.mjs19 августато жето же

Перепись рабочего пути (flang/test/rabochiy-put.test.mjs) считает ЗАГРУЗКУ, а не решение, и потому не обманывает: пока файл грузится, он в числе. На стволе 1d02a4cb путь был 36 файлов и 37 371 строка; после переключения семи законов — 29 и 36 341.

Отвергнутый путь и довод. Число можно было читать у слоя, лениво — в тот же миг, когда связывается слой. Кажется чище: один хозяин, ни одной копии. Прогон это отверг: ведомость печатается СИНХРОННО и не только из externalCheckszakon-commutative.test.mjs строит итоги руками и печатает ведомость, не связав ни одного слоя. Отказ «предел не прочитан» покраснел там тремя проверками. Довод не «дорого», а «мимо»: у ведомости есть вызывающие, которые слоя не строят и строить не должны.

Значит копия, и копия с хозяином: число живёт в src/self.mjs, а объявляет его слой, и self-laws.test.mjs сверяет их. Разъехаться молча они не могут.

Чем ограничено. Это про модули, у которых подпись узкая. Файл, из которого берут десяток имён, так не снимается: там разделение упирается в то, что разделять.

Дополнение 19 августа: состояний не два, а три, и третье снимается дешевле всех. Заход «дропай javascript» (work/zelenyy-stvol) снял четыре файла с рабочего пути flang check — 27 файлов и 37 081 строка стали 23 и 35 991, — и снялись они тремя разными приёмами:

состояниепримерприёмцена
решает свидетельsrc/grid.mjsпереключить на слой flangзамер: ×1,4 на худшей программе
решает слой, грузит имяsrc/svoystva.mjsразделение либо копия числа под сторожемноль
не решает вовсеsrc/factcheck.mjs, src/reachable.mjsотложить ввоз внутрь команды, которой он нуженноль

Третье состояние легко не заметить, потому что снаружи оно неотличимо от второго: файл в переписи есть. Разница в том, что его не держит НИЧЕГО, кроме статической строки наверху точки входа. factcheck.mjs (449 строк) нужен одной команде facts, reachable.mjs (249) — одной команде emit, а грузились оба в каждую команду. Вместе это 698 строк из 1 577 вынутых за заход, и стоили они по одной строке правки.

Как отличить «грузится» от «решает», не гадая. Каждый экспорт подозреваемого модуля оборачивается счётчиком (в КОПИИ дерева, не в нём самом), и команда прогоняется на всём корпусе. На 144 программах examples из восьми модулей долга семь оказались зовущимися хоть раз — checkMonadLaws на 144 из 144, достижимыеОтказы на 2 из 144, — а два снятых не звались ни разу. Текстовый поиск по импортам этого не различает вовсе: он видит одну и ту же строку.

Чем ограничено дополнение. Приём работает, только когда у модуля ОДИН потребитель и тот в асинхронной команде. У src/conc.mjs потребителей пять, и четыре из них — синхронные разбор и вывод типов; отложить ввоз там нечем.

Связано: dropping-unreachable-code-in-flang-costs-180-times-more, the-law-oracle-was-blocked-by-totality-not-by-first-class-functions