何时加载,存储和分配在LLVM中使用

时间:2018-05-25 22:43:48

标签: c llvm

我正在查看LLVM,了解他们如何使用loadstorealloca。在下面的第一张幻灯片中,没有使用它们。在第二种情况下,使用alloca

我不熟悉C所以必须让自己加快速度以便运行一个例子并自己解决这个问题,但是想知道是否有人已经知道了。不确定要编写的示例C代码的类型,以确定在LLVM中使用loadstorealloca的输出。

问题是,当LLVM使用loadstorealloca时。

想知道是否还需要加载/存储,或者LLVM可以不加载它。

图1↓

enter image description here

图2↓

enter image description here

2 个答案:

答案 0 :(得分:2)

如果没有优化,clang将生成LLVM代码,每个局部变量只有一个alloca,每个使用该变量一个read作为r值,{{1}对于该变量的每个赋值(包括其初始化)。

通过优化,clang将尽量减少storeread的数量,并且如果可能的话,通常会完全消除store(仅使用寄存器)。

确保变量存储在内存中的一种方法,即使是优化,也可以采用其地址(因为寄存器不具有地址)。

  

想知道是否还需要加载/存储,或者LLVM可以不加载它。

每当您写入内存位置时,您都需要alloca / store。所以问题就变成你是否可以没有记忆,将所有东西存储在寄存器中。由于LLVM(与真实机器不同)支持无限量的寄存器,因此这是一个有效的问题。

然而,正如我所提到的,登记册没有地址。因此,任何获取变量地址的代码都需要使用内存。任何对地址执行算术的代码也是如此,例如索引数组的代码。

答案 1 :(得分:1)

alloca在函数的本地帧中分配内存。有必要创建一个地址被采用的变量,如下例所示:

void foo(int* ptr) {
    *ptr = 4;
}

int main() {
    int value = 0;
    foo(&value);
    printf("%i\n", value); // 4
}

如果它不是内联foo,则LLVM将需要alloca中的main指令来创建支持value变量的内存。 foo需要使用store将4放在ptr指向的地址,然后main需要使用load来加载value的内容1}}之后被foo修改。

C系列语言的编译器通常更喜欢使用alloca为函数框架中的每个变量开始,然后让LLVM将alloca优化为SSA值。在许多情况下,编译器能够将alloca ted变量提升为SSA值,如ssa2函数所示。 SSA表单能够表示满足以下两个条件的变量:

  • 他们的地址未被采纳
  • 他们的尺寸是固定的

变量的“获取地址”是Javascript / Ruby中不存在的操作,因此您可能需要快速了解C以了解它的含义。它在C和C ++中非常常见。

“固定大小”表示编译器提前知道特定数据结构需要多少内存。例如,它总是知道简单的整数,但数组通常具有可变的大小。可以使用allocamalloc分配在运行时未知的大小的数组,然后您需要使用loadstore访问其内容。

最后,请注意您的第二个示例已损坏:它从未初始化的值读取,如果您在更高的优化级别进行编译,则只需获取ret i32 undef