函数(Functions

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

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

一个函数定义包含一个基本块的列表,可以为函数形成CFG(控制流图形)。每一个基本块可以(可选的)开始于一个label(给定这个基本快一个符号表入口),包含一个指令列表,并且结束与一个终止指令(例如分支或函数返回)。如果一个明确的label不被提供,一个快会被分配到一个隐式的编号label,使用的计数器与匿名临时变量使用同一个计数器。例如,如果一个函数入口块不具有一个显示的label,他会被分配到一个label "%0",然后第一个在这个块中的匿名临时变量将会是“%1”。

函数中的第一基本块特殊在两个方面: 她是在函数进入后马上执行的,并且它是不允许有前置基本块(即函数入口块不能拥有任何分支)。因为这个块没有前置块,所以也不能有任何 PHI nodes.

LLVM允许函数指定一个明确的section。如果目标平台支持它,它会放散函数到这个指定块。

一个显示的对齐属性可能会被指定到一个函数。如果没有指定,或者对齐属性被设置为0,那么这个函数的对齐属性将会根据目标平台的需要设定。如果一个显式对齐属性被指定,这个函数被迫至少想指定的那么多对齐。所有对齐属性必须为2的次幂。

如果 unnamed_addr 属性被指定了,函数的地址会被认为是不重要的且两个相同的函数之间可以被合并。

语法:

define [linkage] [visibility] [DLLStorageClass]
[cconv] [ret attrs]
<ResultType> @<FunctionName> ([argument list])
[fn Attrs] [section "name"] [align N]
[gc] [prefix Constant] { ... }

别名(Aliases

别名作为可别名对象(包括函数,全局变量,另一个别名或全局值的bitcast)的“second name”。别名可以拥有一个可选的链接标识,一个可选的可见性模式,一个可选的DLL存储类别。

语法:

@<Name> = [Visibility] [DLLStorageClass] alias [Linkage] <AliaseeTy> @<Aliasee>

链接标识必须是 privatelinker_privatelinker_private_weakinternallinkonceweaklinkonce_odrweak_odrexternal.中的其中一个。注意一些系统链接器可能会不正确地处理一个降级的弱符号作为非弱别名。

具名元数据(Named Metadata

具名元数据是一个元数据的集合。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}

参数属性(Parameter Attributes

这个返回类型和每一个函数的参数类型可能拥有一个参数属性集。参数属性是用于交流函数的返回值和参数的额外信息。参数类型被认为是函数的一部分,但不是函数类型的一部分,所以用不同的参数属性的函数可以拥有同一个函数类型。

参数属性是是以下的一些跟在类型后的简单的关键字。如果需要多个参数属性,他们需要被空白符分隔开。

例如:

declare i32 @printf(i8* noalias nocapture, ...)
declare i32 @atoi(i8 zeroext)
declare signext i8 @returns_signed_char()

注意,任何对于函数结果nounwindreadonly)属性跟随在实参列表后。

当前,仅有以下的参数属性被定义:

zeroext
这表明了在代码生成时,参数或返回值应该被0扩展到目标平台ABI要求调用者(即参数长度)和被调用者(即返回值长度)的长度范围(一般来说是32bits,但对于x86-64的i1来说是8bits)。Note:是因为寄存器大小和要求压栈操作数大小?
signext
这表明了代码生成时,参数或返回值应该被符号扩展到目标平台ABI要求调用者(即参数长度)和被调用者(即返回值长度)的长度范围(一般来说是32bits)。Note:对于有符号数即需要符号位扩展
inreg
这表明参数和返回值在发散函数调用或返回值的期间,需要应该以一个依赖于特定平台的样式对待(通常来说,把参数和返回值放置到寄存器而不是放置到存储器中,即使一些目标平台使用它来区分两种不同的寄存器)。这个属性的使用的针对指定平台的。
byval
这表明指针参数应该已传至方式传递到函数中。这个属性蕴含了在调用者和被调用者之间的一个隐藏的指针复制操作,因此使被调用者不能修改在调用者里的值。这个属性仅在LLVM指针实参里是有效的。这通常用于传递结构体和数组的值(寄存器只能存放这届数据的指针),但这对于scalar object的指针也是有效的。
这个复制被认为是从属于调用者而不是被调用者的(例如,readonly 函数不应该写一个 byval 的参数)。这个属性对于返回值是无效的。
这个 byval 属性同样支持指定对齐属性。这指明了stack slot的对齐格式且指定调用地点的指针对齐属性。如果对齐属性不被指定的话,代码生成器会做一个平台相关的猜测。

inalloca

注意

这个特性是不稳定的且没有完全实现。

inalloca 实参属性允许调用者带有即将离开stack的实参地址。一个 inalloca 实参必须是一个使用 alloca 指令创建指向栈内存的指针的地址。这个分配的堆栈空间或实参分配必须也以inalloca关键字标识。只有过去的实参可以使用inalloca属性且这个实参保证在内存中传递。

一个实参分配可能被函数调用使用至少一次因为这个函数调用可能会释放它。这个 inalloca 属性不可能与其他会影响实参存储的属性结合使用,像inregnestsret, or byval。这个 inalloca 属性也禁止LLVM隐式降低大型聚合返回值,这意味着前端作者必须通过 sret 降低他们。

当到达调用地点时,实参分配必须是仍然活的最新栈分配,或者结果是未定义的。在一个实参分配后和这个实参的调用地点前额外分配堆栈空间是可能的,但这必须清除llvm.stackrestore

详见 Design and Usage of the InAlloca Attribute

sret
这表明这个指针参数指向一个在源程序中作为函数返回值的结构体的地址。这个指针必须由调用者保证是有效的:这个结构的加载和存储必须与被调用者所假定的方式是一致的。这只适用于第一个参数。这对于返回值并不是一个有效的属性。
noalias
这表明基于实参或者返回值的指针值不是一个不基于它们的别名指针值,忽略明确的“irrelevant”依赖。对于一个父函数的调用,在函数调用前后的内存引用和函数调用内部的内存引用之间的依赖对于带有 noalias 关键字的实参和返回值是“irrelevant”。这个调用者与被调用者共享这个关系以确定这些要求得到满足。更多的细节,请查看alias analysis中的noalias响应的讨论。
注意 noalias 的定义故意定义得与C99中的函数实参的 restrict 定义相似,尽管 restrict 的定义稍微弱一些。
因为对于函数返回至,C99的 restrict 是无意义的而LLVM的 noalias 是有意义的。 
nocapture
这表明被调用者不对生存期比被调用者长的指针做出任何复制。对于返回值这不是一个有效的属性。
nest
这表明指针参数可以使用trampoline intrinsics删除。这不是一个有效的返回值属性,只能被应用于一个参数。
returned
这表明函数始终返回这个参数作为它的返回值。代码生成器生成调用者时的一个优化提示,允许尾部调用优化和在某种情况下忽略寄存器的保存和恢复;在省城被调用者是,它不会被检查或执行。参数和函数返回类型必须是对于bitcast指令有效的操作数。这不是一个有效的返回值属性,只能应用于一个参数。

LLVM language 参考手册(译)(4)的更多相关文章

  1. LLVM language 参考手册 翻译停止相关

    再翻译LLVM language 参考手册的时候,个人感觉很多东西都不是很懂,因此打算学习完编译原理后再去继续研究翻译,多有不便望见谅

  2. LLVM language 参考手册(译)(1)

    LLVM Language Reference Manual 摘要 这个文档是一个LLVM汇编语言的参考手册.LLVM是一个基于Static Single Assignment(SSA - 静态单赋值 ...

  3. LLVM language 参考手册(译)(3)

    可见性模式(Visibility Styles) 所有全局变量和函数具有以下的可见性模式之一: “default” - Default style 在那些使用ELF object file格式的平台( ...

  4. LLVM language 参考手册(译)(6)

    模块级内联汇编(Module-Level Inline Assembly) 模块包含“module-level inline assembly”块,这与GCC中的“file scope inline ...

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

    垃圾回收器名称(Garbage Collector Names) 每一个函数可以制定一个垃圾回收期的名称,这个名称是一个简单的字符串: define void @f() gc "name&q ...

  6. LLVM language 参考手册(译)(2)

    调用约定(Calling Conventions) LLVM functions, calls and invokes 可以带有一个可选的调用约定来指明调用方式.每一对 caller/callee(调 ...

  7. Lua 5.1 参考手册

    Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes 云风 译 www.codingno ...

  8. [SQL]SQL语言入门级教材_SQL语法参考手册(三)

    SQL 语法参考手册 DB2 提供了关连式资料库的查询语言 SQL (Structured Query Language),是一种非常口语化.既易学又易懂的语法. 此语言几乎是每个资料库系统都必须提供 ...

  9. Lua参考手册

    英文原版: http://www.lua.org/manual/5.1/ 中文版下面2个地址都有:一样的 manual.luaer.cn lua在线手册 lua参考手册Lua参考手册的中文翻译(云风翻 ...

随机推荐

  1. open和fopen的区别

    open和fopen的区别: 1.缓冲文件系统缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用,当执行读文件的操作时,从磁盘文件将数据先读入内存“缓冲区”, 装满后再从内存“缓 ...

  2. [原创]SSAS-引用维度与多数据源、多数据源视图引发分区错误

    背景:       最近有个项目,有32家分公司,集团总部需要取这个32家分公司数据做分析,由于每个分公司的数据都比较庞大,所以最终方案是每个分公司一个DW,在cube搭建过程中将每个公司数据作为一个 ...

  3. Linux中的文件描述符与打开文件之间的关系

    Linux中的文件描述符与打开文件之间的关系 导读 内核(kernel)利用文件描述符(file descriptor)来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描 ...

  4. tq2440开发板基本配置

    时钟配置及分配 tq2440的晶振频率是12MHz,在uboot中有如下语句:   #define S3C2440_CLKDIV 0x05 /* FCLK:HCLK:PCLK = 1:4:8, UCL ...

  5. U-BOOT配置过程

    摘自:<嵌入式Linux应用开发完全手册> ( Target  :         smdk2410              $1 Architecture:     arm       ...

  6. PHP.12-PHP-设计文件上传类

    设计文件上传类 [PHP参数详解]{文件上传} ********************** *#构造方法编写 ********************** 此种传参方法规定必须用户必须按响应位置输入 ...

  7. SQL Server数据库自增字段正确的插入值的描述

    我们今天主要向大家讲述的是SQL Server数据库之向SQL Server自增字段正确的插入值的实际操作步骤,在一般的情况下,我们不能向 SQL Server 数据库自增字段中插入值,如果非要这么干 ...

  8. hadoop下的Pipes(用C++进行hadoop程序开发)

    说明:这篇博客来自我的CSDN博客:http://blog.csdn.net/lxxgreat/article/details/7755369 经过一上午的努力,终于以伪分布式模式运行了C++版的Ma ...

  9. Hadoop学习笔记(3)——分布式环境搭建

    Hadoop学习笔记(3) ——分布式环境搭建 前面,我们已经在单机上把Hadoop运行起来了,但我们知道Hadoop支持分布式的,而它的优点就是在分布上突出的,所以我们得搭个环境模拟一下. 在这里, ...

  10. 【MYSQL】数据类型

    转载 https://www.baidu.com/s?ie=UTF-8&wd=cnblog 原文 泪云山海的博客 mysql 数据类型 1.整型 MySQL数据类型 含义(有符号) tinyi ...