c++ - 如何根据 LLVM 中 LoadInst 的结果解析 AllocaInst?

标签 c++ compiler-construction llvm

从概念上讲,我想做的事情非常简单。我正在使用 Alloca technique described in the Kaleidoscope examplemem2reg 配对以减少手动创建 Phi 节点的需要。

我已经实现了我的自定义语言的几个方面,但是我遇到了以通用方式实现后递增/递减的问题。

我的 AST 节点 PostIncrDecrNode 包含一个标记来表示 ++-- 和一个表达式 AST 节点,该节点被代码生成以返回一个 llvm::Value* 很像 Kaleidoscope 的例子。我已经注意到我可能需要返回 llvm::Value* 以外的东西,因为我的语言是非常类型安全的,我需要知道诸如整数类型的符号性之类的东西,但现在我觉得我可能还需要跟踪 llvm::AllocaInst

一个简单的示例情况是这样的代码:

int myfunction(int i)
{
    return i++;
}

我的调试 AST 输出如下所示:

- CompilationUnit:test.str
    - FunctionDeclarationNode
        - IdentifierNode:int
        - IdentifierNode:myfunction
        - FunctionParameterNode
            - IdentifierNode:int
            - IdentifierNode:i
        - BlockNode
            - ReturnNode
                - PostIncrDecrNode
                    - IdentifierNode:i

最后两行是这里的相关部分,因为我有一个 PostIncrDecrNode,其中包含一个 IdentifierNode,它将像这样进行代码生成:

Value* IdentifierNode::codeGenInternal(CodeGenContext& context)
{
    Value* rtn = NULL;
    SharedSymbolEntry entry = context.getSymbolInScopeByName(*value);
    Value* val = entry ? entry->llvmVal : NULL;
    if(val)
    {
        IRBuilder<>* builder = context.getIRBuilder();
        rtn = builder->CreateLoad(val, value->c_str());
    }
    else
    {
        context.handleCodeGenError(*this, "Unknown variable name: " + Twine(value->c_str()));

    }
    return rtn;
}

SharedSymbolEntry entry = context.getSymbolInScopeByName(*value); 使用存储的 shared_ptrstd::String 'value' 成员IdentifierNode(又名变量名)来查找我的SharedSymbolEntry(只是一个包装器类型,用于存储语言特定信息以及 llvm::Value* 是上下文堆栈中的 llvm::AllocaInst*),它由函数参数或变量 AST 节点填充入口 block 分配。

问题是 PostIncrDecrNode 无法访问 alloca,只有从加载 rtn = builder- 返回的 llvm::Value* >CreateLoad(val, value->c_str());.

在 LLVM 中是否有任何方法可以从 llvm::Value* 解析 llvm::AllocaInst* 以便在存储指令中使用它(存储指令需要一个指针,在这种情况下我只有整数值)?

我遇到了几个类似的问题,但我不确定它们是否回答了我的问题。 最后一个似乎表明这可能根本不可能,所以我很好奇其他人是如何解决这个问题的。

最佳答案

当您返回一个 llvm::Value*(在您的例子中它是一个 LoadInst*)时,您可以转换 llvm:Value*llvm::LoadInst* 使用 LLVM RTTI 系统,如下所示:

Value* val = someFunction(...); 
if (llvm::LoadInst* I = dyn_cast<llvm::LoadInst>(val)
{
     // do something with the load instruction I
}
else // not a load instruction

当您拥有 llvm::LoadInst* 时,您可以使用 getPointerOperand() 轻松访问发生加载的地址。 现在您可以尝试将指针操作数转换回 AllocaInst*,如上例所示。如果它成功,你有你的 AllocaInst,当它失败时它是别的东西(例如 GetElementPtrInst)。

关于c++ - 如何根据 LLVM 中 LoadInst 的结果解析 AllocaInst?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34440614/

相关文章:

optimization - clang -O1 和 opt -O1 有什么区别?

c++ - 无法运行在 Windows 10 上使用 MinGW 构建的 Clang 调试版本

c++ - RedHat 上 GCC 4.4.5 中的运行时问题,但在 Apple llvm 4.2 上运行正常?

c++ - 无法在 Watch 窗口中计算具有重载运算符的表达式

c++ - 如何获取所有可用的事件日志名称?

macos - Qt5 "symbol(s) not found for architecture x86_64"

C#编译器和局部变量的缓存

c++ - 我在 C++ 中看到了以下代码。它是定义的行为吗?

c++ - 遍历 Base 类型的 vector 和/或从 base 派生的类型

c# - 为什么我会收到此定义引用错误?