Почему LLVMRunFunction с интерпретатором возвращает одно и то же значение для разных функций? - PullRequest
0 голосов
/ 13 января 2019

Я строю 2 функции, используя LLVM C API. Каждый возвращает различный указатель на глобальную строку («первое» и «второе»). Однако, когда я запускаю каждый с LLVMRunFunction с использованием интерпретатора LLVM, они оба возвращают указатель на строку «first».

Проблема не возникает, когда я возвращаю целые числа или указатели на функции. Я попытался просмотреть полученный код llvm, и это правильно, каждая функция возвращает свой указатель.

Вот пример, который воспроизведет проблему (на LLVM 7.0.1)

#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>
#include <stdio.h>

int main() {
    auto module = LLVMModuleCreateWithName("test");
    LLVMExecutionEngineRef interpreter;
    LLVMCreateInterpreterForModule(&interpreter, module, nullptr);
    auto funType = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), nullptr, 0, 0);
    auto fun = LLVMAddFunction(module, "fun1", funType);
    auto builder = LLVMCreateBuilder();
    auto entry = LLVMAppendBasicBlock(fun, "entry");
    LLVMPositionBuilderAtEnd(builder, entry);
    LLVMBuildRet(builder, LLVMBuildGlobalStringPtr(builder, "first", ""));
    auto generic = LLVMRunFunction(interpreter, fun, 0, nullptr);
    printf("%s\n", (const char*)LLVMGenericValueToPointer(generic));
    fun = LLVMAddFunction(module, "fun2", funType);
    entry = LLVMAppendBasicBlock(fun, "entry");
    LLVMPositionBuilderAtEnd(builder, entry);
    LLVMBuildRet(builder, LLVMBuildGlobalStringPtr(builder, "second", ""));
    generic = LLVMRunFunction(interpreter, fun, 0, nullptr);
    printf("%s\n", (const char*)LLVMGenericValueToPointer(generic));
    return 0;
}

Я бы ожидал выход

first
second

Вместо этого выводит

first
first

1 Ответ

0 голосов
/ 27 января 2019

После более внимательного изучения сгенерированного LLVM я заметил, что глобальные строки, созданные с помощью LLVMBuildGlobalStringPtr, имеют модификатор unnamed_addr. При построении глобальной строки вручную вместо использования LLVMBuildGlobalStringPtr интерпретатор фактически возвращает правильные строковые указатели, и выходные данные становятся такими, как ожидалось:

auto glbstr = LLVMAddGlobal(mBuilder.module_, llvmType, "glbstr");
LLVMSetInitializer(glbstr, LLVMConstString(toStringz(arg.value), cast(uint) arg.value.length, 0));
auto firstCharPtr = LLVMBuildGEP(builder, glbstr, [LLVMConstInt(LLVMInt8Type(), 0, 0), LLVMConstInt(LLVMInt8Type(), 0, 0)].ptr, 2, "");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...