Предложение по дизайну: llvm с несколькими контекстами времени выполнения

Мое приложение должно запускать множество отдельных контекстов в одном и том же (однопоточном) процессе. Все они имеют один общий LLVMContext.

Процесс будет запускать много контекстов (в смысле потока); то есть каждый из них запускает функцию в объекте продолжения, основанном на boost::context(все еще в хранилище, предварительно утвержденная библиотека), это означает, что каждый контекст может уступать, но они в основном работают в одном и том же единственном -поточный процесс. Каждый из них должен работать в основном независимо от другого, и, что более важно, ошибка компиляции в каждом из них не должна влиять на выполнение других.

Каждый из этих контекстов будет динамически вызывать код, который охватывает несколько единиц перевода (TU). некоторые единицы перевода могут быть общими для многих из этих контекстов. ошибки компиляции в новой или измененной единице перевода не должны влиять на другие контексты.

Уточнение Править: Например, Т.У. A может быть разделен между двумя контекстами, контекстом X и Y. Просто для того, чтобы получить полную картину, предположим, что X также будет выполнять код из других единиц перевода, то есть B и D, в то время как Y будет также иметь C. В В какой-то момент X решает внести изменения в A, поэтому он создает новую ЕП A.1, которая является копией A, и применяет там изменения, поэтому они не повлияют на контекст Y. Надеюсь, что этот пример проясняет требование.

Моим первоначальным побуждением было связать по одному llvm::Moduleдля каждого контекста, но поскольку в LLVM не определено, что происходит с модулем в промежуточном состоянии компиляции, я решил добавить один llvm::Moduleдля каждой единицы перевода (см. этот вопрос по причине), а также политику копирования при записи, которую я объяснил ранее, когда модификации единицы перевода происходят локально в контексте, во избежание изменения, влияющего на другие контексты.

У меня есть главный двойной вопрос:

  • Как связать вместе разные модули в контексте, чтобы вызывать их как единую библиотеку? Я использую С++ API. Я особенно опасаюсь этой неприятной старой ошибки, влияющей на эту функциональность. Будет ли эта ошибка влиять на меня, если я передам право собственности на все модули JIT с помощью ExecutionEngine::addModule()?

  • Какие действия необходимо выполнить, если модификация единицы перевода вызывает обновление одного из модулей? мне нужно удалить/удалить старый объект модуля и создать новый? есть ли политика утилизации, о которой я не читал?

Второстепенный вопрос, который у меня есть по этому поводу:

  • Сколько ExecutionEngineмне нужно? один на все приложение? по одному контексту? по одному на модуль?

Надеюсь, объем вопроса не слишком велик.

62
задан Community 23 May 2017 в 11:54
поделиться