gpt4 book ai didi

compiler-construction - LLVM alloca 导致 while 语句上的堆栈溢出

转载 作者:行者123 更新时间:2023-12-04 04:14:31 24 4
gpt4 key购买 nike

我正在为面向 LLVM-IR 的玩具语言实现前端编译器,并且在运行编译时遇到堆栈溢出 while声明:

例如,这段代码应该永远运行,但我们编译的版本在一段时间后堆栈溢出。

def run(): Void = {
i = 0;
while(true) {
i = i + 1;
}
}

这是编译好的 LLVM-IR:
define i32 @run() nounwind ssp {
; i = 0
%i = alloca i32, align 4
%1 = alloca i32, align 4
store i32 0, i32* %1, align 4
%2 = load i32* %1, align 4
store i32 %2, i32* %i, align 4
br label %3

; <label>: %3
; while(true)
; Generated by compileExpression(condition)
%4 = alloca i1, align 4
store i1 true, i1* %4, align 4
%5 = load i1* %4, align 4
br i1 %5, label %6, label %11

; <label>: %6
; i = i + 1
; Generated by compileExpression(body)
%7 = load i32* %i, align 4
%8 = alloca i32, align 4
store i32 1, i32* %8, align 4
%9 = load i32* %8, align 4
%10 = add nsw i32 %7, %9
store i32 %10, i32* %i, align 4
br label %3

; <label>: %11
%12 = load i32* %i, align 4
ret i32 %12
}

我们认为我们的问题来自每个 alloca没有被释放,因为我们仍然在同一个函数中。

LLVM Documentation :

'alloca'd memory is automatically released when the function returns.



我们应该如何编译while循环?
我们能避免这个问题吗?

最佳答案

你产生了不好的 IR:特别是,alloca在循环中是一个坏主意,确实会导致堆栈溢出。

我希望看到的是 alloca在循环之外,然后是 load , addstore循环内的序列。稍后您可以运行 mem2reg pass,这将消除 alloca s 并转换 loadstore更高效 phi .

您的 alloca 也是如此对于while条件:你需要做同样的事情,提前准备内存并且只在循环内部store到它。

关于compiler-construction - LLVM alloca 导致 while 语句上的堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21025099/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com