Как стать автором
Обновить
11
0

Пользователь

Отправить сообщение
Кстати, если вспомнить, что LLVM – это виртуальная машина низкого уровня, то можно ли запустить её в режиме интерпретации? Т.е. подаёшь на вход какой-то код, а LLVM его выполняет? Не с целью генерации кода, а чтобы "поиграться", попробовать. В LLVM Projects нет намёков на это.
Промежуточное представление – это очень общее понятие, это может быть и ориентированный граф, и трёхадресный код, и обратная польская запись и т.д. Лексический, синтаксический, семантический анализ должны каким-то образом хранить анализируемую программу, для этого ПП и служит. Разным по стилю языкам можно подобрать наиболее удобную форму. Если я удалю своё ПП – то как я проанализирую? Воспользоваться ПП от LLVM? Но это опять проблемы. Где взять его описание, какие он оно вообще работает? Много вопросов. Больше, чем если бы просто делал по обычным учебникам.
Бэкенд для x86 уже написан, и он входит в состав LLVM. Я не знаю точно, что вы хотите сделать, но вам нужно внести изменения в Clang, наверное.
Вы хотите реализовать какой-то свой язык программирования?
Имею в виду преобразование (бэкенд) «своё промежуточное представление -> код x86» (которое для меня проще), нежели «своё промежуточное представление -> код LLVM IR»
Вы хотите реализовать какой-то свой язык программирования?
Мы, по-видимому, смотрим на LLVM под разным углом зрения: я – как состыковать свой язык программирования с LLVM, а Вы – как состыковать с ним своё железо :)
Вы говорили, что вам нужно только под платформу x86.
Да, нет, я начал с этого:
Знакомился с LLVM и не нашёл, как можно изменить содержимое указателя стека. В x86 можно написать так: «xchg esp,other_stack». А как сделать что-то подобное на LLVM?
Если есть какой-то универсальный механизм, то кто ж тогда откажется, чтобы его компилятор работал сразу на многих платформах? Честно говоря, написать бэкенд для x86 для меня проще, чем для LLVM, потому что всё знакомо. Но если LLVM позволит сделать многоплатформенный компилятор, то стоит задуматься об изучении LLVM – игра будет стоить свеч.
сделать ассемблерную вставку с нужной командой.
Да, такой «костыль» мог бы стать решением, вот только ещё надо знать, как это сделать. На Си я это делал как раз такой вставкой. Конечно, после вставки нативного кода универсальность теряется.
Если вы хотите сделать оптимизации нативного кода для конкретной архитектуры, то вам не нужно заниматься формированием IR-кода, нужно написать только бэкенд (или модифицировать существующий).
Вероятно, надо модифицировать существующий бэкенд, но потом из IR-кода надо ещё как-то воспользоваться этой модификацией. Короче, надо изучать и вникать. Литературы на русском мало, а с английской всё будет дольше.
Спасибо за проявленное терпение!
На уровне IR (промежуточного кода) никакого стека нет, он работает только с виртуальными (не физическими) регистрами.

Хотелось бы, чтобы были не только виртуальные регистры, но и виртуальный стек.

Дальше генерируются другие промежуточные представления, где действительно есть стек (точнее, Frame Index, индексы в кадре стека)

«Дальше» – это значит после уровня IR (промежуточного кода)? Если взглянуть на рис. 1. (модульная архитектура компилятора), то в центре стоит оптимизатор. На каком этапе существует IR и на каком появляется стек? Вроде бы выходит, что есть несколько промежуточных представлений. И какое из них всё ещё универсальное, не завязанное на конкретную архитектуру?

В чём притягательная сила LLVM? При написании компилятора нет необходимости делать сотню бэкендов, достаточно сделать единственное преобразование в LLVM IR (это так видится!). О преобразовании в код конкретной архитектуры позаботится инфраструктура LLVM. Главное – написать правильный бит-код для LLVM IR и запустить преобразование с правильными опциями.

Но, оказывается (такой вывод можно сделать из ваших слов), генерацию кода для целевой машины надо допиливать, сто раз для ста платформ. И в чём тогда притягательность LLVM? Для разработчиков новых архитектур она полезна: разработал свой бэкенд, и в твоём распоряжении компиляторы Си, Фортрана, Хаскелла. Но для разработчиков компиляторов новых языков – не вполне.
Из Википедии:
«В основе LLVM лежит промежуточное представление кода (Intermediate Representation, IR)… Из этого представления генерируется оптимизированный машинный код для целого ряда платформ, как статически, так и динамически (JIT-компиляция)».

Мне хотелось узнать, какими средствами LLVM IR нужно пользоваться, чтобы генератор кода (уже написанный для x86) делал переключение стеков. Меня не интересует конкретный бэкенд LLVM. Мне хочется узнать, как это сделать на уровне LLVM IR. Если LLVM IR это имеет, то и конкретный бэкенд сделает то, что я хочу. Может, он придумает что-то более оптимальное, нежели «xchg esp,other_stack».
Генерация кода из моего собственного промежуточного представления в нативный код быстрее, нежели из собственного промежуточного представления в промежуточное представление LLVM, из которого уже потом получается нативный код. Просто потому, что этапов меньше.

Для полного задействования возможностей x86, в т.ч. загрузки новым значением указателя стека, нужно переписать соответствующий бэкенд? Я правильно понял? Т.е. сейчас в LLVM указатель стека не может быть загружен новым значением по ходу работы? Или я не всё понял в устройстве LLVM?
Простите, личное сообщение было 32bit_me.

Но в LLVM есть понятие стека, следовательно, стек LLVM опирается на какое-то физическое воплощение в виде регистров. Когда запускается программа, указатель стека в LLVM инициализируется каким-то значением – иначе концепция стека работать не будет. Но как это происходит? Если указатель стека приобретает своё значение в начале работы программы, то он может быть загружен новым значением по ходу её работы?
Под компиляцией и генерацией машинного кода я имею в виду варианты:
1) генерация напрямую: программа на языке высокого уровня -> промежуточное представление -> нативный код,
2) генерация через LLVM: программа на языке высокого уровня -> промежуточное представление -> LLVM -> нативный код.

Первый вариант имеет преимущества:
1) быстрая компиляция
2) полное и эффективное использование возможностей конкретного процессора

Недостаток: необходимость разработки кодогенератора для каждой платформы

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

Мне интересно, насколько сильно обрезаны возможности LLVM в сравнении с традиционными ассемблерами, осталась ли там возможность изменения указатели вершины стека. Почему это интересует – написал в личном сообщении.

Архитектура x86 – живее всех живых, сейчас она существует в своей 64-разрядной инкарнации. Когда-то в ней был регистр SP, потом ESP, теперь RSP. Ну суть осталась та же: он указывает вершину стека. А архитектуре ARM на вершину стека указывает регистр № 13. И ARM, и x86 позволяют загружать эти регистры новым содержимым, т.е. после «xchg esp,other_stack» в 32-разрядной архитектуре x86 он указывает на другое место. А вот в LLVM такой возможности не увиделось. Возможно, плохо искал. Но, может быть, её вообще нет.

Вот в чём суть моих вопросов.
У меня есть обычный процессор x86. Если я пишу компилятор и желаю переключаться между стеками, то какой код генерировать для этого: машинный код х86 или же LLVM, в котором всё таки есть что-то похожее на «xchg esp,other_stack», но которое я не увидел?
Знакомился с LLVM и не нашёл, как можно изменить содержимое указателя стека. В x86 можно написать так: «xchg esp,other_stack». А как сделать что-то подобное на LLVM? Заранее спасибо.
Да, если нет вдохновения, то тяжело. Иногда даже не стоит начинать.
Так напишите и раскройте нам глаза, сколько мегабайт при этом портится. Приподнимите занавес, ведь вряд ли кто-то кинется писать конкурирующий анализатор.
Если это слишком большая тема для комментариев, то может изложить отдельной статьёй? Вы же, в конце концов, должны сказать своим пользователям: «Если у вас в программе завёлся goto, то пеняйте на себя, наш анализатор бесполезен».
Вам никогда не казалось, что создавая рекламу своему продукту, вы создаёте антирекламу C++? Когда такие люди допускают такие ошибки… «Может, что-то в консерватории подправить?» Ведь могут подумать: не лучше ли сменить язык, в котором не могут отказаться от наследия 60-х – 70-х годов – а оно нередко провоцирует на ошибки, чем приобретать лекарства от ошибок?

Кстати, не могли бы пролить свет на то, как анализ, который делается PVS-Studio, уживаются с «goto», наследием 60-х – 70-х? Какие сложности возникают перед анализатором, если встречается «goto», как это влияет на качество анализа? Ну и заодно могли бы коснуться операторов «break» и «continue», они ведь тоже меняют ход выполнения, хотя не так произвольно, как «goto».
Интересно, существуют процессоры, в которых нет регистров, но есть стек, вершина которого (некоторое количество машинных слов) хранится не в памяти, а во внутреннем(-их) регистре(-ах)? Ещё видится полезным, чтобы стек был не единственным, чтобы их было хотя бы два, чтобы переключаться между ними.
Советской экономике был присущ один недостаток, который отметил нобелевский лауреат, американский экономист Василий Леонтьев. Во главу угла был поставлен валовый продукт. Валовый продукт СССР равнялся (если не учитывать экспорт-импорт) сумма валовых продуктов всех предприятий СССР. Система хозяйствования поощряла увеличение валового продукта, но принижала роль других экономических показателей. Планы, зарплаты, премии, социалка – всё опиралось на валовый продукт.

Леонтьев предлагал опереться на добавленный продукт. Возьмём такой пример. Производственная цепочка от сырья до готового изделия состоит из четырёх звеньев. Первое предприятие добыло сырьё, произвело полуфабрикатов и продало их второму предприятию на сумму X. Второе предприятие, внеся свой вклад, продало полуфабрикатов третьему на сумму 2X. Третье – четвёртому на сумму 3X, а чётвёртое продало населению готовых изделий на сумму 4X. Все предприятия в этой цепочке выпустили валовый продукт в размере X+2X+3X+4X=10X. Количество денег в обращение выпускалось под валовый продукт 10X. Там и зарплаты, и премии, и социалка и прочее. Но добавленной продукции было выпущено в размере 4X!

Леонтьев (уже в перестройку) предлагал устранить эту кривизну. Но на это не пошли, да и не могли пойти по идеологическим причинам. Ведь ВВП СССР, посчитанный вот таким валовым способом, был ого-го какой! СССР был второй экономикой мира! Но только на бумаге. Если учитывать только добавленную стоимость, то ВВП сильно сдувался, а советскому руководству было важно показывать прогрессивному человечеству успехи социалистической экономики.

Так что ОГАС действительно могла пролить свет на причины дисбалансов в экономике – ещё до Василия Леонтьева.
СССР – это великое и трагичное рядом. С одной стороны, репрессированные родители, с другой – невероятный успех человека «из народа». По одну сторону – постоянная промывка мозгов коммунистической идеологией, по другую – культ труда и знаний. Поэтому отношение к событиям, людям, технологиям родом из СССР – «полосатое», где-то тепло, а где-то холодно.
достаточно дизассемблировать старый код и сассемблировать его 32-битным ассемблером
Значит, у меня не было сильного непреодолимого желания :)

Информация

В рейтинге
Не участвует
Откуда
Москва и Московская обл., Россия
Зарегистрирован
Активность