2

目前,我正在使用 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++ 函数的调用点抛出,所以不,在我的情况下,无知是幸福,除非我更好地理解它们,否则我想远离内在的 llvm 异常)。

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

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

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

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

1 回答 1

2

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

您可以直接使用 alloca 的地址……但是,没有任何简单的方法可以将其偏移量放入堆栈帧。

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

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

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

真的没那么复杂。

于 2011-09-23T19:10:38.360 回答