我正在查看LLVM,了解他们如何使用load
,store
和alloca
。在下面的第一张幻灯片中,没有使用它们。在第二种情况下,使用alloca
。
我不熟悉C所以必须让自己加快速度以便运行一个例子并自己解决这个问题,但是想知道是否有人已经知道了。不确定要编写的示例C代码的类型,以确定在LLVM中使用load
,store
和alloca
的输出。
问题是,当LLVM使用load
,store
和alloca
时。
想知道是否还需要加载/存储,或者LLVM可以不加载它。
图1↓
图2↓
答案 0 :(得分:2)
如果没有优化,clang将生成LLVM代码,每个局部变量只有一个alloca
,每个使用该变量一个read
作为r值,{{1}对于该变量的每个赋值(包括其初始化)。
通过优化,clang将尽量减少store
和read
的数量,并且如果可能的话,通常会完全消除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 ++中非常常见。
“固定大小”表示编译器提前知道特定数据结构需要多少内存。例如,它总是知道简单的整数,但数组通常具有可变的大小。可以使用alloca
或malloc
分配在运行时未知的大小的数组,然后您需要使用load
和store
访问其内容。
最后,请注意您的第二个示例已损坏:它从未初始化的值读取,如果您在更高的优化级别进行编译,则只需获取ret i32 undef
。