Здравствуйте, Shmj, Вы писали:
S>Вот есть LLVM, который умеет генерить IR. И по сути этот IR мало чем отличается от языка C, только менее удобен для чтения человеком, но чуть более удобен для парсинга. В нем даже указатели и структуры есть.
Да ты прям универсал. И искуственный интеллект тебя интересует, и насущные проблемы компиляции, и проблемы философии и религии тебе не чужды. Прям Леонардо да Винчи наших дней.
S>Вопрос такой — не разумнее бы было генерить голый C (пусть даже сокращенную его версию) вместо IR?
Вот есть LLVM, который умеет генерить IR. И по сути этот IR мало чем отличается от языка C, только менее удобен для чтения человеком, но чуть более удобен для парсинга. В нем даже указатели и структуры есть.
Вопрос такой — не разумнее бы было генерить голый C (пусть даже сокращенную его версию) вместо IR?
Здравствуйте, Shmj, Вы писали:
S>Вот по этой причине он и не является ассемблером — а ближе к C языку.
LLVM IR — трехадресный код, ближе к языку ассемблера и очень далеко от С.
S>Те же указатели там есть, циклы, функции, структуры.
Там нет циклов в явном виде, вместо них есть goto br и этого достаточно чтобы появидись циклы.
Здравствуйте, Shmj, Вы писали:
S>Ну может можно какое-то подмножество C сделать, чтобы там переменные определялись только 1 раз. Оно бы было валидным с т.з. С-компилятора, удобным для прочтения человеком — и выполняло бы те же самые функции, которые выполняет IR.
Так "С" недостаточно чтобы выразить сементику. Например "br i1 <cond>, label <iftrue>, label <iffalse>",
при замене его на "if () goto else goto" мы вернемся к тому с чего начинали.
То есть хотели превратить код, в то, что потом легко отобразилось бы на ассемблер,
а получаем опять AST, которое снова нужно парсить и превращать в "инструкции".
Можно было бы "C" научить передавать метки в функцию как аргументы,
типа:
Здравствуйте, Shmj, Вы писали:
S>Имхо, можно вместо IR использовать упрощенный C. Что мешает?
Нет в C, тем более упрощенном, явной информации, которая нужна для оптимизации и генерации кода. Например, для каждой переменной нужно знать в каких местах программы она определяется и где используется, а для этого нужно сделать анализ потока управления и поиск псевдонимов и нужно сохранить их результаты в чем-то, из чего в конце концов получится IR.
Здравствуйте, Shmj, Вы писали:
S>Ну может можно какое-то подмножество C сделать, чтобы там переменные определялись только 1 раз. Оно бы было валидным с т.з. С-компилятора, удобным для прочтения человеком — и выполняло бы те же самые функции, которые выполняет IR.
Оно не будет удобным для человека. Там в местах слияния потока управления появляются phi функции. Замучаетесь на них смотреть.
S>Или кроме требования определять переменные единожды — еще что-то важное есть?
Есть. Например, если IR реализован как трехадресный код, то порядок вычислений детерменирован.
S>>>Ну нет, это именно Си-подобный язык, с чуть более формальным синтаксисом. Pzz>>Он семантически ассемблер, а не Си.
S>Это с чего вы взяли то? Ассемблер работает напрямую с регистрами — а в IR — этого нет.
Регистры это особенности реализации того или иного цпу.
А IR это абстракция
Здравствуйте, Shmj, Вы писали:
S>Вот есть LLVM, который умеет генерить IR. И по сути этот IR мало чем отличается от языка C, только менее удобен для чтения человеком, но чуть более удобен для парсинга. В нем даже указатели и структуры есть.
S>Вопрос такой — не разумнее бы было генерить голый C (пусть даже сокращенную его версию) вместо IR?
Вы наверное мало на ассемблере писали. IR это тот же ассемблер, только с присваиваниями.
Здравствуйте, Shmj, Вы писали:
S>>>Ну нет, это именно Си-подобный язык, с чуть более формальным синтаксисом. Pzz>>Он семантически ассемблер, а не Си.
S>Это с чего вы взяли то? Ассемблер работает напрямую с регистрами — а в IR — этого нет.
Ассемблер, условно — это язык самого вычислителя, в форме пригодной для чтения человеком.
Какой этот вычислитель, абстрактный, конкретный, хардварный или софтварный — дело десятое.
Например, стековая машина, регистровая машина, итд — все имеют свой собственный ассемблер.
Строго говоря, ассемблер вовсе не обязан транслировать инструкции в код конкретного хардварного процессора.
Ассемблер вполне себе может транслировать и в байт-код, который потом будет съеден JIT.
Здравствуйте, Shmj, Вы писали:
S>Вот есть LLVM, который умеет генерить IR. И по сути этот IR мало чем отличается от языка C, только менее удобен для чтения человеком, но чуть более удобен для парсинга. В нем даже указатели и структуры есть.
S>Вопрос такой — не разумнее бы было генерить голый C (пусть даже сокращенную его версию) вместо IR?
S>>>Ну там же пример есть — llc — одна из тулуз LLVM. M>>Для компиляции С используй clang/gcc
S>Ваш вопрос был — зачем парсить IR. И мой ответ — хотя бы для того, чтобы из IR сделать ассемблерный код.
Ну,
чтобы тоже самое получить из С используй clang/gcc.
Здравствуйте, Muxa, Вы писали:
S>>Ваш вопрос был — зачем парсить IR. И мой ответ — хотя бы для того, чтобы из IR сделать ассемблерный код.
M>Ну, M>чтобы тоже самое получить из С используй clang/gcc.
M>Чего не хватает?
Здравствуйте, Shmj, Вы писали:
S>Вопрос такой — не разумнее бы было генерить голый C (пусть даже сокращенную его версию) вместо IR?
Не вполне понимаю смысл вашего вопроса.
Весь смысл LLVM — именно в IR. IR позволяет реализовывать широкий класс оптимизаций независимым от исходного языка образом.
Можете считать его "сокращённой версией голого C".
Вы же читали, собственно, вводную статью инициаторов проекта?
Цитирую:
The code representation is one of the key factors that differentiates LLVM from other systems. The representation is designed to provide high-level information about programs that is needed to support sophisticated analyses and transformations, while being low-level enough to represent arbitrary programs and to permit extensive optimization in static compilers.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Shmj, Вы писали: S>Но он ведь таковым не является. Если бы это была сокращенная версия C, что было бы разумно — то его можно было бы компилировать как C.
Эмм, по-прежнему непонятно, чего же вы хотите. IR можно компилировать точно так же, как С — получая на выходе бинарь для целевой платформы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Shmj, Вы писали:
S>Но он ведь таковым не является. Если бы это была сокращенная версия C, что было бы разумно — то его можно было бы компилировать как C.
Чтобы скомпилировать как C тоже нужен какой-нибудь IR. Зачем тода нужен дополнительный промежуточный этап преобразования C++ в C если можно сразу преобразовать C++ в IR?
Здравствуйте, Sinclair, Вы писали:
S>>Но он ведь таковым не является. Если бы это была сокращенная версия C, что было бы разумно — то его можно было бы компилировать как C. S>Эмм, по-прежнему непонятно, чего же вы хотите. IR можно компилировать точно так же, как С — получая на выходе бинарь для целевой платформы.
Было бы удобнее вместо нового IR использовать упрощеный C. Его и человеку читать привычнее и для парсера от IR не слишком будет отличаться, имхо.
Здравствуйте, cserg, Вы писали:
S>>Но он ведь таковым не является. Если бы это была сокращенная версия C, что было бы разумно — то его можно было бы компилировать как C. C>Чтобы скомпилировать как C тоже нужен какой-нибудь IR.
Имхо, можно вместо IR использовать упрощенный C. Что мешает?
Здравствуйте, cserg, Вы писали:
S>>Имхо, можно вместо IR использовать упрощенный C. Что мешает? C>Нет в C, тем более упрощенном, явной информации, которая нужна для оптимизации и генерации кода. Например, для каждой переменной нужно знать в каких местах программы она определяется и где используется, а для этого нужно сделать анализ потока управления и поиск псевдонимов и нужно сохранить их результаты в чем-то, из чего в конце концов получится IR.
Ну может можно какое-то подмножество C сделать, чтобы там переменные определялись только 1 раз. Оно бы было валидным с т.з. С-компилятора, удобным для прочтения человеком — и выполняло бы те же самые функции, которые выполняет IR.
Или кроме требования определять переменные единожды — еще что-то важное есть?
Здравствуйте, Shmj, Вы писали: S>Было бы удобнее вместо нового IR использовать упрощеный C.
Кому удобнее? S>Его и человеку читать привычнее и для парсера от IR не слишком будет отличаться, имхо.
Читаемость IR человеком не была среди приоритетов при разработке.
Но вы можете придумать C-синтаксис для IR и сделать компилятор туда-обратно. Всё, что нужно, у вас есть.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Shmj, Вы писали:
Pzz>>IR — это абстрактный ассемблер, а не Си.
S>Ну нет, это именно Си-подобный язык, с чуть более формальным синтаксисом.
Здравствуйте, Shmj, Вы писали: S>Это с чего вы взяли то? Ассемблер работает напрямую с регистрами — а в IR — этого нет.
Конечно есть. Вот только в его "виртуальной машине" количество регистров не ограничено.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>Вот по этой причине он и не является ассемблером — а ближе к C языку. Те же указатели там есть, циклы, функции, структуры.
Нет там циклов — разве что ты циклом называешь if+goto, и структуры чисто условные — доступ к полям через вычисления смещений, вместо них можно просто массивы соответствующих размеров использовать.
Здравствуйте, Shmj, Вы писали:
S>Вопрос такой — не разумнее бы было генерить голый C (пусть даже сокращенную его версию) вместо IR?
Хорошо, как должен выглядеть голый C, но чтоб по имени типа однозначно было понятно его машинное представление (без мутных параграфов), чтобы по сигнатуре однозначно было понятно, какие аргументы-указатели могут указывать на общий участок, по вещественному литералу определялся каждый бит его значения, ну это первое что я вспомнил?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, Shmj, Вы писали:
S>Вот по этой причине он и не является ассемблером — а ближе к C языку. Те же указатели там есть, циклы, функции, структуры.
В ассемблерах макросами даже ооп почти полноценное делается, не то что функции, циклы или структуры