Size: a a a

Compiler Development

2021 January 27

LA

Liber Azerate in Compiler Development
а это кто
Ну если это AST, то FunStatement должен быть наследником Statement
Да, я об этом думал... Наверно так и сделаю
источник

LA

Liber Azerate in Compiler Development
а это кто
И класса Node не должно быть в моём понимании, только Statement, Expression и их наследники (варианты)
Так я всё же считаю лучше выражается связь. У них общий интерфейс
источник

LA

Liber Azerate in Compiler Development
а это кто
И у Statement есть вариант ExpressionStatement который создаётся когда выражение является единственным в утверждении как тут

2 + 2;
fun();
За это у меня отвечал сам класс Statement, но в принципе действительно
источник

LA

Liber Azerate in Compiler Development
а это кто
И ещё например есть

class IfElseStatement inherits Statement {
   Expression condition;
   Statement if_true;
   Statement if_false;
}


Так надеюсь понятнее как этим пользоваться
А со Statement'ами да, и так всё понятно. У меня это выглядит немного так:

class Stmt : public Node { ... };
class IfElseBase : public Stmt { ... };
class If : public IfElseBase{ ... };
class IfElse : public IfElseBase{ ... };
источник

LA

Liber Azerate in Compiler Development
а это кто
Ты программируешь на C++?
Да
источник

LA

Liber Azerate in Compiler Development
а это кто
И у Statement есть вариант ExpressionStatement который создаётся когда выражение является единственным в утверждении как тут

2 + 2;
fun();
Вообще, я не хотел наследоваться от Statement именно потому, что сделал его изначально ExpressionStatement, по достаточно определённым причинам. И в таком случае мне кажется логичным, что FunStatement наследоваться от него не может. Хотя я держал в голове то, что Statement не всегда ExpressionStatement при его написании. Но, может, лучше действительно всё же наследоваться от него
источник

а

а это кто in Compiler Development
Liber Azerate
Вообще, я не хотел наследоваться от Statement именно потому, что сделал его изначально ExpressionStatement, по достаточно определённым причинам. И в таком случае мне кажется логичным, что FunStatement наследоваться от него не может. Хотя я держал в голове то, что Statement не всегда ExpressionStatement при его написании. Но, может, лучше действительно всё же наследоваться от него
В C-подобных языках помимо утверждений-выражений (ExpressionStatement) есть If утверждения, switch, for, while, break, continue и goto, и все они, без условно являются Statement поэтому наверное удобнее сделать ExpressionStatement вариантом Statement
источник

а

а это кто in Compiler Development
Что ты вообще парсишь? забыл спросить хд
источник

LA

Liber Azerate in Compiler Development
а это кто
В C-подобных языках помимо утверждений-выражений (ExpressionStatement) есть If утверждения, switch, for, while, break, continue и goto, и все они, без условно являются Statement поэтому наверное удобнее сделать ExpressionStatement вариантом Statement
Да, у меня практически всё это есть, кроме continue и goto, но в итоге только break не использует Expr, а ещё мне удобно сделать так, чтобы я мог конструировать пустой Statement. Собственно, для
stmts -> stmt
  |
источник

LA

Liber Azerate in Compiler Development
а это кто
Что ты вообще парсишь? забыл спросить хд
Свой язык, это пет
источник

LA

Liber Azerate in Compiler Development
Ну и архитектуру я делал с оглядкой на пример компилятора в книге дракона и пример в доке llvm, поэтому вот немного запутался
источник

LA

Liber Azerate in Compiler Development
Ладно, спасибо, думаю, я понял как сделаю
источник

а

а это кто in Compiler Development
Liber Azerate
Ладно, спасибо, думаю, я понял как сделаю
источник

а

а это кто in Compiler Development
Класс
источник

EM

Evgenii Moiseenko in Compiler Development
Evgenii Moiseenko
Всем привет!)
Вопрос по llvm (который дублирует https://stackoverflow.com/questions/28900202/how-to-translate-intrinsics-to-a-legacy-architecture)
У меня есть анализатор llvm кода (не klee), у которого под капотом кастомный интерпретатор биткода. Естественно, этот интерпретатор не поддерживает все возможные интринсики.
Тем не менее, я хочу запустить его на довольно большой кодовой базе, где как раз встречаются различные интринсики. Интепретатор не может их обработать и падает с ошибкой.
Есть ли какой-то стандартный способ попробовать заловерить интринсики в минимально возможное подмножество биткода, чтобы не поддерживать все возможные интринсики в интерпретаторе? (llvm::IntrinsicLowering не помогает).
В Klee, как я понял, ребята борятся с этим тем, что сами ручками пишут пассы, которые ловерят интринсики, но если честно мне не хотелось бы сейчас этим заниматься :)
https://github.com/klee/klee/issues/678
У меня сейчас интерпретатор не может справиться примерно с тем же списком интринсиков, что и в issue в klee.
BTW, компиляция с -O0 не помогает, clang все равно эмитит интринсики, об которые интерпретатор спотыкается. В частности, сейчас он вылетает с ошибкой на llvm.rint.f64.
Так что изначальный вопрос все ещё актуален (если вдруг кто-то может помочь советом :)
источник

DF

Dollar Føølish in Compiler Development
А есть флажочек типа -march ?
источник

DF

Dollar Føølish in Compiler Development
Возможно при более легасцовой архитектуре таргета , и более легасцовый ir будет
источник

EM

Evgenii Moiseenko in Compiler Development
Dollar Føølish
Возможно при более легасцовой архитектуре таргета , и более легасцовый ir будет
У clang-a есть --target. Попробовал поиграться с ним, но пока безрезультатно.
Хочется чтобы он генерил IR как будто под что-то x86-подобное, но без всяких приблуд и поминимум всяких специфичных интринсиков )
источник

NK

ID:0 in Compiler Development
Распределение регистров - одна из старейших проблем построения компиляторов, первые работы по которой появились еще в 50-ые годы прошлого века. Как и в других NP-полных задачах недостатка в эвристических решениях нет. Тем не менее, в последние десятилетия разработчики все чаще используют один из двух глобальных подходов: линейное сканирование в динамических (JIT) компиляторах и раскраску графа в статических (AOT) компиляторах.

В своей диссертации Йозеф Эйсель (Josef Eisl) предлагает новый субглобальный подход к распределению регистров в динамических компиляторах, имеющий в основе следующие наблюдения:

1. Глобальные методы тратят много времени на редко исполняемый (холодный) код.

2. В современных динамически компилируемых языках после агрессивного встраивания функций (inline) появляются большие функции, где много холодного кода.

3. Крупные функции при глобальном охвате занимают много времени.

Выходит, что если сконцентрировать внимание алгоритма на горячих участках в ущерб холодным, то можно за то же время найти эффективное (или даже оптимальное!) распределение на отдельных важных участках кода.

В качестве важных участков Эйсель выбрал непересекающиеся последовательности базовых блоков - трассы (traces). Каждая трасса в зависимости от популярности получает свою политику распределения - быструю и неэффективную, долгую и эффективную, компромиссную или даже специализированную.

Интересно, что схожий подход уже применялся в трассирующих jit-компиляторах, но там трассы компилировались целиком, тогда как у Эйселя трассы выделяются только для распределения регистров.

Эйсель в сотрудничестве с Oracle реализовал подход в GraalVM, нового jit-компилятора для JVM, где тот показал сравнимую с актуальными версиями линейного сканирования производительность порожденного кода при меньшем времени РР. При этом распределение на трассах позволяет искать баланс между временем компиляции и производительностью распределения, а также открывает возможности для  параллельной работы над трассами.

В настоящий момент код по умолчанию выключен, но доступен в Java версий от 10 и новее через опции
java -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler -Dgraal.TraceRA=true
.

https://ssw.jku.at/General/Staff/Eisl/papers/phdthesis.pdf

#registerallocation #trace #graalvm #jvm
источник

f

for(int c; (c = getc... in Compiler Development
Есть-ли какой-нибудь формат для представления хода выполнения программы? Т.е. все вызовы функций, итерации циклов, проверки условий, присвоения переменных и т.д. Я хочу написать проход для компилятора который к исходному коду добавляет логи - т.е. для кода

for i in 0 .. 3:
 echo i

мы должны получить

for i in 0 .. 3:
 log("loop start")
 log("var set i = ", i)
 log("function call echo", i)
 echo i
 log("loop end")

Проход должен работать на AST после семантической проверки - т.е. есть доступ ко всем символам, определения типов и прочее, так что конкретные детали реализации можно не учитывать (как получать значения переменных, записи в них и т.д)

Основная проблема в формате записи и восстановления хода работы после  выполнения программы - можно придумать какой-то свой формат записи, но может быть уже существуют похожие решения?

И впоследствии я хочу сделать что-то схожее с дебаггером в котором можно проследить весь "путь" значения через все присвоения, вызовы и циклы. Или сделать визуализацию работы самой программы.
источник