如何从LLVM中LoadInst的结果值中解析AllocaInst

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

本文关键字:AllocaInst 结果 LoadInst LLVM      更新时间:2023-10-16

从概念上讲,我想做的事情非常简单。我使用Kaleidoscope示例中描述的Alloca技术与mem2reg配对,以减少手动创建Phi节点的需要。

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

我的AST节点PostIncrDecrNode包含一个表示++--的令牌,以及一个编码为返回llvm::Value*的表达式AST节点,非常类似于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

最后两行是这里的相关部分,因为我有一个包含IdentifierNodePostIncrDecrNode,它将被编码如下:

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);使用存储的IdentifierNodeshared_ptrstd::String"值"成员(也称为变量名)在上下文堆栈中查找我的SharedSymbolEntry(只是一种包装类型,用于存储语言特定信息以及llvm::Value*,即llvm::AllocaInst*),该上下文堆栈由函数参数或变量AST节点分配的入口块填充。

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

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

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

  • llvm依赖项分配加载
  • llvm-pass-how-to-insert-a-variable使用-eisting-variable值
  • 获取指向先前为createload函数分配的llvmvalue的指针

当您返回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)。