llvm:指针操作的值

llvm:指针操作的值,llvm,Llvm,我试着学习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 stor

我试着学习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开始变量。这里有什么区别
  • 我看到正在定义的下一个变量是%2,这意味着跳过了%1。我注意到这样做(跳过)会导致编译错误。那么,这个代码是如何有效的呢
  • 这段代码的实际逻辑是什么?为什么涉及存储指令和i32**类型?有没有更简单的方法在llvm中实现“get value of”操作
  • 存储操作引用的%0是什么?这是指函数参数吗?我遇到的所有其他函数都以%1而不是%0开始变量。这里有什么区别
  • 在LLVM中,函数定义包含基本块列表,可以选择以标签开头。如果未提供显式标签,则从未命名临时表中使用的相同计数器提供隐式编号标签

  • 我看到正在定义的下一个变量是%2,这意味着跳过了%1。我注意到这样做(跳过)会导致编译错误。那么,这个代码是如何有效的呢
  • 此代码有效,因为%0隐式用于参数,%1用于标记basicBlock,如果您遇到任何问题,请发布错误消息

  • 这段代码的实际逻辑是什么?为什么涉及存储指令和i32**类型?有没有更简单的方法在llvm中实现“get value of”操作
  • 我不是专家,但优化是llvm的责任。为了更简单地使用

    define i32 @getVal(i32*) #0 {
      %2 = load i32, i32* %0
      ret i32 %2
    }
    
    如果您想了解有关LLVM语言的更多信息,可以使用一个非常好的文档


    还有我列出的要点,您可以在函数、标识符部分中找到

    多谢各位。这回答了我所有的问题!