LLVM API:创建ispose的正确方法

问题描述 投票:5回答:2

我正试图使用LLVM C API实现一个简单的JIT编译器。到目前为止,我在生成IR代码并执行它方面没有任何问题,也就是说:直到我开始处置对象并重新创建它们。

我基本上想做的是在JIT'ted资源不再被引擎使用的那一刻将其清理掉。我基本上试图做的是这样的事情。

while (true)
{
    // Initialize module & builder
    InitializeCore(GetGlobalPassRegistry());
    module = ModuleCreateWithName(some_unique_name);
    builder = CreateBuilder();

    // Initialize target & execution engine
    InitializeNativeTarget();
    engine = CreateExecutionEngineForModule(...);
    passmgr = CreateFunctionPassManagerForModule(module);
    AddTargetData(GetExecutionEngineTargetData(engine), passmgr);
    InitializeFunctionPassManager(passmgr);

    // [... my fancy JIT code ...] --** Will give a serious error the second iteration

    // Destroy
    DisposePassManager(passmgr);
    DisposeExecutionEngine(engine);
    DisposeBuilder(builder);
    // DisposeModule(module); //--> Commented out: Deleted by execution engine

    Shutdown();
}

然而,这似乎并不正确: 循环的第二次迭代,我得到了一个非常糟糕的错误... ...

所以总结一下:销毁和重新创建LLVM API的正确方法是什么?

llvm dispose
2个回答
3
投票

因为代码太长了,所以把它作为Answer发布。如果可能且没有其他限制条件,可以尝试使用LLVM这样的方式。我很确定 Shutdown() 循环内是罪魁祸首。而且我不认为这将会伤害到保持的。Builder 外,也是。这很好地反映了我在JIT中使用LLVM的方式。

InitializeCore(GetGlobalPassRegistry());
InitializeNativeTarget();
builder = CreateBuilder();

while (true)
{
    // Initialize module & builder

    module = ModuleCreateWithName(some_unique_name);


    // Initialize target & execution engine
    engine = CreateExecutionEngineForModule(...);
    passmgr = CreateFunctionPassManagerForModule(module);
    AddTargetData(GetExecutionEngineTargetData(engine), passmgr);
    InitializeFunctionPassManager(passmgr);

    // [... my fancy JIT code ...] --** Will give a serious error the second iteration

    // Destroy
    DisposePassManager(passmgr);
    DisposeExecutionEngine(engine);             
}
DisposeBuilder(builder);
Shutdown();

0
投票
  /* program init */
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
LLVMLinkInMCJIT();





    ctx->context = LLVMContextCreate();
    ctx->builder = LLVMCreateBuilderInContext(ctx->context);
    LLVMParseBitcodeInContext2(ctx->context, module_template_buf, &module) // create module

    do IR code creation
    {
        function = LLVMAddFunction(ctx->module, "my_func")
        LLVMAppendBasicBlockInContext(ctx->context, ...
        LLVMBuild...
        ...
    }
    optional optimization
    {
        LLVMPassManagerBuilderRef pass_builder = LLVMPassManagerBuilderCreate();
        LLVMPassManagerBuilderSetOptLevel(pass_builder, 3);
        LLVMPassManagerBuilderSetSizeLevel(pass_builder, 0);
        LLVMPassManagerBuilderUseInlinerWithThreshold(pass_builder, 1000);
        LLVMPassManagerRef function_passes = LLVMCreateFunctionPassManagerForModule(ctx->module);
        LLVMPassManagerRef module_passes = LLVMCreatePassManager();
        LLVMPassManagerBuilderPopulateFunctionPassManager(pass_builder, function_passes);
        LLVMPassManagerBuilderPopulateModulePassManager(pass_builder, module_passes);
        LLVMPassManagerBuilderDispose(pass_builder);
        LLVMInitializeFunctionPassManager(function_passes);
        for (LLVMValueRef value = LLVMGetFirstFunction(ctx->module); value;
             value = LLVMGetNextFunction(value))
        {
            LLVMRunFunctionPassManager(function_passes, value);
        }
        LLVMFinalizeFunctionPassManager(function_passes);
        LLVMRunPassManager(module_passes, ctx->module);
        LLVMDisposePassManager(function_passes);
        LLVMDisposePassManager(module_passes);
    }

    optional for debug
    {
        LLVMVerifyModule(ctx->module, LLVMAbortProcessAction, &error);
        LLVMPrintModule
    }
    if (LLVMCreateJITCompilerForModule(&ctx->engine, ctx->module, 0, &error) != 0)
    my_func = (exec_func_t)(uintptr_t)LLVMGetFunctionAddress(ctx->engine, "my_func");

    LLVMRemoveModule(ctx->engine, ctx->module, &ctx->module, &error);
    LLVMDisposeModule(ctx->module);
    LLVMDisposeBuilder(ctx->builder);

    do
    {
         my_func(...);
    }

    LLVMDisposeExecutionEngine(ctx->engine);
    LLVMContextDispose(ctx->context);



/* program finit */
LLVMShutdown();
© www.soinside.com 2019 - 2024. All rights reserved.