Связать код JL LLVM со статическими библиотеками LLVM? - PullRequest
16 голосов
/ 11 мая 2010

Я нахожусь в процессе реализации кроссплатформенного приложения (Mac OS X, Windows и Linux), которое будет выполнять большой объем процессорного анализа финансовых данных. Большая часть механизма анализа будет написана на C ++ по соображениям скорости, с доступным для пользователя механизмом сценариев, взаимодействующим с механизмом тестирования C ++. Я хочу написать несколько сценариев с течением времени для эмуляции другого популярного программного обеспечения с существующими большими пользовательскими базами. Первым фронтом будет язык сценариев, подобный VisualBasic.

Я думаю, что LLVM идеально подойдет для моих нужд. Производительность очень важна из-за огромного количества данных; Выполнение одного прогона тестов для получения ответа может занять несколько часов или дней. Я полагаю, что использование LLVM также позволит мне использовать одно серверное решение, в то время как я реализую различные интерфейсы для разных разновидностей языка сценариев с течением времени.

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

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

Я представляю, что с LLVM я мог бы напрямую реализовать обратные вызовы в C ++, чтобы заставить код сценария работать почти так, как если бы он был написан на C ++. Аналогично, если весь код был скомпилирован в формат байт-кода LLVM, кажется, что оптимизаторы LLVM могли бы оптимизировать через границы между языком сценариев и кодом механизма тестирования, который был написан на C ++.

Я не хочу каждый раз собирать движок тестирования. В идеале я бы хотел, чтобы JIT компилировал только код сценария. Для небольших тестов я пропускаю некоторые этапы оптимизации, а для больших тестов я выполняю полную оптимизацию во время ссылки.

Так возможно ли это? Могу ли я предварительно скомпилировать механизм тестирования в объектный файл .o или файл библиотеки .a, а затем с помощью JIT связать его в коде сценария?

Наконец, в идеале я хотел бы, чтобы код сценария реализовывал конкретные методы в качестве подклассов для определенного класса C ++. Таким образом, механизм тестирования C ++ будет видеть только объекты C ++, в то время как код установки JIT компилирует код сценариев, который реализует некоторые методы для объектов. Похоже, что если бы я использовал правильный алгоритм искажения имен, было бы относительно легко настроить поколение LLVM для языка сценариев, чтобы он выглядел как вызов метода C ++, который затем мог бы быть связан с механизмом тестирования.

Таким образом, этап связывания будет проходить в двух направлениях: вызовы из языка сценариев в объекты механизма тестирования для получения информации о ценах и состоянии теста и вызовы из механизма тестирования методов некоторых конкретных объектов C ++, в которые был передан код, не из C ++, но из языка сценариев.

В итоге:

1) Могу ли я связать предварительно скомпилированные (.bc, .o или .a) файлы как часть JIT-компиляции, процесса генерации кода?

2) Могу ли я ссылаться в коде, используя процесс, описанный в 1) выше, таким образом, чтобы я мог создавать код, который действует так, как если бы он был написан на C ++?

Ответы [ 3 ]

14 голосов
/ 19 мая 2010
  1. Да, мы можем! В зависимости от используемой версии LLVM могут быть разные вызовы API. вам потребуется llvm :: getBitcodeModuleProvider на 2.5.
  2. Самый простой способ вызвать функции C ++ - это создать функцию (llvm :: Function :: Create), используя флаг llvm :: Function :: ExternalLinkage, а затем добавитьGlobalMapping, чтобы она указала на вашу функцию C ++.
3 голосов
/ 11 мая 2010
  1. Я верю в это.
  2. Это волосатое тело. Вы должны соответствовать C ++ ABI функций, которые вы вызываете, и должны убедиться, что сгенерированный код использует те же структуры данных, классы, макет и т. Д. (Через эквивалент файлов заголовков). C ++ ABI имеет множество нюансов и проблем с переносимостью. Возможно, прототип с первым взаимодействием с Си. clang сейчас имеет ограниченную поддержку C ++.
1 голос
/ 21 июня 2010

1) Вы можете загружать и связывать файлы .bc, файлы .o, если они были скомпилированы в архив .so, и их можно загружать, а символы в них можно использовать.

2) Пока вы не хотите делать ужасные вещи с обратными вызовами, вы, вероятно, можете просто передавать стандартные указатели на функции C и выполнять обратные вызовы с помощью указателей на функции. Вы также можете делать некоторые другие вещи, но вам не нужно делать попытки определить объекты или шаблоны C ++ или вызывать функции-члены, не будучи компилятором C ++.

вы должны знать C ++ ABI, вы должны знать о платформе, на которую вы нацелены, вы должны знать все виды вещей, вы должны быть компилятором C ++ для генерации кода, который выглядит так, как будто это C ++. Название Mangler является одной из самых раздражающих частей.

...