2009-02-02 5 views
7

В LLVM учебники и примеры, компилятор выводит LLVM IR, делая звонки, как этотКак бы вы повторно использовали реализации кода op при записи JIT с LLVM?

return Builder.CreateAdd(L, R, "addtmp"); 

но многие переводчики записываются так:

switch (opcode) { 
    case ADD: 
      result = L + R; 
      break; 
    ... 

Как бы вы извлечь каждый из этих фрагментов кода сделать JIT с LLVM без необходимости повторной реализации каждого кода операции в LLVM IR?

ответ

9

Хорошо, сначала возьмите все фрагменты кода и переформатируйте их в свои собственные функции. Таким образом, ваш код идет по адресу:

void addOpcode(uint32_t *result, uint32_t L, uint32_t R) { 
    *result = L + R; 
} 

switch (opcode) { 
    case ADD: 
      addOpcode(&result, L, R); 
      break; 
    .... 

Хорошо, поэтому после этого ваш переводчик должен все еще работать. Теперь возьмите все новые функции и поместите их в свой собственный файл. Теперь скомпилируйте этот файл с помощью llvm-gcc или clang и вместо того, чтобы генерировать собственный код, скомпилируйте его с помощью "cpp" backend (-march -cpp). Это создаст код C++, который создает код байта для блока компиляции. Вы можете указать параметры, чтобы ограничить его конкретными функциями и т. Д. Возможно, вы захотите использовать «-cppgen module».

Теперь вернемся к тому, что ваш цикл интерпретатора соединяет вызовы сгенерированного кода на C++ вместо прямого выполнения исходного кода, а затем передает его некоторым оптимизаторам и родному кодегенератору. Gratz на JIT ;-) Вы можете увидеть пример этого в нескольких проектах LLVM, таких как vm_ops в llvm-lua.

+0

Замечательно! Я думал, что это будет что-то вроде этого, с LLVM, в котором будут вложены все функции. – joeforker

+0

Как это соотносится с интерпретатором с перекрестными ссылками, где вы только JIT серии инструкций CALL для каждой реализации байт-кода, встраиваете реализацию только нескольких опкодов, скорее всего, коды BRANCH, и каждая реализация кода операции заканчивается с помощью RET? – joeforker

+0

Я не совсем понимаю это. Вы хотите передать все функции opcode в LLVM, и когда вы вернете его обратно на C, у него автоматически будет встроенный JIT? – Unknown