如何根据 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_ptr
到 std::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-dependencies-alloca-load
- llvm-pass-how-to-insert-a-variable-using-existing-variable-value
- get-pointer-to-llvmvalue-previously-allocated-for-createload-function
当您返回 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
)。
从概念上讲,我想做的事情非常简单。我正在使用 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_ptr
到 std::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-dependencies-alloca-load
- llvm-pass-how-to-insert-a-variable-using-existing-variable-value
- get-pointer-to-llvmvalue-previously-allocated-for-createload-function
当您返回 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
)。