по ходу портанул live checker (на самом деле def/use checker) из halfmoon. чекер меня сразу же обозвал нехорошими словами. ну, в одном случае он явно неправ, а вот в остальных… вопрос.
в случае, когда он неправ — он отчего-то утверждает, что после `LIR_call` обязательно помечать `allocp` как живые. это совершенно не так, их помечает обработчик `LIR_call`. кажется, там небольшая ошибка: надо помечать только те `allocp`, которые индиректом адресуются. то бишь, штукой типа `addp(allocp, 32)`, например. вот тут Nanojit'у надо помочь. и я помогаю, конечно, без советчиков.
а ещё чекеру очень не понравилась каша, которую я делаю из CASE. в компиляторе три варианта CASE: чисто табличка, балансированое дерево (двоичный поиск), линейный перебор. и немножко эвристик, чтобы между ними выбирать. вот линейный перебор чекеру не понравился. опять таки: это ложная тревога, но чекер прав в другом: кодокаша.
с табличкой всё просто. с деревом — сначала генерируется весь код выбора, и только потом тела веток. а вот с линейным перебором всё плохо: тела веток генерируются сразу после проверок. и это приводит к тому, чего Nanojit очень не любит: к бранчам назад. потому что внутри для штук типа `| 1, 3, 5:` генерируются полноценные ветки. просто у веток для `3` и `5` вместо тела стоит указатель на ветку `1`. это без проблем разрешимо, когда мы сначала генерируем все проверки (или строим табличку), но вот когда линейно идём — нет. поэтому получается проверка уловия, и потом может случиться переход на ветку, тело которой сгенерировано раньше.
в общем, вышло сумбурно, но факт в том, что Nanojit очень не любит переходы назад. в силу того, что он пишет код начиная с последней инструкции — он не может определить набор живых результатов для таких переходов, и ему надо помогать специальной инструкцией `LIR_live`. и вот тут они с чекером вступают в противоречие.
если безусловно отмечать живым то, на что жалуется чекер — тогда начинает жаловаться сам Nanojit, на потеряные спилл-слоты. это обычно значит, что где-то что-то помечено живым неправильно. зато чекер доволен. и наоборот: довольный Nanojit делает грустный чекер.
в принципе, они тут оба правы: Nanojit прав практически, а чекер — теоретически. оба запутались в каше из переходов. там нормально всё с живостью, но доказать это довольно сложно; чекер вот путается в картинке базовых блоков. я и сам на этом месте путаюсь, так что ничего удивительного.
в общем, выкинуть всё, конечно, и написать нормально: сначала проверки, потом тела веток. и никаких переходов назад. оно так во всём коде красившее.
итог: любите чекеры! они стараются помочь. а если и ошибаются — то всё равно стараются помочь. помоги своему чекеру — и чекер поможет тебе. в данном случае он таки убедил меня переписать некрасивую кашу.
ах, да. каша появилась вследствие «органического роста». сначала CASE был очень простой и всегда линейный… а потом я обнаружил, что забыл реализовать штуки типа `| 1, 3, 5: …`. появились ветки-редиректы, и красивый линейный генератор перестал быть линейным. тут-то его надо было переписать, но… но проще ж добавить хак и убежать. он, кстати, ещё и ужасно неэффективен в таком виде: Nanojit не может в полной мере использовать регистры (они грязные после тел).
|