LLVM函数定义由“define” 关键字,一个可选的连接标识,一个可选的可见性模式,一个可选的DLL存储类别,一个可选的调用约定,一个可选的 unnamed_addr 属性,一个返回值类型,一个可选的返回值的参数属性,一个函数名,一个(可能为空的)实参列表(每个都带有可选的参数属性),可选的函数属性,一个可选的section,一个可选的对齐属性,一个可选垃圾回收期的名字,一个可选的前缀,一个左花括号,一个基本块列表和一个右花括号。html
LLVM函数声明由 “declare” 关键字,一个可选的连接标识,一个可选的可见性模式,一个可选的DLL存储类型,一个可选的调用约定,一个可选的 unnamed_addr 属性,一个返回值类型,一个可选的返回值类型的参数属性,一个函数名,一个可能为空的实参列表,一个可选对齐属性,一个可选垃圾回收器名和一个可选的前缀。前端
一个函数定义包含一个基本块的列表,能够为函数造成CFG(控制流图形)。每个基本块能够(可选的)开始于一个label(给定这个基本快一个符号表入口),包含一个指令列表,而且结束与一个终止指令(例如分支或函数返回)。若是一个明确的label不被提供,一个快会被分配到一个隐式的编号label,使用的计数器与匿名临时变量使用同一个计数器。例如,若是一个函数入口块不具备一个显示的label,他会被分配到一个label "%0",而后第一个在这个块中的匿名临时变量将会是“%1”。node
函数中的第一基本块特殊在两个方面: 她是在函数进入后立刻执行的,而且它是不容许有前置基本块(即函数入口块不能拥有任何分支)。由于这个块没有前置块,因此也不能有任何 PHI nodes.python
LLVM容许函数指定一个明确的section。若是目标平台支持它,它会放散函数到这个指定块。web
一个显示的对齐属性可能会被指定到一个函数。若是没有指定,或者对齐属性被设置为0,那么这个函数的对齐属性将会根据目标平台的须要设定。若是一个显式对齐属性被指定,这个函数被迫至少想指定的那么多对齐。全部对齐属性必须为2的次幂。数组
若是 unnamed_addr 属性被指定了,函数的地址会被认为是不重要的且两个相同的函数之间能够被合并。函数
语法:post
define [linkage] [visibility] [DLLStorageClass] [cconv] [ret attrs] <ResultType> @<FunctionName> ([argument list]) [fn Attrs] [section "name"] [align N] [gc] [prefix Constant] { ... }
别名做为可别名对象(包括函数,全局变量,另外一个别名或全局值的bitcast)的“second name”。别名能够拥有一个可选的连接标识,一个可选的可见性模式,一个可选的DLL存储类别。优化
语法:this
@<Name> = [Visibility] [DLLStorageClass] alias [Linkage] <AliaseeTy> @<Aliasee>
连接标识必须是 private, linker_private, linker_private_weak, internal, linkonce, weak, linkonce_odr, weak_odr, external.中的其中一个。注意一些系统连接器可能会不正确地处理一个降级的弱符号做为非弱别名。
具名元数据是一个元数据的集合。Metadata nodes (但非元数据字符串) 是惟一对于具名元数据有效的操做数。
语法:
; Some unnamed metadata nodes, which are referenced by the named metadata.
!0 = metadata !{metadata !"zero"}
!1 = metadata !{metadata !"one"}
!2 = metadata !{metadata !"two"}
; A named metadata.
!name = !{!0, !1, !2}
这个返回类型和每个函数的参数类型可能拥有一个参数属性集。参数属性是用于交流函数的返回值和参数的额外信息。参数类型被认为是函数的一部分,但不是函数类型的一部分,因此用不一样的参数属性的函数能够拥有同一个函数类型。
参数属性是是如下的一些跟在类型后的简单的关键字。若是须要多个参数属性,他们须要被空白符分隔开。
例如:
declare i32 @printf(i8* noalias nocapture, ...)
declare i32 @atoi(i8 zeroext)
declare signext i8 @returns_signed_char()
注意,任何对于函数结果nounwind, readonly)属性跟随在实参列表后。
当前,仅有如下的参数属性被定义:
inalloca
注意
这个特性是不稳定的且没有彻底实现。
inalloca 实参属性容许调用者带有即将离开stack的实参地址。一个 inalloca 实参必须是一个使用 alloca 指令建立指向栈内存的指针的地址。这个分配的堆栈空间或实参分配必须也以inalloca关键字标识。只有过去的实参可使用inalloca属性且这个实参保证在内存中传递。
一个实参分配可能被函数调用使用至少一次由于这个函数调用可能会释放它。这个 inalloca 属性不可能与其余会影响实参存储的属性结合使用,像inreg, nest, sret, or byval。这个 inalloca 属性也禁止LLVM隐式下降大型聚合返回值,这意味着前端做者必须经过 sret 下降他们。
当到达调用地点时,实参分配必须是仍然活的最新栈分配,或者结果是未定义的。在一个实参分配后和这个实参的调用地点前额外分配堆栈空间是可能的,但这必须清除llvm.stackrestore。
详见 Design and Usage of the InAlloca Attribute