Использование байт-кода LLVM для библиотек (вместо собственных объектных файлов)
Каковы последствия для
- переносимость (соглашение о вызовах: действительно ли это имеет значение на уровне LLVM, когда вызывается только функция библиотеки C или OS)
- время ссылки
- оптимизации
Я хотел бы скомпилировать игрушечный язык с помощью LLVM, поскольку все сложные компоненты уже присутствуют (оптимизация, генерация объектного кода), но я борюсь с концепцией, которую хотел бы сохранить, если она того стоит: файлы библиотеки должны быть распространяемый, используемый как статическая и совместно используемая библиотека (для связи, в совместно используемом случае будет сгенерировано реальное so или dll при связывании конечного приложения), переносимый. Я считаю, что это сократит часть времени компиляции (поскольку генерация собственного кода и, возможно, оптимизация выполняются только один раз, во время окончательного двоичного соединения). Я предполагаю, что компоновщик позаботится о соглашении о вызовах (если возможно) и преобразовании в разделяемую библиотеку по запросу. В далеко растянутом дополнении, возможно, LLVM можно было бы использовать, чтобы не связывать, и использовать JL LLVM для непосредственного запуска сгенерированного байт-кода, полностью удаляя время ссылки при написании кода.
Это звучит
- Выполнимо?
- Стоило того? Я знаю, что время ссылки C/C++ сравнительно велико, что проблематично при частой перестройке. Как насчет бесплатной оптимизации времени ссылки (CFR
/GL
а также-flto
поскольку это будет по существу байт-код LLVM, связанный вместе, который затем будет преобразован в собственный двоичный файл).
Это может быть неопределенный вопрос, если мне нужно что-то уточнить, пожалуйста, спросите.
1 ответ
Я делал что-то подобное в прошлом. Вы должны понимать, что битовый код LLVM не является "переносимым" в том смысле, что он не является полностью независимым от машины. Файлы битовых кодов содержат сведения о размере указателей и т. Д., Которые зависят от целевого процессора.
Сказав это, в прошлом я компилировал программы и их библиотеки поддержки для битового кода и связывал файлы битового кода вместе, прежде чем генерировать файл сборки для всей программы. Вы правы в том, что соглашения о вызовах не важны для внутренних вызовов, но для вызовов, совершаемых снаружи (или снаружи), все еще требуется соблюдение ABI.
Возможно, вам удастся спроектировать ваш игрушечный язык таким образом, чтобы избежать бит-кода, зависящего от процессора, но вам нужно быть очень осторожным.
Я заметил, что объединение файлов битового кода заняло довольно много времени, особенно на высоких уровнях оптимизации. Возможно, это ускорилось, я сделал это с LLVM 2-3 года назад.
И последнее замечание: в зависимости от целевого процессора вам, вероятно, понадобится эквивалент libgcc.a или compiler-rt для обработки вещей, которые процессору не нравятся с плавающей запятой, или 64-битных целочисленных вещей, если процессор не имеет инструкций, которые выполнить эти операции.