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

How to resolve AllocaInst from a Value that was a result of a LoadInst in LLVM?

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

我已经实现了我的自定义语言的几个方面,但是我 运行 遇到了以通用方式实现 post increment/decrement 的问题。

我的 AST 节点 PostIncrDecrNode 包含一个标记来表示 ++-- 和一个代码生成为 return 和 llvm::Value* 的表达式 AST 节点就像万花筒的例子。我已经注意到我可能需要 return 除了 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 节点分配的入口块填充。

问题是 PostIncrDecrNode 无法访问 alloca,只有 returned llvm::Value* 来自负载 rtn = builder->CreateLoad(val, value->c_str());.

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

我 运行 进入了几个类似的问题,但我不确定他们是否回答了我的问题。 最后一个似乎暗示这可能根本不可能,所以我很好奇其他人是如何解决这个问题的。

当您返回 llvm::Value*(在您的情况下是 LoadInst*)时,您可以使用 LLVM RTTI 系统将 llvm:Value* 转换为 llvm::LoadInst*这个:

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)。