Как нам улучшить Би
Apr. 24th, 2025 10:48 pmВ симуляторе dubna заработал компилятор с языка программирования Би. Подробности смотрите в списке рассылки: besm6/c/cRbp6A-dUXc/m/_al8inGlDQAJ
Чем Би может быть нам полезен? Во первых, в чисто познавательном отношении. Из его исходников многое видно и понятно. Во вторых, Би может помочь разобраться, что и как надо делать в компиляторе Си.
Стоит ли улучшать сам компилятор Би? Судя по сдержанной реакции публики, никто так и не заглянул в порождаемый ассемблерный код. Там нельзя сказать чтобы совсем ужас-ужас, но можно многое улучшить. Это одно потенциальное направление развития. Другое направление - вместо ассемблерного текста выдавать сразу бинарный объектный модуль. Но честно говоря, я не вижу, кто собирается пользоваться этим компилятором. Так что актуальность низкая.
Как улучшить качество генерируемого кода? Сейчас код выдаётся сразу непосредственно из парсера. По этой причине никакая пост-обработка невозможна. Надо вместо немедленной выдачи кода через printf (или write) складывать его в некий буфер. Это может быть массив размером, скажем на 100 машинных команд или больше, там видно будет. Для каждой команды можно хранить четыре слова:
После каждого добавления машинной команды в этот буфер вызывается функция оптимизации. Она реализует набор эвристик. Смотрит на последнюю команду и на предыдущие, и при возможности заменяет их на более оптимальную последовательность. К примеру, сейчас присваивание "x = y" генерится как:
Придётся переделать размещение строковых литералов. Проще всего писать их на временный барабан, а в конце каждой функции добавлять в конец бинарного модуля.
Чем Би может быть нам полезен? Во первых, в чисто познавательном отношении. Из его исходников многое видно и понятно. Во вторых, Би может помочь разобраться, что и как надо делать в компиляторе Си.
Стоит ли улучшать сам компилятор Би? Судя по сдержанной реакции публики, никто так и не заглянул в порождаемый ассемблерный код. Там нельзя сказать чтобы совсем ужас-ужас, но можно многое улучшить. Это одно потенциальное направление развития. Другое направление - вместо ассемблерного текста выдавать сразу бинарный объектный модуль. Но честно говоря, я не вижу, кто собирается пользоваться этим компилятором. Так что актуальность низкая.
Как улучшить качество генерируемого кода? Сейчас код выдаётся сразу непосредственно из парсера. По этой причине никакая пост-обработка невозможна. Надо вместо немедленной выдачи кода через printf (или write) складывать его в некий буфер. Это может быть массив размером, скажем на 100 машинных команд или больше, там видно будет. Для каждой команды можно хранить четыре слова:
- номер индекс регистра
- код машинной команды
- тип адреса
- значение адреса
После каждого добавления машинной команды в этот буфер вызывается функция оптимизации. Она реализует набор эвристик. Смотрит на последнюю команду и на предыдущие, и при возможности заменяет их на более оптимальную последовательность. К примеру, сейчас присваивание "x = y" генерится как:
Это безобразие должно преобразовываться в:14,VTM,X
,ITA,14
14,VTM,Y
,ITS,14
,ATI,14
14,XTA,
15,WTC,
,ATX,
,XTA,Y
,ATX,XКак выдавать бинарный модуль? У нас имеется реализация формата бэсмовского модуля на Си: stdobj.c, stdobj.h. Переписать это дело на Би и вызывать вместо печати мадленовского текста.Придётся переделать размещение строковых литералов. Проще всего писать их на временный барабан, а в конце каждой функции добавлять в конец бинарного модуля.
no subject
Date: 2025-04-25 06:52 am (UTC)Что касается кода выдаваемого на присваивание это очень странно, с чем это может быть связано. Видимо тут какая-то особенность того что он изначально был сделан для PDP?
Если добавлять оптимизации то боюсь что компилятор сильно распухнет и не будет self-hosted (а хотелось бы эту аутентичность сохранить)
Я как-то давно упражнялся в компиляторо-писании и делал транслятор из упрощенного Оберона в инструкции БЭСМ-6 (нашей МЭСМ-6) и ради теста запустил на таком примере:
MODULE Halt;
var a,b : integer;
begin
b := a
END Halt.
Выдает вот такой вот псевдо код (М15 стек, точно не помню, но вроде М1 - фрейм, М2 - таблица констант или глобальных переменных):
[('LABEL', 'Halt_main'),
('ALLOC', 2),
('VLOAD', -2, 'a'),
('VSTOR', -1, 'b'),
('STOP', '12345')]
TEXT:
00000: VTM 10 ,M1
00001: VTM 10 ,M15
00002: VTM 8 ,M2
00003: UJ 4
00004: Halt_main UTM 2 ,M15
00005: XTA -2 ,M1
00006: ATX -1 ,M1
00007: STOP 12345
00008: WORD 0
00009: WORD 0
CONSTANT TABLE:
PROCEDURE TABLE
Halt_main: 4
STOP at PC=7 code=12345 ir=0
у меня там крайне простой алгоритм который аккумулятор рассматривает как вершину стека и не совершает никаких оптимизационных проходов, то есть генерит код как и деды 60 лет назад
В общем, загадка Би
no subject
Date: 2025-04-25 06:55 am (UTC)no subject
Date: 2025-04-25 03:05 pm (UTC)