【问题标题】:llvm: value of pointer operationllvm:指针操作的值
【发布时间】:2019-01-18 11:44:50
【问题描述】:

我尝试学习 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 代码的问题:

  1. 存储操作所指的 %0 是什么?这是指函数参数吗?我遇到的所有其他函数都以 %1 开头,而不是 %0。这里有什么区别?
  2. 我看到定义的下一个变量是 %2,这意味着 %1 被跳过。而且我注意到这样做(跳过)会导致编译错误。那么这段代码是如何有效的呢?
  3. 这段代码的实际逻辑是什么?为什么会涉及到 store 指令和 i32** 类型?有没有更简单的方法在 llvm 中实现“get value of”操作?

【问题讨论】:

    标签: llvm


    【解决方案1】:
    1. 存储操作所指的 %0 是什么?这是指函数参数吗?我遇到的所有其他函数都以 %1 开头,而不是 %0。这里有什么区别?

    在 LLVM 函数定义中包含基本块列表,可以选择以标签开头。如果未提供显式标签,则从与未命名临时文件中使用的相同计数器提供隐式编号标签。

    1. 我看到定义的下一个变量是 %2,这意味着 %1 被跳过。而且我注意到这样做(跳过)会导致编译错误。那么这段代码是如何有效的呢?

    此代码有效,因为 %0 隐式用于参数,%1 用于标记基本块,如果您遇到任何问题,请发布错误消息。

    1. 这段代码的实际逻辑是什么?为什么涉及存储指令和 i32** 类型?有没有更简单的方法在 llvm 中实现“get value of”操作?

    我不是一个clang专家,但优化是llvm的责任。为了更简单的使用方式,

    define i32 @getVal(i32*) #0 {
      %2 = load i32, i32* %0
      ret i32 %2
    }
    

    如果您想了解有关 LLVM 语言的更多信息,可以使用非常好的文档。 LLVM Lang Ref

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

    【讨论】:

    • 非常感谢。这回答了我所有的问题!
    猜你喜欢
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多