Добавляем функции в модуль LLVM, из которого мы делаем JIT

В настоящее время я пытаюсь использовать llvm::ExecutionEngine для JIT llvm::Function, которые я лениво генерировал с помощью моего генератора кода один за другим.

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

В результате получается направленный ациклический граф генерации кода:

func_1 ---> func_2 (depends on fn1)
    \
     \-> func_3 -> func_4 (depends on func_1 and func_3)

time -------------->

Теоретически все функции принадлежат одной и той же единице компиляции и должны возвращаться как одна llvm::Module объединение.

Можно ли как-то передать ExecutionEngine новыми функциями без добавления модуля (engine->addModule(...);) с предварительным объявлением каждый раз, когда я хочу добавить новую функцию в JIT (что в основном означает 1 модуль для каждой функции при рекурсивном создании)?

Потому что тогда мне пришлось бы клонировать все функции через llvm::CloneFunctionInto в объединение (или генерировать его снова), что не выглядит хорошим решением для меня.


person Denis Blank    schedule 10.01.2017    source источник
comment
Есть ли в коде хоть одно место, где вы наконец форсируете JIT-компиляцию модуля (например, с помощью getFunctionAddress)? Если это так, то вместо этого вы можете добавить функции в один llvm::Module, а затем, после того как все функции сгенерированы, наконец, добавить этот модуль в llvm::ExecutionEngine.   -  person eush77    schedule 21.01.2017
comment
Денис, ты нашел чистый способ решить эту проблему? Интересно, достаточно ли этого: stackoverflow.com/questions/24331498/ Я имею в виду, что это, вероятно, работает, но мне интересно, может ли LLVM сделать некоторые аккуратные оптимизации в этом случае (например, встроенные).   -  person freakish    schedule 10.03.2020