LLVM 'ret' 指令
LLVM 'ret' instructions
我已经学习了 LLVM 教程 Kaleidoscope。现在我正在尝试将这个前端编译器外部化为类似于 Pascal 的语言。我有这个代码:
program main;
function rett(): integer;
begin
rett := 1;
exit;
rett := 5;
end;
var a: integer;
begin
a := rett();
writeln(a);
end.
这个程序的输出应该是一个整数“1”,因为有退出命令(所以行 rett := 5;
应该不会被执行)。但是输出是“5”。对于这个输入,我生成了这个 LLVM IR:
define i32 @rett() {
entry:
%rett = alloca i32
store i32 0, i32* %rett
store i32 1, i32* %rett
%rett1 = load i32, i32* %rett
ret i32 %rett1
store i32 5, i32* %rett
%rett2 = load i32, i32* %rett
ret i32 %rett2
}
define i32 @main() {
entry:
%a = alloca i32
%main = alloca i32
store i32 0, i32* %main
store i32 0, i32* %a
%calltmp = call i32 @rett()
store i32 %calltmp, i32* %a
%a1 = load i32, i32* %a
%calltmp2 = call i32 (i8*, ...) @printf([4 x i8]* @.str, i32 %a1)
%main3 = load i32, i32* %main
ret i32 %main3
}
为什么不执行第一个'ret'命令?有什么我想念的吗?
更新:
在文档中写道:
Each basic block may optionally start with a label (giving the basic block a symbol table entry), contains a list of instructions, and ends with a terminator instruction (such as a branch or function return).
这是否意味着"terminator"指令只能在基本块的末尾?如果是,我应该如何为我的语言实施 return 和 break 命令?
我无法重现问题(您的示例输出 1
),但无论如何我都会回答问题。
Is that mean that a "terminator" instruction can by only at the end of basic block?
没错。实际上,opt
显示您示例中的 @rett
函数由以下两个基本块组成:
And if yes how should I implement return and break command for my language?
有 ret
和 br
。
您永远不需要在基本块中生成终止符,因为正如您所指出的,任何经过它的指令都不会执行,因此您最好不要生成它们。
我已经学习了 LLVM 教程 Kaleidoscope。现在我正在尝试将这个前端编译器外部化为类似于 Pascal 的语言。我有这个代码:
program main;
function rett(): integer;
begin
rett := 1;
exit;
rett := 5;
end;
var a: integer;
begin
a := rett();
writeln(a);
end.
这个程序的输出应该是一个整数“1”,因为有退出命令(所以行 rett := 5;
应该不会被执行)。但是输出是“5”。对于这个输入,我生成了这个 LLVM IR:
define i32 @rett() {
entry:
%rett = alloca i32
store i32 0, i32* %rett
store i32 1, i32* %rett
%rett1 = load i32, i32* %rett
ret i32 %rett1
store i32 5, i32* %rett
%rett2 = load i32, i32* %rett
ret i32 %rett2
}
define i32 @main() {
entry:
%a = alloca i32
%main = alloca i32
store i32 0, i32* %main
store i32 0, i32* %a
%calltmp = call i32 @rett()
store i32 %calltmp, i32* %a
%a1 = load i32, i32* %a
%calltmp2 = call i32 (i8*, ...) @printf([4 x i8]* @.str, i32 %a1)
%main3 = load i32, i32* %main
ret i32 %main3
}
为什么不执行第一个'ret'命令?有什么我想念的吗?
更新: 在文档中写道:
Each basic block may optionally start with a label (giving the basic block a symbol table entry), contains a list of instructions, and ends with a terminator instruction (such as a branch or function return).
这是否意味着"terminator"指令只能在基本块的末尾?如果是,我应该如何为我的语言实施 return 和 break 命令?
我无法重现问题(您的示例输出 1
),但无论如何我都会回答问题。
Is that mean that a "terminator" instruction can by only at the end of basic block?
没错。实际上,opt
显示您示例中的 @rett
函数由以下两个基本块组成:
And if yes how should I implement return and break command for my language?
有 ret
和 br
。
您永远不需要在基本块中生成终止符,因为正如您所指出的,任何经过它的指令都不会执行,因此您最好不要生成它们。