LLVM language 参考手册(译)(5)

 

垃圾回收器名称(Garbage Collector Names

每个函数能够制定一个垃圾回收期的名称,这个名称是一个简单的字符串:html

define void @f() gc "name" { ... }

编译器声明了这个名字的可能值。指定一个收集器将会致使编译器会为了支持这个垃圾回收算法修改它的输出。前端

前置数据(Prefix Data

前置数据是一种与函数相关的数据,在函数主体以前代码生成器会立刻发散这种数据。这个特性的目的是为了让容许在前端分配语言指定的在指定函数中运行期元数据,而且能够经过函数指针来得到这个数据的同时这个函数指针仍然是可调用的。对一个给定的函数来访问这个数据,程序能够经过bitcast转换这个函数指针到一个常量类型的指针。这是意味着这个IR符号指向这个前置数据的开始。算法

为了维持普通函数调用的语义,这个前置数据必须有一个实际格式。具体来讲,这必须开始于一段bytes序列,且能够从中解码到一段用于该模块目标的机器指令序列,这个点的传送控制紧随这个前缀数据,而不执行任何其余的可见动做。这就容许内联器和其余pass来推论这是一个函数定义语义而不是须要一个前置数据。显而易见地,这使前置数据的格式高度依赖于目标平台。后端

前置数据的定义,相似于一个前缀数据类型的全局变量的初始化式。在前置数据和函数主体之间没有自动填充的数据。若是有填充要求,那么它必须是前置数据的一部分。数组

这是一个很小的有效前置数据,其对于X86体系结构的值为144,类型为i8,则会被编码为 nop 指令。安全

define void @f() prefix i8 144 { ... }

通常来讲,前置数据能够跳过元数据经过编码一个相关的branch指令,就像下面这个例子中的对于X86_64体系有效的前置数据,它的前两个byte将被编码jmp.+10dom

%0 = type <{ i8, i8, i8* }>

define void @f() prefix %0 <{ i8 235, i8 8, i8* @md}> { ... }

函数可能只拥有前置数据但没有主体。这与 available_externally 连接标识有着相同的语义,即数据可能会被优化器使用的不会被发散到对象文件中。函数

属性组(Attribute Groups

属性组是在IR中的对象引用的属性的集合。他们对于保持 .ll 可读有着重要意义,由于许都函数会使用相同的属性集。在退化的状况下一个 .ll 文件对应着单一的 .c 文件,这个单一的属性组讲捕获那些用于构建这个文件的重要命令行标识。布局

一个属性组是一个模块层次的对象。要使用一个属性组,一个对象能够引用这个属性组的ID(例如 #37)。一个对象可能引用超过一个属性组。在这种状况下来自于不一样属性组的属性会被合并。性能

这里有一个规定一个函数应该内联的属性组的例子,并拥有一个堆栈对齐属性值为4,且不使用SSE指令

; Target-independent attributes:
attributes #0 = { alwaysinline alignstack=4 }

; Target-dependent attributes:
attributes #1 = { "no-sse" }

; Function @f has attributes: alwaysinline, alignstack=4, and "no-sse".
define void @f() #0 #1 { ... }

函数属性(Function Attributes

函数属性用于函数交流额外信息的。函数属性被认为是函数的一部分,而不是函数类型的一部分,因此拥有不一样函数属性的函数能够对应着同一个函数类型。

函数属性是紧跟在指定的函数类型后的简单的关键字。若是之后须要指定多个函数属性,那么使用空格符分隔它们。例如:

define void @f() noinline { ... }
define void @f() alwaysinline { ... }
define void @f() alwaysinline optsize { ... }
define void @f() optsize { ... }
alignstack(<n>)
这个属性指明了,当发散序言和后记,后端应该强制对齐堆栈指针。在括号中指定所但愿的对齐属性,其值必须是2的幂。
alwaysinline
该属性指明了内联器应该尽量地内联这个函数到调用者中,而忽略这个调用者有效的内联阙值。
builtin
这代表,在调用点被调用函数应该被认定为内建函数,即便该函数的声明使用了  nobuiltin 属性。这只在直接调用了声明了  nobuiltin 属性的函数的调用地点有效。
cold
该属性代表了这个函数将不多被调用。在计算边权重时,被一个cold函数所控制的基本块也被认为是cold的,所以将被给予低权重。
inlinehint
该属性代表,这份源代码包含一个提示,即内联函数是可行的(如C / C + +中的“inline”关键字)。这仅仅是一个提示,它不对内联器作出任何要求。
minsize
该属性建议优化器pass和代码生成器pass保持函数的代码长度尽可能的小且牺牲运行时效率来最小化生成的代码来进行优化。
naked
这个属性禁止函数的序言/结尾发散。产生的结果是特定于系统的。
nobuiltin
这代表,在调用点被调用函数不被识别为一个内建函数。 LLVM将保留原来的调用,而不是使用基于内建函数语义等价的代码替换它,除非调用点使用了  builtin 的属性。这个属性对于调用点和函数的声明和定义都是有效的。、
noduplicate

该属性代表,函数的调用不能被复制。一个 noduplicate 函数的调用可能被移动到父函数​​,但不能被复制到父函数。

一个包含 noduplicate 函数仍然可能被内联,条件是该调用没有被重复内联。这意味着,该函数具备 internal 连接标识,并只有一个调用点,因此内联后,原始调用被删除。

noimplicitfloat
该属性代表,禁用隐式的浮点指令
noinline
此属性代表,在任何状况下,内联器都不该该内联该函数。此属性不能与 alwaysinline 属性一块儿使用。
nonlazybind
此属性代表,抑制函数的延迟绑定符号特性。若是函数在程序启动时不被调用,那么程序启动会耗费额外的启动时间,但这可能会使函数调用更快。
noredzone
此属性代表,即便目标平台指定的ABI一般容许,该属性指示代码生成器也不该该使用一个red zone,。
noreturn
此属性代表,该函数从不正常返回。若是该函数动态返回,这将产生不肯定的运行期行为,。
nounwind
此属性代表,该函数从不返回展开的或异常的控制流。若是函数不展开,其运行时的行为是未定义的。
optnone

此此属性代表,该函数不能被除了过程间优化 pass 外的任何优化或代码生成器 pass 优化。这个属性不能与一块儿 alwaysinline 属性使用;这个属性也与 minsize 属性和 optsize 属性不兼容。( minsize 与 optsize 要求优化)

此属性要求在函数中同时指定该属性和 noinline 属性,因此该函数从不内联到任何调用者。只有具有alwaysinline 属性的函数才能内联到这个函数。

optsize
此属性代表,优化 pass 和代码生成器 pass 应该保持这个函数的代码长度较小,不然进行特定的优化,不显著影响运行期性能的状况下减小代码长度。
readnone

对于一个函数,这个属性代表该函数严格基于它的参数计算其结果(或决定展开异常),而不经过解引用任何指针参数或以其余方式访问任何调用者可见的可变状态(如内存,控制寄存器等)。它不经过任何指针参数(包括 byval 参数)写入和从不改变调用者可见的任何状态。这意味着它没法经过调用C + +的异常throw的方法展开异常。

对于一个参数,这个属性代表,该函数不能解引用指针参数,尽管若是经过其余指针它能够读取或写入指针参数指向内存(由于调用者可见的是指针的值而不是指针指向的值)。

readonly

对于一个函数,这个属性代表该函数不经过任何指针参数(包括 byval 参数)或写其余方式修改任何调用者函数可见的状态(如内存,控制寄存器等)。它可能会解引用指针参数和读取在调用者中设置的状态。在使用相同的函数集和全局状态时,一个只读函数老是返回相同的值(或展开相同的异常)。它没法经过调用C + +的异常throw的方法展开异常。

上一个参数,这个属性表示该函数不经过这个指针参数写的,即便它可能写入内存的指针指向。

returns_twice
该属性代表,该函数能够返回两次。该C  setjmp 的是这样一种函数的一个例子。编译器禁用这些函数的调用者一些优化(如尾调用)。
sanitize_address
该属性代表,为函数启用AddressSanitizer检查(动态地址安全分析)。
sanitize_memory
该属性代表,为函数启用MemorySanitizer检查(未初始化内存访问的动态检测)
sanitize_thread
该属性代表,为函数启用ThreadSanitizer检查(动态线程安全性分析)
ssp

该属性代表,该函数应该发散一个堆栈溢出保护功能。它有一个“canary”形式 —( a random value placed on the stack before the local variables that’s checked upon return from the function to see if it has been overwritten.)。一个启发式用来肯定一个函数须要的堆栈保护与否。在如下状况,这个被使用了启发式将启用函数保护器:

字符数组比 ssp-buffer-size 大(默认值为8)。
字符数组的集合比 ssp-buffer-size 大。
调用alloca()的变量长度或常量长度(alloca的参数)大于 ssp-buffer-size 。

被识别为须要保护的变量将被安排在堆栈,使得对于堆栈保护器它们是连续的。

若是一个函数,它有一个SSP属性被内联到一个不具备SSP属性的函数,而后将获得的函数将具备一个SSP属性。

sspreq

该属性代表,该函数应该发散一个堆栈溢出保护功能。这将覆盖 ssp 函数属性。

被识别为须要保护的变量将被安排在堆栈,使得对于堆栈保护器它们是连续的。具体布局规则是:

一、大数组和含大数组的结构体(>= sp-buffer-size)是最接近堆栈保护器的。
二、小数组和含小数组的结构体(< sp-buffer-size)是第二接近堆栈保护器的。 

三、采起了它们的地址的变量是第三接近堆栈保护器的

若是一个函数,它有一个 sspreq 属性被内联到一个不具备 sspreq 属性或具备 ssp 或 sspstrong 属性的函数,那么获得的结果函数将具备 sspreq 属性。

sspstrong

该属性代表,该函数应该发散一个堆栈溢出保护功能。在肯定函数是否须要的堆栈保护器时,此属性会使用一个强有力的试探法。强大的启发式将为函数启用保护器:

任何长度和类型的数组
任何长度和类型的数组的集合。
调用了alloca( ) 。
采起了它们的地址的局部变量。

被识别为须要保护的变量将被安排在堆栈,使得对于堆栈保护器它们是连续的。具体布局规则是:

一、大数组和含大数组的结构体(>= sp-buffer-size)是最接近堆栈保护器的。 
二、小数组和含小数组的结构体(< sp-buffer-size)是第二接近堆栈保护器的。 

三、采起了它们的地址的变量是第三接近堆栈保护器的

这将覆盖 ssp 功能属性。

若是一个函数,它有一个 sspstrong 属性被内联到一个不具备 sspstrong 属性的函数,那么最后获得的函数将具备 sspstrong 属性。

uwtable
该属性代表,被指定的ABI要求为这个函数展开表实体,即便咱们能够代表没有异常会被这个函数传递。。这一般是针对于ELF x86-64 ABI的状况,可是它能够为某些编译单元被禁用。
相关文章
相关标签/搜索