Вызовите функции C/C++ из ExecutionEngine
Я изучаю llvm и хотел сделать доказательство концепции идеи, которая у меня есть.
По сути, я хочу разделить мой компилятор и время выполнения. Компилятор выдаст.bc, а среда выполнения загрузит его через ParseBitcodeFile и использует ExecutionEngine для его запуска. Эта часть работает.
Теперь, чтобы легко выполнять системные вызовы, я хочу иметь возможность реализовывать в моем C/C++ функции времени выполнения, которые выполняют все системные вызовы (файл io, печать стандартного вывода и т. Д.). Мой вопрос заключается в том, как я мог бы вызывать эти функции из кода моего игрушечного компилятора, который компилируется на другом шаге с помощью llvm, и позволять использовать его при выполнении.
2 ответа
Хорошая новость: при использовании JIT ExecutionEngine
, это будет просто работать. Когда JIT-er находит внешний символ, используемый IR, который не найден в самом IR, он просматривает сам процесс JIT, поэтому можно вызывать любые символы, видимые из вашей хост-программы.
Это объясняется непосредственно в части 4 учебного пособия по LLVM:
Ого, как JIT узнает о грехе и созидании? Ответ на удивление прост: в этом примере JIT начал выполнение функции и получил вызов функции. Он понял, что функция еще не была скомпилирована JIT, и вызвал стандартный набор подпрограмм для разрешения функции. В этом случае для функции не определено тело, поэтому JIT в конечном итоге вызвал "dlsym("sin")" в самом процессе калейдоскопа. Поскольку "sin" определен в адресном пространстве JIT, он просто исправляет вызовы в модуле, чтобы напрямую вызывать версию sin для libm.
Для кровавых подробностей посмотрите на lib/ExecutionEngine/JIT/JIT.cpp
- в частности, его использование DynamicLibrary
,
Ответ Илии велик, и ты должен принять это. Есть и другая альтернатива, которая заключается в том, чтобы отдельно скомпилировать исходные файлы вашей среды выполнения в модули LLVM (например, с Clang) и использовать ExecutionEngine::addModule()
добавить их.
Это менее удобно, и это означает компиляцию одних и тех же файлов дважды (один раз для вашей хост-программы, другой для получения Module
от них), но преимущество заключается в том, что он позволяет встроить и другие перекрестные функции оптимизации из вашего кода JITted.