可见性模式(Visibility Styles

所有全局变量和函数具有以下的可见性模式之一:

default” - Default style
在那些使用ELF object file格式的平台(targets),默认可见性意味着声明对于其他模块是可见的,并且在可共享库,意味着这个声明的实体是可被覆盖的。在Darwin平台,默认可见性意味着声明对于其他模块是可见的。默认可见性与在这种语言中的 “external linkage” 是一致的。
hidden” - Hidden style
一个对象的带有hidden可见性的两个声明,如果它们是处于一个相同的可共享单元(shared object),那么它们会被引用到一个相同的对象。通常来说,hidden可见性表明符号不会被放置到动态符号表,所以其他模块(可执行程序 或 共享库)不可以直接引用这个符号
protected” - Protected style
在ELF中,protected 可见性表明符号会被放置到动态符号表,但在特定模块中的这些引用会绑定到一个本地的符号。所以这个符号不能被其他模块重写。

DLL存储类别(DLL Storage Classes

所有全局变量,函数,别名(Aliases)可以拥有下面的DLL存储类别之一:

dllimport
dllimport” 会导致编译器通过一个指向到 被DLL导出的指针 的全局指针,来引用一个函数或变量。在微软windows平台,这个指针名的格式为  __imp_ 接上引用的函数或变量的名称(__imp_函数名)。
dllexport
dllexport” 会导致编译器提供一个指向 一个在DLL中的指针 的全局变量,所以它可以被引用到带有 dllimport 属性的实体。在微软windows平台,这个指针名的格式为  __imp_ 接上引用的函数或变量的名称(__imp_函数名)。为了使编译器,汇编器和链接器知道某个符号是被外部引用并且防止这个符号被删除,因此这个存储类别为了定义一个dll接口而存在的。

具名类型(Named Types

LLVM IR允许你为明确类型标识其名称的别名。这使得阅读IR更加得容易且使IR更加紧凑(condensed )(实际上这与递归类型有关)。一个名字标识的例子如下:

%mytype = type { %mytype*, i32 }

你可以给定对除了“void”任何类型一个名称。类型名的别名可以被使用到任何期望 “%mytype”语法的地方。

注意,这些类型名是构造类型指明的名称的别名,因此你可以对同一个类型标识多个名字。这通常会在dumping out一个 .ll文件的时候导致行为混乱。由于LLVM IR使用构造类型,所以这个名称不是这个类型的一部分。当print out LLVM IR,printer会挑选一个名称替代来同一类型的所有名称(the printer will pick one name to render all types of a particular shape. 。。。为相同形状着色,囧)。这意味着如果你有最终具有相同LLVM 类型的两个不同的源类型在一段代码中,那么dumper会打印the “wrong” 或 unexpected type。这是一个重要的设计点且将不会被改变。

全局变量(Global Variables

全局变量在编译期定义存储分配范围而不是运行期。

全局变量定义必须被初始化,被放置在一个显式的section中,且有一个可选的显式对齐标识。

全局变量在其他的编译单元也可以被声明,但在这种情况下它们没有初始化式(initializer)。

一个变量可能被定义为thread_local,,这意味着这个变量不会被其他线程所共享(每一个线程会拥有这个变量的一份单独的拷贝)。

不是所有平台都支持thread-local变量。可选地,一个TLS模型可以标识:

localdynamic

标识仅用于当前可共享库的变量

initialexec

标识在模块中不会被动态加载的变量

localexec

标识在可执行程序中定义且只在可执行程序中使用的变量

这种模型与ELF TLS模型是一致的;详见ELF Handling For Thread-Local Storage。如果指定的模型不被支持或者有一个更合适的模型可供选择,平台可能会选择一个不同TLS模型。
一个变量可能被定义为一个全局常量,表明其内容从不会被修改(使其能够更好地被优化,允许这个全局数据被放置到可执行程序的只读section)。注意,需要在运行期被初始化的变量不能被标识为constant,因为初始化时有一个到这个变量的存储操作。
LLVM允许明确全局变量的声明被标识为constant,计时这个全局变量的最终定义不是constant。这种能力可以使程序获得些微的优化,但这要求这个语言定义保证基于“constantness”的优化对于不包含这个定义的编译单元是有效的。
作为SSA值,全局变量定义为指针值,其作用域是程序中的所有基本块。全局变量永远定义为一个其content所对应的类型的指针因为他们描述一个存储范围,所有这些LLVM中的存储对象被通过这个指针访问。
全局变量可以被 unnamed_addr 标识,表明它的地址是没有意义的,仅仅是指向其内容。一个常量被这样标识可以被合并到其他拥有相同初始化式的常量。注意,一个地址有意义的常量可以被合并到一个 unnamed_addr 常量,且合并结果变为一个地址有意义的常量。
一个全局变量可能被声明驻留在一个平台指定的编号地址空间。对于支持编号地址空间的平台,地址空间会影响优化被怎么处理及使用什么指令来访问变量。默认的地址空间是0。地址空间限定符必须放在其他任何属性前。
LLVM允许一个明确的section用于指定全局变量。如果目标平台支持它,他会发散全局变量到这个指定section。

默认下,全局初始化式通过假设被定义在模块中的全局变量是在全局初始化式之前他们的初始值是不会被修改的。对于可能从外部被访问的变量,包括带有“external”链接标识的全局变量 或者 出现在@llvm.used 或者 dll导出的变量,这种猜想也是正确的。这种猜想会被带有"externally_initialized"的变量抑制。

一个显式对齐可能被标识于一个全局变量,这个显示对齐一定是2的次幂。如果对齐属性标识不存在,或者对齐属性被设置为0,那么这个全局变量的对齐属性将会被根据目标平台需求设置。如果一个显式的对齐属性被标识,这个全局变量被迫完全按照这个对齐属性对齐。如果这个全局变量有一个被分配到的section,目标平台和优化器不会允许over-align这个全局变量。在这种情况下,额外的对齐是显而易见的:例如,代码可能猜想全局变量被集中放置到他们的section中并尝试以数组形式遍历他们,但对齐填充会打破这个遍历过程。

全局变量同样可以拥有一个DLL存储类别

语法:

[@<GlobalVarName> =] [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
[AddrSpace] [unnamed_addr] [ExternallyInitialized]
<global | constant> <Type>
[, section "name"] [, align <Alignment>]

例如,下面定义了一个存储在编号地址带有一个初始化式,section和对齐属性的全局常量。

@G = addrspace(5) constant float 1.0, section "foo", align 4

下面是一个只声明全局变量的例子

@G = external global i32

下面是一个定义了thread-local的带有initialexec TLS模型的全局变量

@G = thread_local(initialexec) global i32 0, align 4

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

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

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

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

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

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

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

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

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

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

    函数(Functions) LLVM函数定义由“define” 关键字,一个可选的链接标识,一个可选的可见性模式,一个可选的DLL存储类别,一个可选的调用约定,一个可选的 unnamed_addr 属 ...

  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. c语言中的二分法

    \\\题外:对于printf引号中的内容一定要细心书写 ; 数组由a[0]开始计数,切记:尤其是与for循环中i=1 搞混 运用a[i+1]等超前数据时 需先用 for(i=0;i<=n-1;i ...

  2. make[1]: *** [pcrecpp.lo] 错误 1

    在安装:pcre-8.30 时,报如下错误: [root@localhost pcre-8.30]# make && make installmake  all-ammake[1]: ...

  3. JDBC常用代码

    try { //加载驱动 Class.forName("com.mysql.jdbc.Driver"); String url="jdbc:mysql://127.0.0 ...

  4. RunJS - 在线编辑、展示、分享、交流你的 JavaScript 代码

    发现一个很好玩,很强大的网站 RunJS - 在线编辑.展示.分享.交流你的 JavaScript 代码   http://runjs.cn/ 比如: http://runjs.cn/detail/l ...

  5. 使用Jenkins搭建持续集成服务

    1. 什么是持续集成 持续集成 (Continuous Integration, 简称 CI) 是软件工程中的一种实践, 用于将开发人员不同阶段的工作成果集成起来, 通常一天之中会进行多次. 持续集成 ...

  6. XXX项目 android 开发笔记

    1 工具? eclipse or android studio fragment 套用

  7. ubuntu搭建分布式hadoop-2.6.0概略和错误

    详细配置:http://blog.csdn.net/ggz631047367/article/details/42426391 1.修改机器/etc/hostname分别为   master    s ...

  8. 为textarea增加maxlength属性(转)

    如果只是單純地想限制 textarea 中的字數,不想寫太多的話,可用:   <textarea onkeyup="this.value = this.value.slice(0, 8 ...

  9. HDU 3062 Party

    Party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  10. [转]SVN-版本控制软件

    一.版本控制软件 1.为什么需要版本控制软件 问题:① 团队开发 ② 异地协作 ③ 版本回退 2.解决之道 SCM(Software Configuration Management):软件配置管理 ...