【问题标题】:LLVM exceptions; how to unwindLLVM 异常;如何放松
【发布时间】:2011-09-23 15:55:43
【问题描述】:

目前,我正在使用 CreateEntryBlockAlloca 将变量插入块范围的开头:

template <typename VariableType>
            static inline llvm::AllocaInst *CreateEntryBlockAlloca(BuilderParameter& buildParameters,
                    const std::string &VarName) {
                HAssertMsg( 1 != 0 , "Not Implemented");
            };

            template <>
              inline llvm::AllocaInst *CreateEntryBlockAlloca<double>(BuilderParameter& buildParameters,
                    const std::string &VarName) {
                llvm::Function* TheFunction = buildParameters.dag.llvmFunction;
                llvm::IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
                        TheFunction->getEntryBlock().begin());
                return TmpB.CreateAlloca(llvm::Type::getDoubleTy(buildParameters.getLLVMContext()), 0,
                        VarName.c_str());
            }

现在,我想为非 POD 类型添加 Allocas(可能需要在退出时使用析构函数/清理函数)。但是,在退出范围块的末尾添加析构函数调用是不够的,因为不清楚如何在抛出常规 DWARF 异常时调用它们(为了这个参数的目的,假设异常是从调用仅抛出 POD 类型的 C++ 函数的调用点抛出,所以不,在我的情况下,无知是幸福,我想远离 intrinsic llvm exceptions,除非我更了解它们)。

我在想可能我可以在堆栈中有一个带有 Alloca 寄存器的偏移量的表,并让异常处理程序(在堆栈底部,在 JIT 函数的调用点)遍历这些偏移量放在桌子上并适当地调用析构函数。

我不知道的是如何查询使用 CreateAlloca 创建的 Alloca'ed 寄存器的偏移量。 我怎样才能可靠地做到这一点?

另外,如果您认为有更好的方法可以实现这一点,请在llvm的路径上赐教

  • 技术评论:JIT 代码在 boost::context 中被调用,它只在 try catch 中调用 JIT 代码,并且对 catch 不做任何事情,它只是从上下文中退出并返回到 main执行栈。这个想法是,如果我在主执行堆栈中处理展开,我调用的任何函数(例如,清理堆栈变量)都不会从终止的 JIT 上下文中覆盖那些相同的堆栈内容,因此它不会被破坏。希望我有足够的意义

【问题讨论】:

    标签: c++ exception-handling llvm jit dwarf


    【解决方案1】:

    我不知道的是如何查询使用 CreateAlloca 创建的 Alloca'ed 寄存器的偏移量。我怎样才能可靠地做到这一点?

    您可以直接使用 alloca 的地址...不过,没有任何简单的方法可以将其偏移量获取到堆栈帧中。

    为什么你不想使用内在的 LLVM 异常?它们确实并不难使用,尤其是在您的代码实际上从未捕获任何东西的简单情况下。您基本上可以将clang在简单情况下生成的代码复制粘贴。

    编辑: 要了解如何在简单情况下使用 IR 中的异常,请尝试将以下 C++ 代码粘贴到 http://llvm.org/demo/ 的演示页面中:

    class X { public: ~X() __attribute((nothrow)); };
    void a(X* p);
    void b() { X x; a(&x); }
    

    其实没那么复杂。

    【讨论】:

    • 原因是这样的;我不知道在哪里以及如何构建析构函数 IR 代码,以便在每次展开帧时调用它们
    • 我已经更新了我的答案,尝试展示如何正确构建 IR。
    • 请给我解释一下;如果正在调用 b,则调用 a 并引发异常; b 帧展开后要调用 @X::~X() 的代码在哪里?我不确定如何从 API 级别执行此操作
    • 更准确地说,我如何在 b 的末尾创建 'to label %3 unwind label %4' 部分?
    • 该演示页面当前已失效(好吧,已禁用)。
    猜你喜欢
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    相关资源
    最近更新 更多