我尝试使用llvm汇编语言。 由于我没有找到任何教程,因此我的学习方法是编写简单的C函数,然后让clang通过以下方式显示相应的llvm代码:
clang -S -emit-llvm simple.c
我现在正在尝试学习如何使用指针。所以我测试了以下C函数:
int getVal(int* ptr) { return *ptr; }
生成了以下llvm:
define i32 @getVal(i32*) #0 {
%2 = alloca i32*, align 8
store i32* %0, i32** %2, align 8
%3 = load i32*, i32** %2, align 8
%4 = load i32, i32* %3, align 4
ret i32 %4
}
我对llvm代码的疑问:
答案 0 :(得分:1)
- 存储操作所引用的%0是什么?这是指函数参数吗?我遇到的所有其他函数均以%1(而非%0)开头。这里有什么区别?
在LLVM函数定义中包含basicBlocks列表,可以选择以标签开头。如果未提供显式标签,则从与未命名临时文件使用的计数器相同的计数器提供隐式编号的标签。
- 我看到定义的下一个变量是%2,这意味着%1被跳过。而且我注意到这样做(跳过)会导致编译错误。那么这段代码是如何有效的呢?
此代码有效,因为%0隐式用作参数,%1用于标记basicBlock,如果遇到任何问题,请张贴错误消息。
- 此代码的实际逻辑是什么?为什么要涉及存储指令和i32 **类型?有没有更简单的方法在llvm中实现“获取值”操作?
我不是一个lang语专家,但是优化是llvm的责任。为了更简单的使用方式,
define i32 @getVal(i32*) #0 {
%2 = load i32, i32* %0
ret i32 %2
}
如果您想了解有关LLVM lang的更多信息,可以使用非常好的文档。 above
我列出的要点也可以在“功能”,“标识符”部分中找到。