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?

retbr

您永远不需要在基本块中生成终止符,因为正如您所指出的,任何经过它的指令都不会执行,因此您最好不要生成它们。