LLVM IR 函数

在LLVM中 函数可以用“define”来定义,也可用“declare”进行声明:

  • LLVM函数由“define”关键字进行定义,每个函数都有一个可选的链接标识,一个可选的可见性模式,一个可选的DLL存储类别,一个可选的调用约定,一个可选的unnamed_addr属性,一个返回值类型,一个可选的返回值的参数属性,一个函数名,一个(可能为空的)实参列表(每一个都带有可选的参数属性),可选的函数属性,一个可选的section,一个可选的对齐属性,一个可选垃圾回收期的名字,一个可选的前缀,一个左花括号,一个基本块列表和一个右花括号。

  • LLVM函数声明由 “declare”关键字,一个可选的链接标识,一个可选的可见性模式,一个可选的DLL存储类型,一个可选的调用约定,一个可选的 unnamed_addr 属性,一个返回值类型,一个可选的返回值类型的参数属性,一个函数名,一个可能为空的实参列表,一个可选对齐属性,一个可选垃圾回收器名和一个可选的前缀。

一个函数定义包含一个基本块列表,形成该函数的CFG(控制流图)。每个基本块可以有选择地以一个标签开始(赋予基本块一个符号表入口),包含指令列表,并以终止指令(如分支或函数返回)结束。如果未提供显式标签,一个块被赋值给一个隐含的编号标签,编号使用从计数器中返回下一个值,就像用于未命名的临时对象那样(参见上文)。例如,如果函数入口块没有明确的标签,则会分配标签“%0”,那么该块中的第一个未命名的临时块将为“%1”,以此类推。

函数中的第一个基本块在两个方面是特殊的:在函数入口时立即执行,并且不允许有祖先基本块(即不能有任何分支到函数的入口块)。由于该块可以没有前驱,它也不能有任何PHI节点

LLVM允许为函数指定显式section。如果目标机支持它,它将函数发送给指定的section。另外,该函数可以放置在COMDAT中。

可以为函数指定明确的对齐方式。如果不存在,或者如果对齐方式设置为零,则函数的对齐由目标机设置为任何感觉方便的方式。如果指定了明确的对齐方式,则该函数被强制至少具有那么多的对齐。所有对齐必须是2的幂。

如果unnamed_addr给出该属性,则知道该地址不重要,并且可以合并两个相同的函数。

如果local_unnamed_addr给出该属性,则该地址在模块内是不明显的。

如果未给出显式地址空间,则它将默认为字符串中的程序地址空间。

Syntax:

define [linkage] [PreemptionSpecifier] [visibility] [DLLStorageClass]
       [cconv] [ret attrs]
       <ResultType> @<FunctionName> ([argument list])
       [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [fn Attrs]
       [section "name"] [comdat [($name)]] [align N] [gc] [prefix Constant]
       [prologue Constant] [personality Constant] (!name !N)* { ... }

参数列表是逗号分隔的参数序列,其中每个参数具有以下形式:

Syntax:

<type> [parameter Attrs] [name]