LLVM'ret'指令

时间:2017-04-09 13:23:41

标签: return llvm llvm-ir

我已经关注了LLVM教程Kaleidoscope。现在我试图将这个前端编译器外部用于类似于Pascal的语言。我有这段代码:

program main;

function rett(): integer;
begin
    rett := 1;
    exit;
    rett := 5;
end;

var a: integer;
begin
    a := rett();    
    writeln(a);
end.

由于exit命令(因此行rett := 5;不应该执行),该程序的输出应该是单个整数'1'。但输出为'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'命令?有什么东西我错过了吗?

更新 在文件中写道:

  

每个基本块可以选择以标签开头(给基本块一个符号表条目),包含一个指令列表,并以一个终结符指令(例如分支或函数返回)结束。

这是否意味着“终结者”指令只能在基本块的末尾?如果是,我该如何为我的语言实现return和break命令?

1 个答案:

答案 0 :(得分:0)

我无法重现问题(您的示例输出1),但无论如何我都会回答这些问题。

  

这是否意味着"终结者"指令只能在基本块的末尾?

那是对的。实际上,opt显示示例中的@rett函数包含以下两个基本块:

CFG for @rett

  

如果是,我应该如何为我的语言实现return和break命令?

使用retbr

你不需要在一个基本块中生成一个终结符,因为正如你所指出的那样,任何超过它的指令都不会执行,所以你也可能不会生成它们。