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

时间:2015-12-23 17:11:13

标签: c++ compiler-construction llvm

从概念上讲,我想做的事情非常简单。我使用与Alloca technique described in the Kaleidoscope example配对的mem2reg来减少手动创建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_ptr的{​​{1}} std::String'值'成员(又称变量名称)来查找我的IdentifierNode (只是一个包装器类型,用于在上下文堆栈中存储语言特定信息以及SharedSymbolEntry llvm::Value*),该堆栈由函数参数或变量AST节点填充入口块分配。

问题是,llvm::AllocaInst*无法访问alloca,只能访问负载PostIncrDecrNode中返回的llvm::Value*

LLVM中是否有任何方法可以解析rtn = builder->CreateLoad(val, value->c_str());中的llvm::AllocaInst*以便在存储指令中使用它(存储指令需要一个指针,在这种情况下我只有整数值) )?

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

1 个答案:

答案 0 :(得分:1)

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